游客发表

文件上传漏洞绕过方法

发帖时间:2026-10-17 05:08:06

去年有个客户找我做渗透测试,文件目标是上传一个看起来挺正规的企业OA系统。前端限制得挺严,漏洞只允许上传jpg和png,绕过还加了JavaScript校验。文件我随手抓了个包,上传把文件名改成shell.php,漏洞Content-Type改成image/jpeg,绕过直接放行。文件服务器照单全收,上传Webshell就这么进去了。漏洞这事说明一个道理:前端校验永远是绕过纸糊的墙。

文件上传漏洞的文件核心问题不在上传本身,在于服务器怎么处理这个文件。上传很多开发者觉得限制一下扩展名就万事大吉,漏洞实际上绕过手段多到让人头疼。

后缀名那点事

黑名单是最常见的做法,比如禁止.php、.jsp、.asp。问题是黑名单永远列不全。.php3、.php5、.phtml、.phar这些后缀在特定配置下照样能被解析。Apache的mod_mime模块会根据AddHandler指令把.php和.phtml都交给PHP解析器,开发者可能压根不知道这回事。

大小写也经常被忽略。.PhP、.PHP在Windows环境下和.php没区别,但黑名单如果只匹配小写就废了。还有在末尾加空格或点号,shell.php.或者shell.php ,Windows会自动去掉这些字符,Linux某些版本也有类似行为。

更隐蔽的是利用::$DATA这种NTFS数据流特性。上传shell.php::$DATA,Windows保存后实际文件名变成shell.php,校验的时候看到的又是另一个东西。这招在IIS上特别好使。

Content-Type骗局

有些系统检查请求头里的Content-Type,觉得改成image/png就安全了。抓包改一下的事,Burp Suite里一秒钟搞定。我见过一个系统,后端拿Content-Type去判断文件类型,然后决定存到什么目录。改成image/gif就存到图片目录,改成application/x-php就存到脚本目录。攻击者自己选路径,这跟开门揖盗有什么区别。

内容检测的猫腻

稍微认真点的会检查文件头。比如GIF89a、PNG的魔数。绕过方法也简单,在Webshell前面加一行GIF89a就行。PHP解析器遇到非PHP标签的内容会直接输出,不影响后面代码执行。图片马就是这么来的,配合文件包含漏洞用,效果拔群。

有些还会用getimagesize()函数验证。这个函数确实能读图片尺寸,但攻击者可以构造一个合法的图片文件,把PHP代码塞在EXIF注释里。上传后配合本地文件包含,照样能触发。

解析漏洞才是大杀器

Apache有个经典漏洞:shell.php.abc会被当作PHP解析,因为Apache从右往左找可识别的扩展名,遇到不认识的.abc就跳过,继续找.php。Nginx早年也有类似问题,shell.jpg%00.php在特定版本下能截断。

IIS 6.0的解析漏洞更离谱,shell.asp;.jpg直接当ASP执行,分号后面的内容被忽略。还有shell.asp/abc.jpg这种目录解析,IIS会把shell.asp当目录,里面所有文件都按ASP解析。

这些漏洞现在少见了,但老系统还在跑。去年碰到一个政府单位的站,IIS 7.5,shell.php.jpg上传后访问shell.php直接解析。问了一下,运维说“我们用了最新的Windows Server”。版本号确实新,但FastCGI配置里cgi.fix_pathinfo没关,照样中招。

竞争条件和文件名截断

有些系统上传后先存临时文件,校验通过再改名。如果校验和改名之间有时间差,攻击者可以在这期间访问临时文件。用Python写个脚本疯狂请求,总有一次能命中。这叫竞争条件,利用难度高但确实存在。

文件名截断在PHP 5.3.4之前有效,shell.php%00.jpg,%00后面的内容被忽略,实际保存为shell.php。现在PHP版本都高了,但这招在Java或.NET的老系统里偶尔还能碰到。

防御不是加个黑名单就完事

白名单比黑名单靠谱,但白名单也得看怎么实现。只允许jpg,那就得确保上传后的文件真的按jpg处理,而不是看后缀。最好的办法是重命名文件,用随机字符串加白名单后缀,存到Web目录之外,通过脚本读取。这样即使上传了恶意文件,也执行不了。

还有,别把上传目录和Web根目录放一起。我见过太多系统直接传到/upload/下面,然后/upload/shell.php就能访问。分离存储加权限控制,能挡住大部分问题。

最后说一句,文件上传漏洞的本质是信任边界问题。前端不可信,Content-Type不可信,文件名不可信,甚至文件内容都不可信。服务器端只认自己重新生成的东西,其他一律当敌人处理。

    热门排行

    友情链接