打开DVWA(Damn Vulnerable Web Application)的低等级文件上传模块,你会看到一个普通的上传文件选择框和一个“Upload”按钮。界面上甚至没有一行警告文字。漏洞但就是文件这看似人畜无害的交互,成了无数安全测试员的上传第一课——也是无数真实站点的噩梦起点。
我上传了一个名为“shell.php”的漏洞文件,内容只有一行:<?文件php system($_GET['cmd']); ?>。服务器没有半点犹豫,上传直接返回“成功上传”。漏洞紧接着,文件在浏览器地址栏输入路径加参数,上传cmd=ipconfig,漏洞Windows下的文件网络配置信息瞬间喷涌而出。那种感觉像在银行柜台递了张纸条,上传柜员看都不看就给了你金库钥匙。漏洞
为什么这么容易?因为低等级代码里,move_uploaded_file()函数只检查了文件是否移动成功,压根没看文件内容或扩展名。更讽刺的是,DVWA官方文档明明白白写着“这个模块故意不设防”,但现实中仍有大量开发人员犯同样的错误——他们以为上传功能就是“选文件、存文件”这么简单。
换个角度想,文件上传漏洞的本质是什么?是服务器把用户输入当成了“可执行代码”的入口。图片、文档、压缩包,这些本该被当作数据处理的文件,一旦被允许以脚本形式运行,就等于把服务器的执行权交了出去。攻击者不需要多高深的技术,只要会写几行PHP或JSP,再懂点路径遍历,就能拿下整个站点。
我见过一个真实案例:某小型电商网站的后台上传功能只校验了MIME类型——就是浏览器发送的Content-Type头。攻击者用Burp Suite拦截请求,把“image/jpeg”改成“text/php”,文件名改成“avatar.php”,服务器照单全收。最后那个“头像”文件变成了Webshell,攻击者用它读取了数据库配置,拖走了几万条用户信息。整个过程不到十分钟。
DVWA的高等级关卡倒是做得像样:它用getimagesize()检查文件头,强制重命名文件,还限制扩展名必须是jpg或png。但即便这样,仍有绕过思路——比如图片马,把PHP代码塞进图片的EXIF信息里,再配合文件包含漏洞才能触发。这说明什么?单靠上传模块本身,永远防不住所有攻击。安全是链条,上传只是其中一环。
写代码的人总有个错觉:只要过滤了“危险后缀”,就万事大吉。可现实是,黑名单永远追不上攻击者的想象力。.php、.php5、.phtml、.pht,甚至.htaccess都能被利用。白名单才是正解——只允许你需要的文件类型,其余一概拒绝。这道理不难懂,但很多项目急急忙忙上线,漏洞就这么埋下了。
最后说个细节:DVWA低等级上传成功后的页面,会直接显示文件的存储路径。这等于把攻击面主动暴露给用户。现实中,有些系统还会把上传目录放在web根目录下,连路径猜测都省了。如果你在测试中碰到这种站点,别急着兴奋,先想想怎么修复——因为真正的安全,从来不是靠运气,而是靠每个环节都较真。