本文目录导读:
我来详细介绍目录遍历攻击的原理和防护方法。
目录遍历攻击原理
目录遍历(Directory Traversal)是通过操纵文件路径来访问受限目录的攻击技术。
攻击示例
基本路径遍历
http://example.com/download?file=../../etc/passwd
URL编码绕过
http://example.com/download?file=..%2F..%2F..%2Fetc%2Fpasswd
双重编码
http://example.com/download?file=..%252F..%252F..%252Fetc%252Fpasswd
攻击测试方法
常见Payload
# 基础遍历 ../../../etc/passwd ..\..\..\windows\system32\config\sam # 编码变体 ..%2f..%2f..%2fetc%2fpasswd %2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd # 避开过滤 ....//....//....//etc/passwd ..;/..;/../etc/passwd
工具辅助测试
使用Burp Suite
- 拦截请求
- 修改参数中的文件路径
- 使用Intruder模块测试多种Payload
使用curl命令
curl "http://target.com/download?file=../../../etc/passwd" curl --path-as-is "http://target.com/../../../etc/passwd"
防护措施
代码层面防护
Java示例
public class FileDownload {
private static final String BASE_DIR = "/var/www/downloads/";
public void downloadFile(String fileName) throws Exception {
// 1. 过滤路径遍历字符
if (fileName.contains("..") || fileName.contains("/")) {
throw new SecurityException("Invalid file name");
}
// 2. 规范化路径
File file = new File(BASE_DIR + fileName);
String canonicalPath = file.getCanonicalPath();
// 3. 验证路径在允许范围内
if (!canonicalPath.startsWith(new File(BASE_DIR).getCanonicalPath())) {
throw new SecurityException("Access denied");
}
// 处理文件下载...
}
}
Python示例
import os
def safe_download(filename, base_dir="/var/www/downloads"):
# 1. 拒绝包含路径分隔符的输入
if '/' in filename or '..' in filename:
raise Exception("Invalid filename")
# 2. 构建安全路径
safe_path = os.path.normpath(os.path.join(base_dir, filename))
# 3. 验证路径合法性
if not safe_path.startswith(os.path.abspath(base_dir)):
raise Exception("Access denied")
return safe_path
Web服务器配置
Apache配置
# 禁止目录遍历
Options -Indexes
# 限制访问范围
<Directory /var/www/html>
Order Allow,Deny
Allow from all
<FilesMatch "\.(php|html)$">
Require all granted
</FilesMatch>
</Directory>
Nginx配置
# 禁止访问隐藏文件和目录
location ~ /\. {
deny all;
}
# 限制访问目录
location /uploads/ {
alias /var/www/uploads/;
internal; # 仅限内部重定向访问
}
输入验证最佳实践
def validate_path(user_input):
# 1. 白名单验证
allowed_files = ['file1.pdf', 'file2.jpg', 'file3.txt']
if user_input not in allowed_files:
raise Exception("Invalid file")
# 2. 正则验证
import re
if not re.match(r'^[\w\-\.]+$', user_input):
raise Exception("Invalid characters in filename")
# 3. 文件类型验证
allowed_extensions = ['.pdf', '.jpg', '.txt']
ext = os.path.splitext(user_input)[1]
if ext not in allowed_extensions:
raise Exception("File type not allowed")
测试工具
自动化扫描工具
- OWASP ZAP: Web应用安全扫描
- Burp Suite: Web安全测试平台
- Nikto: Web服务器扫描器
- DirBuster: 目录暴力破解
专用测试工具
# dirsearch - 目录扫描 python3 dirsearch.py -u http://target.com -e php # gobuster - 目录枚举 gobuster dir -u http://target.com -w wordlist.txt # wfuzz - 模糊测试 wfuzz -c -z file,payloads.txt http://target.com/download?file=FUZZ
安全最佳实践
开发阶段
- 使用抽象文件访问接口(如数据库存储文件引用)
- 实施最小权限原则
- 对用户输入进行严格验证
部署阶段
# 设置正确的文件权限 chmod 644 /var/www/html/*.php chmod 755 /var/www/html/ chown -R www-data:www-data /var/www/html/ # 使用chroot限制访问范围 chroot /var/www /bin/bash
监控与审计
# 日志记录
import logging
logging.basicConfig(filename='access.log', level=logging.WARNING)
def log_suspicious_activity(request):
if '..' in request.path or '\\' in request.path:
logging.warning(f"Directory traversal attempt: {request.remote_addr}")
目录遍历攻击的防御关键在于:
- 永远不要信任用户输入
- 使用规范的路径处理函数
- 实施白名单验证
- 限制Web应用权限
- 保持系统和框架更新
安全的文件访问应该是白名单模式,而不是黑名单模式。
标签: 安全测试