文件上传漏洞实战:从BurpSuite抓包到Webshell上传的攻防复盘

📅 2026/7/6 9:36:15
文件上传漏洞实战:从BurpSuite抓包到Webshell上传的攻防复盘
1. 项目概述一次攻防演练中的文件上传漏洞复盘最近在内部的一次红蓝对抗演练中我作为攻击方成功利用了一个典型的文件上传漏洞拿下了目标系统的权限。整个过程从信息收集、漏洞发现、绕过防御到最终获取Shell环环相扣其中BurpSuite的抓包和改包技巧起到了关键作用。这次实战让我对文件上传漏洞的利用链有了更深的体会也积累了一些绕过常见防护措施的技巧。今天我就从一个攻击者的视角完整复盘这次渗透过程并分享其中用到的核心工具技巧和思考逻辑。无论你是安全测试人员想提升实战能力还是开发人员想了解攻击者思路以加固自身系统这篇文章都能提供一份详实的参考。文件上传功能几乎是所有Web应用的标配它方便了用户但也为攻击者打开了一扇危险的大门。一个未经严格校验的上传点很可能直接成为通往服务器内网的“高速公路”。本次实战的目标是一个内容管理系统CMS我们将看到攻击者如何一步步将一张“图片”变成控制服务器的“后门”。2. 前期信息收集与目标分析在发起任何攻击之前充分的信息收集是成功的一半。盲目测试不仅效率低下还容易触发告警。这次的目标是一个企业门户网站我们的第一步就是摸清它的“家底”。2.1 网站结构与技术栈识别我首先使用浏览器对目标网站进行了常规浏览重点关注“关于我们”、“联系我们”、“用户中心”等可能存在上传功能的页面。同时打开浏览器的开发者工具F12查看网络请求和页面源代码。关键操作与发现查看响应头在Network标签页中查看任意一个页面请求的HTTP响应头。我发现了X-Powered-By: PHP/7.2.24和Server: Apache/2.4.41 (Ubuntu)。这立刻明确了后端语言是PHPWeb服务器是Apache运行在Ubuntu系统上。PHP环境意味着我们可以尝试上传.php后缀的Webshell。目录扫描与敏感文件发现使用dirsearch这类目录扫描工具对目标进行初步探测。命令类似python3 dirsearch.py -u https://target.com -e php,html,zip,bak。扫描结果中除了常见的admin、upload目录外还发现了一个/uploads/目录访问后直接列出了已上传的文件这是一个重要信号说明上传的文件可能被直接存储在可访问的Web路径下。寻找上传点通过手动浏览和扫描结果在用户头像设置页面找到了上传点。页面提示“支持上传JPG、PNG格式图片大小不超过2MB”。这是一个非常典型的图片上传功能。注意信息收集阶段要尽可能安静。我会调整目录扫描工具的线程数和延迟避免对目标服务器造成过大压力或触发基于频率的防护规则。同时使用不同的User-Agent也是基本操作。2.2 客户端校验机制初探找到上传点后我没有急于上传恶意文件而是先分析前端的防御措施。我尝试选择了一个.php文件进行上传。首次测试结果点击上传按钮后页面立刻弹窗提示“文件类型不支持请上传图片格式”文件并未发生网络上传。这说明存在前端JavaScript校验。绕过方法这是最简单的防护。打开浏览器开发者工具的“Sources”或“调试器”面板找到负责上传的JavaScript文件通常可以搜索file、upload、check等关键词。我很快找到了一个名为validateFileType()的函数它通过检查文件名后缀如.jpg,.png来过滤。绕过方法有两种禁用浏览器JavaScript直接在浏览器设置中禁用JS然后重试上传。拦截并修改请求更常用的方法是让前端校验通过然后在文件被发送到服务器的途中进行“调包”。这就是BurpSuite登场的时候。我保持JS开启正常选择一个.jpg图片文件但在点击上传前先打开BurpSuite的代理拦截功能。3. 核心工具配置与抓包技巧详解BurpSuite是Web安全测试的“瑞士军刀”在文件上传漏洞利用中其代理和重放功能至关重要。很多新手卡在抓不到包或改包无效上这里详细说明我的配置和技巧。3.1 BurpSuite代理环境搭建首先确保你的浏览器网络流量经过BurpSuite。Burp端配置打开BurpSuite在Proxy-Options标签页下确保代理监听器Proxy Listeners是启用的默认是127.0.0.1:8080。记住这个地址和端口。浏览器端配置以Chrome为例安装SwitchyOmega这类代理管理插件。新建一个情景模式配置代理协议为HTTP代理服务器为127.0.0.1端口为8080。然后选择这个模式。安装CA证书为了拦截HTTPS流量必须在浏览器中安装BurpSuite的CA证书。在浏览器中访问http://burp或127.0.0.1:8080点击“CA Certificate”下载证书文件然后在浏览器的证书管理设置中导入并信任该证书。验证访问任意HTTP网站查看BurpSuite的Proxy-Intercept标签页如果显示“Intercept is on”且有请求内容说明配置成功。3.2 精准抓包与拦截策略面对文件上传请求精准抓包是第一步。开启拦截在BurpSuite的Proxy-Intercept标签页确保按钮状态是“Intercept is on”。执行上传操作回到浏览器选择那个用于绕过前端校验的合法图片文件比如test.jpg点击上传按钮。分析请求包此时浏览器会卡住因为请求被BurpSuite拦截了。在Intercept标签页你会看到一个POST请求其Content-Type为multipart/form-data。这就是文件上传的请求体。重点关注以下几个部分POST /upload.php HTTP/1.1上传处理程序的路径。Content-Disposition: form-data; namefile; filenametest.jpg这里包含了前端传递的文件名。这是我们后续改包的重点字段之一。请求体最后部分是一串乱码那是图片文件的二进制内容。实操心得有时点击上传后Burp里瞬间闪过多个请求难以精准拦截到上传的那个POST请求。我的技巧是先开启拦截执行操作如果请求太复杂可以先点“Intercept is off”放行所有请求然后去Proxy-HTTP history历史记录里找到刚才那条POST /upload.php的请求。右键选择“Send to Repeater”这样就可以在Repeater模块里进行稳定的重放和修改测试比在Intercept里反复开关拦截要高效得多。4. 漏洞利用绕过服务器端校验拦截到上传请求只是开始真正的挑战在于绕过服务器端的校验。服务器端的防护通常有多层我们需要逐一分析并尝试绕过。4.1 绕过Content-Type校验这是较弱的防护方式。服务器可能只检查HTTP头中的Content-Type字段。攻击前请求在BurpSuite中我们看到Content-Type: image/jpeg。绕过方法即使我们上传一个.php文件只要将这里的Content-Type改为image/jpeg或image/png就可能绕过检查。在Burp的Repeater模块中直接修改这个字段的值然后发送请求观察响应。4.2 绕过黑名单/白名单后缀校验这是更常见的防护。服务器检查文件名后缀。攻击方法在拦截的请求中找到filenametest.jpg这一行。大小写绕过尝试改为filenametest.Php或filenametest.PHP。某些系统在Linux下大小写敏感但Windows服务器或配置不当的检查逻辑可能不敏感。特殊后缀绕过尝试filenametest.php5、filenametest.phtml、filenametest.phps。这些后缀在某些服务器配置下依然会被当作PHP文件解析。双写/点号绕过尝试filenametest.p.phphp如果过滤逻辑是简单删除php字符串可能剩下.php或filenametest.php.、filenametest.php末尾加空格。这在处理文件名时可能引发解析差异。路径拼接绕过如果上传路径可控可尝试filename../../../test.jpg路径遍历或利用服务器解析特性如filenametest.jpg/.php在某些特定环境下可能被解析为PHP。4.3 绕过文件内容头校验Magic Number许多系统会读取文件的前几个字节魔数来判断文件真实类型而不仅仅是看后缀。JPEG文件的魔数是FF D8 FF E0。PNG文件的魔数是89 50 4E 47。绕过方法制作一个“图片马”。先准备一个简单的PHP Webshell内容如?php eval($_POST[cmd]);?。然后使用十六进制编辑器如010 Editor或Linux下的cat命令在Webshell内容之前插入图片的魔数。Linux下命令示例cat real.jpg shell.php shell.jpg.php。这样生成的文件用图片查看器打开显示正常但服务器如果配置不当如未检测文件内容尾部或解析优先级问题当以.php后缀访问时PHP解释器会从?php标签开始执行忽略前面的图片二进制数据。在BurpSuite中我们无法直接修改二进制内容体但可以先制作好“图片马”然后在上传时将filename改为shell.jpg.php同时保持Content-Type为image/jpeg。这是一种组合拳。4.4 实战绕过过程记录在本次实战中我遇到了组合防护。第一层前端JS校验已通过Burp拦截绕过。第二层服务器端检查后缀黑名单.php,.php5,.phtml等。我尝试.php、.Php、.php7均被拦截返回“文件类型非法”。第三层尝试.php点号空格Burp中修改filename为test.php 注意末尾空格。发送请求后返回“上传成功”但访问/uploads/test.php却返回404。查看服务器返回的完整响应发现其中包含了文件存储路径File saved to: /var/www/html/uploads/test.php。这说明服务器端存储时去掉了末尾空格实际保存为test.php。解析漏洞利用我立刻想到这是不是存在解析漏洞我上传了一个名为test.php.jpg的文件。响应成功且存储路径显示为test.php.jpg。直接访问/uploads/test.php.jpg服务器返回了乱码图片二进制被直接输出并未解析。这说明服务器没有将.php.jpg当作PHP执行。关键突破我回想起Apache的解析特性它会从右往左解析后缀直到遇到可识别的类型。如果.php不可识别它会尝试.jpg。但更重要的是一个古老但可能存在的配置AddHandler或AddType。我构造了文件名test.php.xxx。上传成功访问/uploads/test.php.xxx——奇迹发生了浏览器提示下载而不是执行。这说明.xxx没有被当作PHP处理。最终Payload我猜测服务器可能配置了AddType application/x-httpd-php .php .phtml但没有其他。我需要一个服务器不认识但访问时又能触发PHP解析的后缀。我尝试了test.php.末尾点号、test.php::$DATANTFS流对Linux无效均未成功。最后我尝试了空字节截断虽然在高版本PHP中已修复但值得一试。在Burp中修改filename为test.php%00.jpg注意要在Hex视图下将%00修改为真正的空字节00。上传后服务器返回路径为/uploads/test.php空字节后的.jpg被截断。访问/uploads/test.php成功看到了空白页因为文件内容还是图片二进制没有有效的PHP标签。这说明我成功控制了存储的文件名。上传Webshell我将文件内容替换为真正的PHP Webshell代码再次使用filenameshell.php%00.jpg进行上传。访问/uploads/shell.php返回空白这是正常的因为Webshell需要POST参数。使用curl或Burp的Repeater向/uploads/shell.php发送一个POST请求参数为cmdsystem(whoami);。服务器返回了www-data。至此Webshell上传并执行成功。5. 权限提升与内网渗透思路获取Webshellwww-data权限通常只是第一步。为了证明漏洞的危害性或在实际渗透中获取更大价值需要进行权限提升和横向移动。5.1 信息收集与权限提升在Webshell中执行命令收集系统信息whoami/id查看当前用户。uname -a查看内核版本。cat /etc/passwd查看系统用户。ps aux查看进程寻找root权限运行的服务。find / -perm -4000 -type f 2/dev/null查找SUID特权文件。sudo -l查看当前用户可以以root身份执行哪些命令需要密码。在本次环境中通过sudo -l发现www-data用户被允许以root身份无需密码运行/usr/bin/vi。这是一个经典的提权路径。我们可以通过sudo vi打开一个文件然后在vi中执行:!bash或:!/bin/sh来启动一个root shell。5.2 内网探测与横向移动拿到服务器权限后内网可能是更广阔的战场。网络信息收集ifconfig/ip addr查看内网IP段。netstat -antp查看网络连接和监听端口。探测内网存活主机上传一个静态编译的nmap二进制文件或使用脚本如for i in {1..254}; do ping -c 1 192.168.1.$i done进行存活探测。收集敏感信息在Web目录、配置文件如/etc/passwd,/etc/shadow需root、数据库配置文件如config.php,wp-config.php、用户家目录、历史命令.bash_history中寻找数据库密码、SSH密钥、其他系统凭证等。利用凭证横向移动如果找到SSH私钥或密码可以尝试登录内网其他机器。数据库密码可能在其他Web应用中复用。重要注意事项权限提升和内网渗透高度依赖于具体环境没有通用方法。上述vi提权只是一个例子。在实际授权测试中这些操作必须在获得明确授权的前提下进行并且要非常小心避免对业务系统造成不可逆的影响。我们的目标是证明漏洞存在及其潜在危害而非破坏。6. 防御方案与安全开发建议从这次攻击复盘我们可以从防御者角度总结出多层防护策略这些应该是开发和安全人员必须落实的。6.1 前端与后端双重校验前端校验为了用户体验可以做但必须明白这只能防君子不能防黑客。任何前端校验都可以被绕过。后端校验核心白名单校验严格限定允许上传的后缀名列表如.jpg,.jpeg,.png,.gif拒绝任何不在列表中的文件。绝对不要使用黑名单。文件类型校验使用服务器的API获取文件的MIME类型如PHP的mime_content_type()或finfo_file()并与白名单后缀进行映射校验。不要信任客户端传来的Content-Type。文件内容校验检查文件头魔数确保文件内容与实际后缀匹配。例如一个.jpg文件必须以FF D8开头。文件重命名上传后使用随机生成的文件名如UUID替换原始文件名并保留原始后缀。例如a1b2c3d4.jpg。这可以防止攻击者直接访问或预测文件路径。目录隔离将上传的文件存储在Web根目录之外。通过后端脚本如readfile()来读取和提供这些文件。如果必须放在Web目录下务必配置服务器如Apache的.htaccess或Nginx的location规则禁止直接执行上传目录下的脚本文件。6.2 服务器安全配置及时更新保持操作系统、Web服务器Apache/Nginx、编程语言PHP/Python及所有组件的最新版本修复已知的解析漏洞。最小权限原则运行Web服务的用户如www-data应具有最低必要权限。禁止其使用sudo避免其访问敏感目录。禁用危险函数在PHP中可以在php.ini中禁用eval(),system(),exec(),shell_exec()等危险函数。配置解析规则明确服务器对文件的解析规则。避免使用模糊的AddHandler配置。对于上传目录可以强制设置所有文件为application/octet-stream类型强制浏览器下载而非执行。6.3 安全监测与响应日志审计详细记录上传操作包括时间、IP、原始文件名、存储路径、文件大小、MD5等。定期审计日志发现异常上传行为如频繁上传、尝试非常规后缀。WAFWeb应用防火墙部署WAF可以拦截许多常见的攻击payload包括文件上传漏洞利用的请求。文件内容安全扫描对上传的图片等文件可以使用开源或商业的扫描引擎检测其中是否隐藏了恶意代码。定期渗透测试邀请专业的安全团队或使用自动化工具对系统进行定期的安全评估主动发现类似漏洞。文件上传漏洞的利用与防御是一场持续的博弈。攻击者的手法在进化防御者的策略也需要层层加固。通过这次完整的实战复盘我希望不仅展示了攻击链更能让防御者理解每一层防护为何如此重要。安全是一个整体任何一个环节的疏忽都可能导致全盘沦陷。对于开发者而言在设计上传功能时必须将“不信任任何客户端输入”作为铁律实施上述多层防御策略才能有效守护系统安全。