SSTI
SSTI 漏洞即服务器端模板注入漏洞(Server-Side Template Injection)。
原理
服务器端模板注入是攻击者利用应用程序中模板引擎的漏洞,通过注入恶意代码到模板中,从而在服务器端执行任意代码或获取敏感信息的攻击方式。模板引擎通常用于将动态数据与固定的模板相结合,生成最终的 HTML、XML 或其他格式的文档。
模版实际指,如:搜索框
常见的模板引擎及漏洞示例
- Jinja2:在 Python 的 Flask 框架中常使用 Jinja2 模板引擎。如果应用程序使用 Jinja2 模板且没有正确处理用户输入,攻击者可能通过构造特殊的输入来执行任意 Python 代码。例如,攻击者可以尝试注入类似于
{ { 7*7 }}
这样的表达式,如果应用程序直接将用户输入渲染到模板中,就可能会计算并显示出 49,证明存在注入漏洞。更危险的是,攻击者还可能注入如{ { config }}
这样的内容来获取应用程序的配置信息,或者注入{ { [].__class__.__base__.__subclasses__() }}
来获取系统的一些敏感信息。 - Thymeleaf:在 Java 的 Spring 框架等中较为常用。攻击者可能通过注入恶意的 OGNL(Object Graph Navigation Language)表达式来实现攻击。比如,攻击者可能尝试注入
${#rt.exec('calc.exe')}
,如果漏洞存在,就可能在服务器端执行计算器程序,当然在实际环境中可能会执行更恶意的命令。 - Velocity:也是 Java 中常用的模板引擎。攻击者可以利用它的语法进行注入攻击,例如
#set($x='freemarker.template.utility.Execute')${$x("id")}
,可能会在服务器上执行id
命令获取用户信息等。
出现漏洞原因
当应用程序没有对用户输入进行充分的验证和过滤时,攻击者就可能利用这一点注入恶意脚本,破坏应用程序的正常运行,甚至获取服务器的控制权。
防范措施
- 输入验证和过滤:对用户输入进行严格的验证和过滤,确保输入符合预期的格式和范围,不包含任何可能导致注入的特殊字符或表达式。可以使用正则表达式等方式进行验证,对危险字符进行转义或拒绝。
- 使用安全的模板引擎配置:确保模板引擎使用安全的配置选项,例如,在 Jinja2 中可以启用
autoescape
功能,自动对用户输入进行转义,防止注入攻击。 - 更新和维护软件:及时更新模板引擎和相关的框架、库,以修复已知的安全漏洞。软件开发者通常会在发现漏洞后发布安全更新,及时应用这些更新可以有效防范 SSTI 攻击。
- 最小权限原则:运行应用程序的用户或进程应具有最小的权限,避免以管理员或高权限用户身份运行,这样即使发生 SSTI 攻击,攻击者能够造成的危害也会受到限制。
- 安全审计和监控:建立安全审计机制,对应用程序的日志进行监控和分析,及时发现异常的请求和操作。如果发现有疑似 SSTI 攻击的行为,能够及时采取措施进行处理。
SSTI注入
常见模板引擎的 SSTI 注入示例:
Jinja2(Python)
Jinja2 是 Python 中常用的模板引擎。攻击者可以通过注入特殊的表达式来执行任意 Python 代码。
{
{ 7*7 }} # 若存在漏洞,会输出 49,可用于验证漏洞
{
{ config.items() }} # 尝试获取应用程序的配置信息
可以执行系统命令
{
{ ''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read() }} # 读取 /etc/passwd 文件内容