目录
一、文件上传漏洞
1、概念
概念:攻击者将恶意文件(如Webshell、木马、勒索软件)上传到服务器,进而可能导致服务器被完全控制、数据泄露、服务瘫痪等严重后果。
直接危害:
-
Webshell上传: 攻击者上传PHP/JSP/ASP等脚本文件,通过浏览器访问该文件即可执行任意服务器命令(查看文件、数据库操作、反弹Shell)。
-
服务器沦陷: 通过Webshell获得系统权限,植入持久化后门,控制整个服务器。
-
挂马与钓鱼: 上传恶意HTML/JS文件,用于传播木马或伪造登录页面窃取用户凭证。
-
拒绝服务(DoS): 上传超大文件耗尽磁盘空间或内存;上传大量文件耗尽inode资源。
-
存储型XSS: 上传包含恶意JS的SVG/HTML文件,用户访问时触发XSS。
-
病毒传播: 上传带毒文件(如EXE、宏文档),其他用户下载后感染。
-
敏感数据泄露: 覆盖服务器关键配置文件或日志。
-
作为跳板: 攻击内网其他系统。
2、常见攻击手法
绕过文件类型检查:
-
修改HTTP
Content-Type
头: 如将application/php
改为image/jpeg
。 -
修改文件扩展名:
-
双扩展名:
shell.php.jpg
(部分系统取最后一个扩展名.jpg
,但Apache可能按.php
执行)。 -
大小写混淆:
shell.PhP
,shell.pHp5
。 -
特殊扩展名:
.php3
,.php4
,.php5
,.phtml
,.phar
(旧版PHP可能仍执行)。 -
空字节截断:
shell.php%00.jpg
(旧版PHP解析时%00
后内容被忽略)。 -
添加点/空格:
shell.php.
,shell.php
(Windows可能自动去除)。
-
-
利用解析差异: 如IIS6.0中的目录路径解析漏洞 (
/upload/shell.jpg/shell.php
) 和分号解析漏洞 (shell.jpg;.php
)。
绕过内容检查:
-
添加文件头: 在恶意PHP文件前添加图片头如
GIF89a
或ÿØÿà
(JPEG),伪装成图片。 -
嵌入恶意代码: 在图片元数据(EXIF)或正常文件中插入PHP代码。
-
利用二次渲染: 上传经过精心构造的图片,使其在服务器调整大小/压缩后仍保留可执行代码。
-
利用压缩包: 上传包含恶意脚本的ZIP文件,配合其他漏洞(如路径遍历、解压执行)触发。
绕过客户端验证:
-
直接修改HTML/JS: 禁用浏览器JS、修改前端文件类型限制代码、使用Burp Suite等工具拦截修改请求。
利用黑名单缺陷:
-
使用冷门可执行扩展名:
.jspx
,.asa
,.cer
,.cdx
,.asax
(IIS)。 -
利用服务器配置:
.htaccess
(Apache) 文件上传后可覆盖目录配置允许执行其他扩展名。 -
利用特殊文件:
web.config
(IIS) 上传可配置处理程序。
利用条件竞争:
-
文件写入与检查不同步: 在服务器完成文件上传但尚未进行安全扫描或移动到安全目录的瞬间访问并执行恶意脚本。
利用云存储与CDN特性:
-
上传到云存储桶(S3, OSS等),利用配置错误使文件可被公开访问或执行。
3、防御措施
前端验证 (基础但不可靠):
-
使用JS检查文件扩展名、大小(提升用户体验,减轻服务器压力,但必须配合后端验证)。
后端严格验证 (核心防线):
-
扩展名白名单: 只允许
jpg
,png
,pdf
等必要类型(绝对优于黑名单!)。 -
检查文件内容:
-
魔术字节(Magic Bytes): 检查文件头部真实类型(如
FF D8 FF
是JPEG)。 -
文件内容扫描: 使用杀毒引擎扫描上传文件。
-
图像二次渲染: 对图片进行压缩/缩放,破坏嵌入的恶意代码。
-
文件内容解析: 对于文档(PDF, DOCX),检查是否包含恶意宏或脚本。
-
-
检查
Content-Type
头: 但仅作为辅助手段。 -
限制文件大小: 设置合理的上限。
安全处理上传文件:
-
重命名文件: 使用随机不可预测的文件名(如UUID),避免使用用户提供的原始名。
-
修改扩展名: 强制将文件存储为白名单中的安全扩展名(如所有图片统一存为
.img
)。 -
存储在Web根目录之外: 上传的文件保存在服务器上但不可通过URL直接访问。
-
设置严格文件权限: 上传目录禁止脚本执行 (
noexec
),文件设置为只读。 -
使用单独域名/CDN: 通过独立的无Cookie域名提供静态文件,降低XSS影响。
服务器与中间件加固:
-
配置Web服务器:
-
明确禁止上传目录执行任何脚本 (Apache:
php_flag engine off
, Nginx:location ~* \.(php|jsp)$ { deny all; }
)。 -
及时更新服务器、PHP/Python/Java等语言环境、中间件(Tomcat, IIS)补丁。
-
-
安全配置云存储: 设置正确的Bucket ACL(私有访问),禁用静态网站托管(除非必要)。
文件内容交付安全:
-
使用Content-Disposition: attachment: 强制浏览器下载而非渲染潜在危险文件(如HTML/SVG)。
-
设置安全的CSP策略: 防止上传的HTML/JS文件造成XSS。
日志与监控:
-
详细记录所有上传操作(用户、IP、时间、文件名、大小、结果)。
-
监控上传目录的文件变化,对异常活动(如大量.php文件)进行告警。
-
使用WAF/IPS规则检测常见文件上传攻击特征。
安全开发实践:
-
使用成熟安全的库: 如Apache Commons FileUpload (Java), Django FileField/Pillow (Python), Symfony File组件 (PHP)。
-
安全代码审计: 定期审查文件上传功能代码。
-
渗透测试: 模拟攻击者尝试绕过上传限制。
二、文件下载漏洞
1、原理
-
攻击者通过精心构造请求参数(通常是文件路径或文件名),欺骗 Web 应用程序读取并返回服务器文件系统上的任意文件。
-
漏洞通常出现在提供文件下载功能的接口处,这些接口本应只允许用户下载预先设定好的、安全的文件(如用户上传的图片、文档等)。但如果应用程序没有对用户传入的文件路径/名称参数进行严格验证和过滤,攻击者就能利用路径遍历技术(如
../
)跳出预设目录,访问系统上的其他文件。
2、常见攻击手法
2.1 常见触发点
任何接收文件名/路径作为参数并直接用于文件读取操作的 API 端点:
-
download.php?file=report.pdf
-
getFile.jsp?filename=user_avatar.jpg
-
exportData?template=/templates/default.xml
2.2 攻击方式(利用路径遍历)
-
基础遍历:
download.php?file=../../../../etc/passwd
(Linux/Unix) -
编码绕过:
download.php?file=%2e%2e%2f%2e%2e%2fetc%2fpasswd
(URL 编码../
) -
双重编码:
download.php?file=%252e%252e%252f%252e%252e%252fetc%252fpasswd
(对%
再次编码) -
空字节截断:
download.php?file=../../../etc/passwd%00.pdf
(利用老式系统或不当处理的截断) -
绝对路径:
download.php?file=/etc/passwd
(如果应用未限制绝对路径) -
操作系统特定文件:
-
Linux/Unix:
/etc/passwd
,/etc/shadow
(权限允许时),/proc/self/environ
(环境变量),/home/{user}/.ssh/id_rsa
(私钥), 应用配置文件 (config.php
,.env
,web.config
,application.properties
), 数据库备份文件等。 -
Windows:
C:\Windows\win.ini
,C:\Windows\System32\drivers\etc\hosts
,C:\boot.ini
(旧系统), 用户目录下的敏感文件等。
-
3、防御措施
-
白名单验证: 最有效的方法。 严格定义允许下载的文件集合(基于文件名、ID 或存储在数据库中的安全路径)。拒绝任何不在白名单内的请求。
-
避免直接传递路径/文件名: 使用映射 ID(数据库 ID、UUID)代替真实的文件路径/名。应用根据 ID 查询数据库获取安全的存储路径。
-
规范化与验证: 如果必须处理路径/文件名:
-
对用户输入进行严格的路径规范化(移除
./
,../
, 多余的/
)。 -
将路径解析为绝对路径,并检查其是否在应用程序指定的安全根目录(
chroot
或工作目录)之下。使用编程语言提供的安全函数(如 Python 的os.path.abspath
+os.path.commonprefix
检查, Java 的Path.normalize().toAbsolutePath()
+startsWith
检查安全根)。 -
禁止使用绝对路径。
-
-
安全上下文 (Jail/Chroot): 将 Web 应用程序运行在受限的文件系统环境中(如 chroot jail 或容器),限制其可访问的文件范围。
-
最小权限原则: Web 服务器进程应仅拥有访问其必需文件(Web 根目录、临时目录等)的最低权限。
-
输入过滤与编码: 对用户输入进行严格过滤(移除特殊字符),并在输出文件名时进行适当的编码(如 Content-Disposition 头中的文件名)。
-
禁用危险函数: 在 PHP 等语言中,考虑禁用
realpath()
等可能导致信息泄露的函数(如果可能且不影响功能)。
三、目录浏览漏洞
1、原理
-
当 Web 服务器接收到一个指向目录(而非具体文件)的请求(如
http://example.com/images/
),且该目录下没有默认文档(如index.html
,index.php
),同时服务器配置错误地启用了目录浏览功能时,服务器会自动生成并返回一个包含该目录下所有文件和子目录列表的 HTML 页面。 -
攻击者无需利用特定的参数注入,只需访问目录 URL 即可。
2、常见攻击手法
直接访问指向目录,目录下没有默认文档的情况
常见触发点:
-
访问明显可能包含文件的目录:
/images/
,/uploads/
,/backups/
,/static/
,/docs/
。 -
访问不存在的文件,但路径指向一个真实目录(有时会回退到目录列表)。
-
故意省略文件名,只访问目录路径。
3、防御措施
-
禁用目录浏览: 最根本的解决方案。 在 Web 服务器配置中明确关闭目录浏览功能。
-
Apache: 在
<Directory>
或虚拟主机配置中设置Options -Indexes
。 -
Nginx: 在
location
块中设置autoindex off;
。 -
IIS: 在“目录浏览”功能中禁用。
-
-
放置默认页面: 在每个目录下放置一个有效的默认文档(如
index.html
,index.php
)。即使浏览功能开启,请求目录时也会显示默认页而非文件列表。 -
最小化目录内容: 只存放 Web 应用程序运行所必需的文件。移除临时文件、备份文件、源代码文件、敏感配置文件(或将其移出 Web 可访问目录)。
-
权限控制: 确保 Web 服务器用户对目录只有必要的读取(或执行)权限,没有列表权限(虽然主要依赖服务器配置)。
-
Web 应用程序防火墙 (WAF): 配置 WAF 规则阻止对目录 URL 的访问或检测返回的目录列表内容。
-
定期扫描与审计: 定期使用扫描器检查自身网站是否存在意外的目录浏览漏洞,并审计 Web 服务器配置。