加载中...

【Root-Me】 Server-side Template Injection



前置知识

SSTI (服务侧模板注入) 题型,此挑战要用到的相关知识可以参考以下文档:


试错

题目要求是读取文件【SECRET_FLAG.txt】的内容。

开启挑战后只有一个输入框,首先试试能不能 XXS ,输入一个探针 <img src=0 /> ,发现原文回显,即被过滤了:

然后尝试直接访问 【http://challenge01.root-me.org/web-serveur/ch41/SECRET_FLAG.txt】,理所当然报错:


SSTI 探针

既然这些方法都被封锁了,题目有提示是要用 SSTI 解题,还是不绕弯子实打实做吧~~

但是要使用 SSTI 攻击,首先需要知道这个页面使用了什么模板引擎。

网上 找到了 Burp Sutie 提供的一套 payload探针,用于快速确认模板引擎(其中绿色分支表示探针注入成功时的下一个步骤,红色表示注入失败时的下一个步骤):

根据流程按部就班做就可以了。首先输入探针 ${7*7} ,发现 WEB 计算成了 49 ,即注入成功:

继续输入下一个探针 a{*comment*}b ,这次原文回显,即注入失败:

继续输入下一个探针 ${"z".join("ab")} ,这次直接返回异常,即注入失败。

从探针流程上看,我们测试得到的模板引擎是 Unknown 。。。

不过仔细观察返回的异常信息,可以看见信息 freemarker

从网上找到 freemarker 是属于 Java 语言的模板引擎,因此可以针对性进行注入。


构造 payload

由于题目目标很明确要我们读取文件【SECRET_FLAG.txt】的内容,因此很自然就想到最直接的方法就是使用 系统命令 读取这个文件,例如:cat SECRET_FLAG.txt

接下来只需要找到方法“如何通过 freemarker 调用系统命令”即可。

我稍微找了一下就看到了 这篇文章 ,它提供的 payload 还是很简单的:

<#assign exp="freemarker.template.utility.Execute"?new()>
${exp("any system cmd")}

其中第一行的意思是:利用 assign 标签定义一个全局变量 exp ,这个全局变量是通过 freemarker.template.utility.Executenew 出来的一个实例变量。而在 freemarker 中, freemarker.template.utility.Execute 类的功能是调用系统命令。

第二行的意思就更简单了:利用全局变量 exp 调用任意系统命令。

关于 freemarker 的 assign 标签的功能可以参考 这篇文章

我们可以通过一个简单的 Linux 系统命令 id 测试它是否起作用,构造 payload 如下(去掉了换行):

<#assign exp="freemarker.template.utility.Execute"?new()>${exp("id")}

成功获取到了当前 Linux 用户的 id 信息。


完成挑战

于是可以开始解题了,首先查看一下 SECRET_FLAG.txt 文件在哪,构造 payload 如下:

<#assign exp="freemarker.template.utility.Execute"?new()>${exp("ls -al")}

很幸运地,这个文件就在当前目录:

最后我们构造 payload 读取这个文件:

<#assign exp="freemarker.template.utility.Execute"?new()>${exp("cat SECRET_FLAG.txt")}

得到 flag ,完成挑战:


答案下载

flag 下载后的 flagzip 的文件需要手动更改后缀为 *.zip,然后解压即可(为了避免直接刷答案)


文章作者: EXP
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 EXP !
  目录