# PortSwigger 目录遍历靶场完全攻略(6 个实验全解析)
# 前言
目录遍历(Directory Traversal),也称为路径遍历(Path Traversal),是 Web 安全中常见的高危漏洞之一。攻击者通过构造特殊的路径序列,能够访问 Web 应用程序根目录之外的文件和目录,从而读取敏感文件、获取系统信息,甚至在某些情况下实现远程代码执行。
PortSwigger 提供的目录遍历靶场包含 6 个精心设计的实验,涵盖了从基础到高级的各种目录遍历技术和绕过方法。本文将详细解析每个实验的原理、攻击步骤和技术要点,帮助读者全面掌握目录遍历漏洞的原理和利用方法。
# 什么是目录遍历漏洞
目录遍历漏洞是一种允许攻击者读取应用程序目录结构之外的任意文件的漏洞。当应用程序使用用户提供的输入来构建文件路径,但没有对输入进行充分验证时,就会出现这种漏洞。
# 漏洞原理
考虑一个显示待售商品图像的购物应用程序。图像通过 HTML 加载,如下所示:
1 | <img src="/loadImage?filename=218.png"> |
loadImage URL 接受一个 filename 参数并返回指定文件的内容。图像文件本身存储在磁盘中的位置 /var/www/images/ 。要返回图像,应用程序将请求的文件名附加到此基本目录并使用文件系统 API 来读取文件的内容。
在上述情况下,应用程序从以下文件路径读取:
1 | /var/www/images/218.png |
# 攻击原理
该应用程序没有针对目录遍历攻击实施任何防御措施,因此攻击者可以请求以下 URL 从服务器的文件系统中检索任意文件:
1 | https://insecure-website.com/loadImage?filename=../../../etc/passwd |
这会导致应用程序从以下文件路径读取:
1 | /var/www/images/../../../etc/passwd |
该序列 ../ 在文件路径中有效,意味着在目录结构中上一级。三个连续的 ../ 序列从 /var/www/images/ 文件系统的根目录开始,所以实际读取的文件是:
1 | /etc/passwd |
在基于 Unix 的操作系统上,这是一个标准文件,其中包含在服务器上注册的用户的详细信息。
在 Windows 上, ../ 和 ..\ 都是有效的目录遍历序列,检索标准操作系统文件的等效攻击是:
1 | https://insecure-website.com/loadImage?filename=..\..\..\windows\win.ini |
# 实验环境准备
在开始之前,请确保:
- 拥有 PortSwigger Academy 账号
- 熟练使用 BurpSuite 进行抓包和改包
- 了解基本的文件系统结构和路径概念
- 理解 HTTP 协议和 Web 应用架构
- 熟悉不同操作系统的路径分隔符(Unix:
/, Windows:\)
# 实战演练
# 实验 1:目录遍历,简单案例
# 目标描述
该实验室的产品库存检查器中存在目录遍历漏洞。应用程序显示来自指定文件的产品图像。
# 任务目标
检索 /etc/passwd 文件的内容。
# 漏洞分析
应用程序可能执行类似如下的文件读取操作:
1 | # 伪代码示例 |
当 filename 参数直接传递给文件系统时,攻击者可以使用 ../ 序列向上遍历目录。
# 攻击步骤
- 访问目标页面:导航到产品图片加载功能
- 开启 Burp 拦截:使用 Burp Suite 拦截加载图片的请求
- 分析请求参数:观察 filename 参数的传递方式
- 注入遍历序列:修改 filename 参数,添加目录遍历序列
具体 Payload:
1 | filename=../../../etc/passwd |
# 技术原理
目录遍历的核心是使用 ../ 序列:
../表示上一级目录../../表示上两级目录../../../表示上三级目录
从 /var/www/images/ 开始:
1 | /var/www/images/../../../etc/passwd |
简化后:
1 | /etc/passwd |
# 预期结果
响应中应该包含 /etc/passwd 文件的内容,例如:
1 | root:x:0:0:root:/root:/bin/bash |
# 实验 2:目录遍历,遍历序列被绝对路径绕过
# 目标描述
许多将用户输入放置到文件路径中的应用程序实现了某种针对路径遍历攻击的防御,并且这些通常可以被规避。
# 任务目标
检索 /etc/passwd 文件的内容。
# 漏洞分析
应用程序可能过滤了 ../ 序列,但没有阻止绝对路径。这种情况下,可以使用绝对路径直接引用文件,而无需使用任何遍历序列。
# 攻击步骤
- 测试相对路径:首先尝试使用
../../../etc/passwd - 观察过滤结果:如果相对路径被过滤,尝试绝对路径
- 使用绝对路径:直接使用从文件系统根目录开始的路径
具体 Payload:
1 | filename=/etc/passwd |
# 技术原理
当应用程序过滤 ../ 序列时,可能存在以下几种情况:
- 简单字符串过滤:直接删除
../序列 - 正则表达式过滤:使用正则匹配
../ - 路径验证:验证路径是否包含遍历序列
绝对路径绕过的原理是:
- 绝对路径以
/开头,直接指向文件系统根目录 - 不包含
../序列,可能绕过过滤规则 - 直接访问目标文件,无需遍历目录结构
# 验证方法
如果绝对路径成功,说明应用程序:
- 只过滤了相对路径遍历
- 没有验证路径的合法性
- 允许访问任意绝对路径文件
# 实验 3:目录遍历,遍历序列被非递归剥离
# 目标描述
应用程序从用户提供的文件名中剥离或阻止目录遍历序列,但处理方式存在缺陷。
# 任务目标
检索 /etc/passwd 文件的内容。
# 漏洞分析
应用程序可能使用非递归的字符串替换来过滤 ../ 序列,这意味着只会替换一次匹配的序列。这种情况下,可以使用双写绕过技术。
# 攻击步骤
- 测试单次遍历:尝试
../../../etc/passwd - 观察过滤结果:如果被过滤,尝试双写绕过
- 构造双写 Payload: 使用
....//或类似模式
具体 Payload:
1 | filename=....//....//....//etc/passwd |
# 技术原理
非递归过滤的代码可能如下:
1 | # 伪代码示例 |
这种过滤只会替换一次 ../ :
- 输入:
....//....//....//etc/passwd - 第一次替换:
../→'' - 结果:
../../../etc/passwd
双写绕过的变体:
....//→../..\/→../(URL 编码)..%2f→../(URL 编码)
# 其他绕过技术
混合编码:
1
filename=..%2f..%2f..%2fetc%2fpasswd
Unicode 编码:
1
filename=..%u2215..%u2215..%u2215etc%u2215passwd
双重 URL 编码:
1
filename=..%252f..%252f..%252fetc%252fpasswd
# 实验 4:目录遍历,遍历序列被过度 URL 解码剥离
# 目标描述
在某些情况下,例如在 URL 路径或请求 filename 参数中 multipart/form-data ,Web 服务器可能会在将您的输入传递给应用程序之前剥离任何目录遍历序列。您有时可以通过 URL 编码,甚至双重 URL 编码,绕过这种清理。<mcreference link="https://www.cnblogs.com/Sayo-/p/16388740.html" index="0">0</citereference>
# 任务目标
检索 /etc/passwd 文件的内容。
# 漏洞分析
应用程序可能在多层处理中剥离目录遍历序列:
- Web 服务器层解码和过滤
- 应用程序层再次解码和过滤
- WAF 层过滤
这种情况下,可以使用各种编码技术绕过清理。
# 攻击步骤
- 测试基础遍历:尝试
../../../etc/passwd - 使用 URL 编码:对
../进行 URL 编码 - 尝试双重编码:对已编码的内容再次编码
- 使用非标准编码:尝试各种编码变体
具体 Payload:
单次 URL 编码:
1
filename=%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd
双重 URL 编码:
1
filename=%252e%252e%252f%252e%252e%252f%252e%252e%252fetc%252fpasswd
非标准编码:
1
filename=..%c0%af..%c0%af..%c0%afetc%c0%afpasswd
# 技术原理
URL 编码表:
| 字符 | 单次编码 | 双重编码 | 非标准编码 |
|---|---|---|---|
/ | %2f | %252f | %c0%af |
. | %2e | %252e | - |
编码绕过原理:
- 单次 URL 编码:绕过简单的字符串匹配
- 双重 URL 编码:绕过多层解码处理
- 非标准编码:利用编码解析的差异
处理流程示例:
1 | 输入: %252e%252e%252f |
# 实验 5:目录遍历,路径起始验证
# 目标描述
应用程序验证路径必须以特定前缀开头,但验证逻辑存在缺陷。
# 任务目标
检索 /etc/passwd 文件的内容。
# 漏洞分析
应用程序可能使用正则表达式验证路径必须包含特定目录,如 /var/www/images/ ,但验证逻辑可以被绕过。
# 攻击步骤
- 了解验证规则:确定要求的前缀
- 构造符合要求的路径:在路径中包含必需的前缀
- 注入遍历序列:在前缀后添加遍历序列
具体 Payload:
1 | filename=/var/www/images/../../../etc/passwd |
# 技术原理
验证代码可能如下:
1 | # 伪代码示例 |
这种验证只检查路径是否以指定前缀开头,但不检查路径的实际安全性。
绕过原理:
- 路径以
/var/www/images/开头,通过验证 ../../../将路径回退到根目录- 最终访问
/etc/passwd
其他绕过方法:
使用绝对路径:
1
filename=/var/www/images/etc/passwd
使用相对路径:
1
filename=var/www/images/../../../etc/passwd
# 实验 6:目录遍历,文件扩展名验证与空字节绕过
# 目标描述
应用程序验证文件必须具有特定的扩展名,但可以使用空字节绕过验证。
# 任务目标
检索 /etc/passwd 文件的内容。
# 漏洞分析
应用程序可能要求文件必须以特定扩展名结尾(如 .jpg ),但底层文件系统 API 可能忽略空字节后的内容。
# 攻击步骤
- 了解扩展名要求:确定要求的文件扩展名
- 构造包含扩展名的路径:在目标文件后添加必需扩展名
- 使用空字节绕过:在扩展名前插入空字节
具体 Payload:
1 | filename=../../../etc/passwd%00.jpg |
# 技术原理
空字节绕过原理:
- 应用程序验证:
../../../etc/passwd%00.jpg以.jpg结尾,通过验证 - 文件系统 API:
%00被解析为空字符\0,截断后面的内容 - 实际访问:
../../../etc/passwd
编程语言中的空字节处理:
1 | // C语言示例 |
1 | // PHP示例 |
其他绕过技术:
长文件名截断:
1
filename=../../../etc/passwd.....................................................jpg
路径遍历结合空字节:
1
filename=/var/www/images/../../../etc/passwd%00.jpg
# 目录遍历技术总结
# 常用遍历序列
| 操作系统 | 遍历序列 | 示例 |
|---|---|---|
| Unix/Linux | ../ | ../../../etc/passwd |
| Windows | ../ | ../../../windows/win.ini |
| Windows | ..\ | ..\..\..\windows\win.ini |
# 编码绕过技术
| 编码类型 | 编码结果 | 应用场景 |
|---|---|---|
| URL 编码 | %2e%2e%2f | 绕过字符串过滤 |
| 双重 URL 编码 | %252e%252e%252f | 绕过多层解码 |
| Unicode 编码 | ..%u2215 | 绕过特定过滤器 |
| 十六进制编码 | ..%c0%af | 绕过 UTF-8 过滤器 |
# 绕过技术矩阵
| 防御类型 | 绕过方法 | 成功率 |
|---|---|---|
| 简单字符串过滤 | 双写、编码 | 高 |
| 正则表达式过滤 | 编码、混合 | 中 |
| 路径前缀验证 | 绝对路径 | 高 |
| 扩展名验证 | 空字节 | 高 |
| 多层过滤 | 双重编码 | 中 |
# 敏感文件列表
# Unix/Linux 系统文件
| 文件路径 | 描述 | 危险等级 |
|---|---|---|
/etc/passwd | 用户账户信息 | 高 |
/etc/shadow | 用户密码哈希 | 极高 |
/etc/hosts | 主机名映射 | 中 |
/etc/issue | 系统版本信息 | 低 |
/proc/version | 内核版本信息 | 中 |
/proc/self/environ | 环境变量 | 高 |
/home/user/.bash_history | 命令历史 | 高 |
/var/log/auth.log | 认证日志 | 高 |
# Windows 系统文件
| 文件路径 | 描述 | 危险等级 |
|---|---|---|
C:\windows\win.ini | 系统配置 | 中 |
C:\boot.ini | 启动配置 | 中 |
C:\windows\system32\drivers\etc\hosts | 主机映射 | 中 |
C:\windows\system32\config\sam | 用户密码 | 极高 |
C:\windows\repair\sam | 备份密码 | 极高 |
# Web 应用文件
| 文件路径 | 描述 | 危险等级 |
|---|---|---|
config.php | 数据库配置 | 极高 |
.env | 环境变量 | 极高 |
wp-config.php | WordPress 配置 | 高 |
database.yml | 数据库配置 | 高 |
.htaccess | Apache 配置 | 中 |
# 防御措施
# 1. 输入验证
1 | # 安全的文件名验证 |
# 2. 白名单验证
1 | // Java白名单验证示例 |
# 3. 路径规范化
1 | // PHP路径规范化示例 |
# 4. 权限控制
1 | # 设置适当的文件权限 |
# 5. Web 服务器配置
1 | # Nginx配置示例 |
1 | # Apache配置示例 |
# 自动化检测工具
# Burp Suite 插件
- Intruder: 自动化 fuzzing 测试
- Scanner: 自动漏洞扫描
- Sequencer: 会话令牌分析
# 自定义检测脚本
1 | import requests |
# Fuzzing 字典
1 | # 目录遍历fuzzing字典 |
# 总结
通过 PortSwigger 目录遍历靶场的 6 个实验,我们系统学习了:
- 基础目录遍历:使用
../序列向上遍历目录 - 绝对路径绕过:使用绝对路径避开相对路径过滤
- 非递归过滤绕过:使用双写技术绕过简单过滤
- 编码绕过:使用各种编码技术绕过多层过滤
- 路径验证绕过:构造符合验证要求但包含遍历的路径
- 扩展名验证绕过:使用空字节等技术绕过文件类型验证
# 关键技术要点
- 遍历序列:熟练使用
../、..\等遍历序列 - 编码技术:掌握 URL 编码、双重编码、Unicode 编码等
- 绕过技巧:理解各种防御机制的绕过方法
- 自动化测试:使用工具提高检测效率
# 防御最佳实践
- 输入验证:严格的白名单验证
- 路径规范化:使用安全的路径处理函数
- 权限控制:最小权限原则
- 安全编码:避免直接拼接用户输入
- 监控审计:部署检测和监控机制
目录遍历漏洞虽然原理相对简单,但在实际应用中仍然普遍存在。掌握其原理和利用方法,不仅有助于渗透测试工作,更重要的是帮助开发者编写更安全的代码,构建更安全的 Web 应用。
# 参考资源
- PortSwigger Web Security Academy - File Path Traversal
- OWASP Path Traversal Prevention
- Burp Suite Documentation
- OWASP Testing Guide - Path Traversal
免责声明:本文内容仅用于教育目的,请勿在未授权的情况下对他人系统进行测试。所有安全测试都应在获得明确授权的环境中进行。
