SSTI服务端模板注入

什么是SSTI服务端模板注入 ?

当攻击者使用原生的模板语法注入恶意的payload到模板当中,就可以在服务端进行远程命令执行。

模板引擎是什么?

模板引擎是被设计来生成web页面的,它会联合修改了的模板和多变的数据来生成一个新的页面。

例如,在一个web页面中,它有着不变的部分“hello world!”和一直改变的时间“2022年7月14日”

1
2
hello world!
2022714

那么上面这个页面用模板引擎来实现,动态更新,从而让每个访问页面的人看到的时间都是当前时间。

那么这样的一个页面就可能存在SSTI 服务端请求伪造。

一个有漏洞的代码如下所示

1
$output = $twig->render("Dear " . $_GET['name']);

如果你会php的话,很明显这个页面接受GET请求,请求的参数是name

于是我们可以使用http://ip:port/page?name=payload 这种形式对服务端进行传参。而页面会接受这个传参的内容,把它显示在页面当中。

攻击者可以使用这样的payload,执行SSTI攻击

http://vulnerable-website.com/?name={{bad-stuff-here}}

攻击分为发现,确认,利用三个步骤

第一步,发现

为了发现漏洞,我们可以传参不同的特殊字符,例如 ${{<%[%'"}}%\

如果服务器报错了,那么我们就发现了有可能利用ssti漏洞对它进行攻击。

1
2
3
4
5
{{7*7}}
${7*7}
<%= 7*7 %>
${{7*7}}
#{7*7}

背后的引擎的工作逻辑可能是这样的:engine.render("Hello {{"+greeting+"}}", data)

传参可能是这样的

http://vulnerable-website.com/?greeting=data.username

如果攻击者这样传参http://vulnerable-website.com/?greeting=data.username}}hello

就会导致服务端报错,从而发现漏洞。

第二步,检测漏洞

虽然有很多不同的模板语言,但是大部分模板语言的语法十分相似,目的是不与 HTML 字符冲突。

一些可能会让服务器报错的payload

1
2
3
4
5
6
7
8
9
10
11
12
${}
{{}}
<%= %>
${7/0}
{{7/0}}
<%= 7/0 %>
${foobar}
{{foobar}}
<%= foobar %>
${7*7}
{{7*7}}
``

否则,您将需要手动测试不同语言特定的有效负载并研究模板引擎如何解释它们。 这样做的一种常见方法是使用来自不同模板引擎的语法注入任意数学运算。 然后,您可以观察它们是否被成功评估。 为了帮助完成此过程,您可以使用类似于以下的决策树:

49 正常回显

${7*7} 报错

$49报错

${“aaaa”} 报错 You searched for: Error occured: banned characters

#{7*7} 回显??49_en_US?? 这代表7乘以7的命令成功执行了