Kali Linux系统利用DVWA靶场进测试文件上传漏洞:

2019-04-16  本文已影响0人  我准备注销了请取关

文件上传漏洞:

漏洞原因是由于开发人员或者网站运维人员的一些失误导致用户上传的文件可以被服务器当作脚本执行文件解析执行,但是想要成功利用这个漏洞至少需要满足三个条件:1.有效上传点;2.上传文件能够被解析执行;3.上传文件能够被访问到.

Low安全级别源代码:

<?php

if( isset( $_POST[ 'Upload' ] ) ) {

// Where are we going to be writing to?

$target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";

$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );

// Can we move the file to the upload folder?

if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {

// No

$html .= '<pre>Your image was not uploaded.</pre>';

}

else {

// Yes!

$html .= "<pre>{$target_path} succesfully uploaded!</pre>";

}

}

?>

Kali Linux系统利用DVWA靶场进测试文件上传漏洞:

菜刀连接成功:

Kali Linux系统利用DVWA靶场进测试文件上传漏洞:
注:可以看到确实没做什么过滤,文件路径DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/"再加上文件名即可绕过.

MediumA安全级别源代码:

<?php

if( isset( $_POST[ 'Upload' ] ) ) {

// Where are we going to be writing to?

$target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";

$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );

// File information

$uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];

$uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];

$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];

// Is it an image?

if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&

( $uploaded_size < 100000 ) ) {

// Can we move the file to the upload folder?

if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {

// No

$html .= '<pre>Your image was not uploaded.</pre>';

}

else {

// Yes!

$html .= "<pre>{$target_path} succesfully uploaded!</pre>";

}

}

else {

// Invalid file

$html .= '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';

}

}

?>

Kali Linux系统利用DVWA靶场进测试文件上传漏洞:
注:红色圈中首先获取了文件类型,保存再$uploaded_type里面,然后再判断这个变量是否符合条件,这个变量实际上就是存储的mime类型.

先试试直接上传脚本:

Kali Linux系统利用DVWA靶场进测试文件上传漏洞:
注:可以看到只允许上传jpeg或者png的图片来绕过这个限制,限制上传php文件路径:1.前端:利用js判断;2.后端:a.判断文件名后缀;b.判断mime类型;c.判断文件内容。首先看看是否是前端JavaScript判断,由于使用的是Chrome浏览器,所以设置一下禁用JavaScript,这样一来页面中JavaScript就不在生效,但是当攻击者尝试上传文件任然不成功,这就说明不是JavaScript限制了攻击者操作.
注:chrome禁用js方法:设置----->高级------->隐私设置和安全性----->内容设置------>禁用js
注:如果后台是使用文件名来判断,那么也就无法让服务器直接将脚本解析,因为现在php版本是5.4,所以以前盛传的文件名%00阶段也不可用了,例如:文件名为1.php%00.jpg,可以绕过后台文件后缀检查,但是在服务器解析是会解析成1.php,原因是%00截断了后面的字符,但是这个方法利用其它5.3.29版本的php没有复现出来,可能或许需要更低版本的php,下面就试试绕过看看是不是后台对mime类型进行判断,这个时候需要用到抓包进行辨别.

BurpSuite抓包结果:

Kali Linux系统利用DVWA靶场进测试文件上传漏洞:

修改Mime类型:

Kali Linux系统利用DVWA靶场进测试文件上传漏洞:

成功绕过:

Kali Linux系统利用DVWA靶场进测试文件上传漏洞:

菜刀连接:

Kali Linux系统利用DVWA靶场进测试文件上传漏洞:

High安全级别源代码:

<?php

if( isset( $_POST[ 'Upload' ] ) ) {

// Where are we going to be writing to?

$target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";

$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );

// File information

$uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];

$uploaded_ext  = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);

$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];

$uploaded_tmp  = $_FILES[ 'uploaded' ][ 'tmp_name' ];

// Is it an image?

if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&

( $uploaded_size < 100000 ) &&

getimagesize( $uploaded_tmp ) ) {

// Can we move the file to the upload folder?

if( !move_uploaded_file( $uploaded_tmp, $target_path ) ) {

// No

$html .= '<pre>Your image was not uploaded.</pre>';

}

else {

// Yes!

$html .= "<pre>{$target_path} succesfully uploaded!</pre>";

}

}

else {

// Invalid file

$html .= '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';

}

}

?>

Kali Linux系统利用DVWA靶场进测试文件上传漏洞:
注:可以看出对文件名后缀以及文件内容进行了判断,实际上getimagesize()函数进行了文件内容的判断.

尝试上传失败:

Kali Linux系统利用DVWA靶场进测试文件上传漏洞:

判断文件图片类型:

  $type    = $_FILES['image']['tmp_name'];

  //文件名

  //$type    = $this->getImagetype( $type );

$filetype = ['jpg', 'jpeg', 'gif', 'bmp', 'png'];

if (! in_array($type, $filetype))

  { 

  return "不是图片类型";

注:如上若用户修改文件后缀为png、jpeg等无法满足限制时,解决方案是采用判断文件的二进制流信息,代码如下:

public function getImagetype($filename)

//判断图片上传格式是否为图片

    {

        $file = fopen($filename, 'rb');

        $bin  = fread($file, 2);

        //只读2字节

        fclose($file);

        $strInfo  = @unpack('C2chars', $bin);

        $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);

        // dd($typeCode);

        $fileType = '';

        switch ($typeCode) {

            case 255216:

                $fileType = 'jpg';

                break;

            case 7173:

                $fileType = 'gif';

                break;

            case 6677:

                $fileType = 'bmp';

                break;

            case 13780:

                $fileType = 'png';

                break;

            default:

                $fileType = '只能上传图片类型格式';

        }

        // if ($strInfo['chars1']=='-1' AND $strInfo['chars2']=='-40' ) return 'jpg';

        // if ($strInfo['chars1']=='-119' AND $strInfo['chars2']=='80' ) return 'png';

        return $fileType;

      //return返回文件后缀

    }


完整限制上传代码:

<?php

$imgurl = "http://www.php10086.com/wp-content/themes/inove/img/readers.gif";

//方法1:strrchr()函数查找字符串在另一个字符串中最后一次出现的位置:

echo $ext = strrchr($imgurl,'.');

echo '<hr>';

//方法2:strrpos()函数如需进行大小写不敏感的查找字符串在另一个字符串中最后一次出现的位置

echo $ext1 = substr($imgurl,strrpos($imgurl, '.'));

echo '<hr>';

//方法3:explode()把字符串分割成数组,取数组最后一个键值

echo(@end(explode(".",$imgurl)));

echo '<hr>';

//方法4:pathinfo(path,options)函数以数组的形式返回文件路径信息,包括以下数组元素:[dirname]、[basename]、[extension],可能的值:PATHINFO_DIRNAME – 只返回dirname、PATHINFO_BASENAME – 只返回basename、PATHINFO_EXTENSION – 只返回extension

echo pathinfo($imgurl,PATHINFO_EXTENSION);

print_r(pathinfo($imgurl));

echo '<hr>';

//方法5:getimagesize获取图片大小

$imginfo= getimagesize($imgurl);

print_r($imginfo);

echo end($imginfo);

echo '<hr>';

//方法6:get_headers获取http报头信息,如果图片路径是一个标准URL路径,那么可以使用get_header这个函数返回http报头

$imghttp = get_headers($imgurl,true);

print_r($imghttp);

echo '<hr>';

//方法7:使用gd类库函数exif_imagetype()读取一个图像的第一个字节并检查其签名,如果发现了恰当的签名则返回一个对应的常量,否则返回FALSE,返回值和getimagesize()返回数组中的索引2的值一样

echo exif_imagetype($imgurl);

总结:比较主流使用的方法是方法1,如果考虑安全问题的话可以使用方法5,因为方法5可以判断这个文件是否为图像文件,可以避免有人把非法程序伪造成图片文件.

注:若不能上传,试试用medium方法,抓包改为mime类型,还是爆出了同样的错误,说明这次不是判断的mime类型了,或者是不止判断了mime类型,猜想可能是对文件的内容进行了判断,可能必须要内容也是图片才行,一般后台判断一个文件是不是图片都是判断一个文件的前几位数据是通过bom头进行判断的,具体说一下利用方法,Windows系统cmd命令行打开,键入如下命令:

copy 文件1.jpg/b+文件2.php/a 新文件.jpg:

Kali Linux系统利用DVWA靶场进测试文件上传漏洞:

根据两个指定的文件生成一个新文件,再查看生成文件内容:

Kali Linux系统利用DVWA靶场进测试文件上传漏洞:
注:可以看到一句话被添加到了文件末尾,现在把刚刚生成的图片后缀名改为php,这样就可以绕过后端对文件头的检查,现在试试上传还是被拦截了,看来真的不止对文件内容进行了判断,带有后缀名的验证,现在还要把后缀名改为jpg或者png,这样一改确实是可以上传了,但是访问的时候不能被解析为php,再加上之前的%00截断不能用,其他利用方法都是配合着文件包含来执行getshell.
Kali Linux系统利用DVWA靶场进测试文件上传漏洞:
上一篇下一篇

猜你喜欢

热点阅读