文件上传漏洞原理与实例测试

0x00 什么是文件上传

  • 为了让用户将文件上传到网站,就像是给危机服务器的恶意用户打开了另一扇门。即便如此,在今天的现代互联网的Web应用程序,它是一种常见的要求,因为它有助于提高业务效率。企业支持门户,给用户各企业员工有效地共享文件。允许用户上传图片,视频,头像和许多其他类型的文件。向用户提供的功能越多,Web应用受到攻击的风险和机会就越大,这种功能会被恶意用户利用,获得到一个特定网站的权限,或危及服务器的可能性是非常高的。

0x01 为什么文件上传存在漏洞

  • 上传文件的时候,如果服务器脚本语言,未对上传的文件进行严格的验证和过滤,就容易造成上传任意文件,包括上传脚本文件。
  • 如果是正常的PHP文件,对服务器则没有任何危害。
  • PHP可以像其他的编程语言一样,可以查看目录下的文件,查看文件中的吗内容,可以执行系统命令等。
  • 上传文件的时候,如果服务器端脚本语言,未对上传的文件进行严格的验证和过滤,就有可能上传恶意的PHP文件,从而控制整个网站,甚至是服务器。这个恶意的PHP文件,又被称为WebShell。

0x02 哪里存在文件上传漏洞

  • 服务器配置不当
  • 开源编辑器的上传漏洞
  • 本地文件上传限制被绕过
  • 过滤不严或被绕过
  • 文件解析漏洞导致文件执行
  • 文件路径截断

0x03 文件上传实例(本地测试)

  • 裸体的文件上传
<!DOCTYPE html>
<html>
<head>
    <title>文件信息</title>
</head>
<meta charset="utf-8">
<body>
<form action="" enctype="multipart/form-data" method="POST" name="uploadfile">
    上传文件: <input type="file" name="upfile" />
    <input type="submit" value="上传" name="submit">
</form>
</body>
</html>
<!-- 完全没有过滤,任意文件上传 -->
<?php
if (isset($_POST[‘submit‘])) {
    var_dump($_FILES[‘upfile‘]);
    echo "文件名:".$_FILES[‘upfile‘][‘name‘]."<br />";
    echo "文件大小:".$_FILES[‘upfile‘][‘size‘]."<br />";
    echo "文件类型:".$_FILES[‘upfile‘][‘type‘]."<br />";
    echo "临时路径:".$_FILES[‘upfile‘][‘tmp_name‘]."<br />";
    echo "上传后系统返回值:".$_FILES[‘upfile‘][‘error‘]."<br />";
    echo "====================保存分各线========================<br />";
    if ($_FILES[‘upfile‘][‘error‘] == 0) {
        if (!is_dir("./upload")) {
            mkdir("./upload");
        }
        $dir = "./upload/".$_FILES[‘upfile‘][‘name‘];
        move_uploaded_file($_FILES[‘upfile‘][‘tmp_name‘],$dir);
        echo "文件保存路径:".$dir."<br />";
        echo "上传成功...<br />";
        echo "图片预览:<br />";
        echo "<img src=".$dir.">";
    }
}
 ?>

设置本地代理用Burp Suite 抓包,通过对比我们可以看到,PHP中的<文件名>和<文件类型>分别对应数据包中<filename>和<Content-Type>。

  • 穿上下内衣的文件上传
<!DOCTYPE html>
<html>
<head>
    <title>文件信息</title>
</head>
<meta charset="utf-8">
<body>
<form action="" enctype="multipart/form-data" method="POST" name="uploadfile">
    上传文件: <input type="file" name="upfile" />
    <input type="submit" value="上传" name="submit">
</form>
</body>
</html>
<!-- 按文件类型过滤 -->
<?php
if (isset($_POST[‘submit‘])) {
    var_dump($_FILES[‘upfile‘]);
    echo "文件名:".$_FILES[‘upfile‘][‘name‘]."<br />";
    echo "文件大小:".$_FILES[‘upfile‘][‘size‘]."<br />";
    echo "文件类型:".$_FILES[‘upfile‘][‘type‘]."<br />";
    echo "临时路径:".$_FILES[‘upfile‘][‘tmp_name‘]."<br />";
    echo "上传后系统返回值:".$_FILES[‘upfile‘][‘error‘]."<br />";
    echo "====================保存分各线========================<br />";
    $flag = 0;
    switch ($_FILES[‘upfile‘][‘type‘]) {
        case ‘image/jpeg‘:
            $flag = 1;
            break;
        default:
            die("文件类型错误.....");
            break;
    }
    if ($_FILES[‘upfile‘][‘error‘] == 0 && $flag ) {
        if (!is_dir("./upload")) {
            mkdir("./upload");
        }
    $dir = "./upload/".$_FILES[‘upfile‘][‘name‘];
    move_uploaded_file($_FILES[‘upfile‘][‘tmp_name‘],$dir);
    echo "文件保存路径:".$dir."<br />";
        echo "上传成功...<br />";
        echo "图片预览:<br />";
        echo "<img src=".$dir.">";
    }
}
 ?>

在这段代码里,我们通过 <$_FILES[‘upfile‘][‘type‘]> 来检测文件上传的类型,通过第一个图里的对比我们知道Http数据包请求头里的<Content-Type >对应的是上传文件的类型,那么我们是不是可以通过修改数据包的内容来实验绕过.ok,现在我们上传一个PHP一句话木马。

<?php
@eval($_POST[‘xxx‘]);
echo "dahuiji....";
 ?>

看返回的页面我们知道我们成功绕过了对文件类型的检测,并且菜刀连接成功

  • 穿上上内衣的文件上传(一个十六进制的<00>截断的ctf)
url:http://ctf4.shiyanbar.com/web/upload/

首先我们对抓取的数据包做出以上修改

通过16进制我们知道 <.>的16进制是<2e>在<2e>出插入一个字节,右键菜单里有<insert byte>插入。

ok,现在我们成功获取了flag。

现在我们说下这个实验的实现原理:

1.为什么在文件后面加上<.jpg>和在数据包<uploads/>后面加上修改后的文件名?
     PHP在对文件后缀进行判断时是对最后一个 <.xxx> 来判断的。这样我们修改过后的文件
  名,PHP会将其判断为.jpg文件这样我们可以绕过对文件名的检测。
  
2.为什么我们对文件名修改过后还需要添加%00截断?
    尽管我们知道我们上传的是一个PHP文件,但是如果不进行%00截断,我们上传的文件在服务
  器上是以<xxx.php.jpg>格式保存也就是说这是一个图片文件,PHP是不会解析这个文件。
  当我们进行%00截断后,服务器就会将%00后的<.jpg>进行截断,这是我们的的文件将以<xxx.php>
  的形式保存在服务器上,我们的一句话木马也就成功的时上传成功了。
  • 穿上外套的文件上传
<!DOCTYPE html>
<html>
<head>
    <title>文件信息</title>
</head>
<meta charset="utf-8">
<body>
<form action="" enctype="multipart/form-data" method="POST" name="uploadfile">
    上传文件: <input type="file" name="upfile" />
    <input type="submit" value="上传" name="submit">
</form>
</body>
</html>
<?php
if (isset($_POST[‘submit‘])) {
    var_dump($_FILES[‘upfile‘]);
    echo "文件名:".$_FILES[‘upfile‘][‘name‘]."<br />";
    echo "文件大小:".$_FILES[‘upfile‘][‘size‘]."<br />";
    echo "文件类型:".$_FILES[‘upfile‘][‘type‘]."<br />";
    echo "临时路径:".$_FILES[‘upfile‘][‘tmp_name‘]."<br />";
    echo "上传后系统返回值:".$_FILES[‘upfile‘][‘error‘]."<br />";
    echo "====================保存分各线========================<br />";
    $flag = 0;
    $path_parts = pathinfo($_FILES[‘upfile‘][‘name‘]);
    echo ‘---<br>‘;
    var_dump($path_parts);    //返回文件路径信息
    if ($path_parts[‘extension‘] == ‘jpg‘ && $_FILES[‘upfile‘][‘type‘] == ‘image/jpeg‘) {
        $flag = 1;
    }else{
        die("文件类型错误....");
    }
    if ($_FILES[‘upfile‘][‘error‘] == 0 && $flag ) {
        if (!is_dir("./upload")) {
            mkdir("./upload");
        }
        $dir = "./upload/".$_FILES[‘upfile‘][‘name‘];
        echo "文件保存路径:".$dir."<br />";
        move_uploaded_file($_FILES[‘upfile‘][‘tmp_name‘],$dir);
        echo "上传成功...<br />";
        echo "图片预览:<br />";
        echo "<img src=".$dir.">";
    }
}
 ?>

上传一张正常的图片。

上传一句话木马进行绕过检测

为什么这次不能进行绕过?
     我们对文件名进行截断后,当数据包到Apache的时候,Apache会对截断处理这时截断的文件
     名变为<xxx.php>当PHP判断时会发现文件的后缀为<php>,然后我们就上传失败了....

 (以上只是我对上传失败的一点理解,欢迎指正。
  欢迎技术讨论,可以将上述方法绕过的同学欢迎指教。
  致谢...)

0x04 上传漏洞的防御

  1. 对面文件后缀进行检测
  2. 对文件类型进行检测
  3. 对文件内容进行检测
  4. 设置上传白名单
时间: 2024-10-10 17:48:40

文件上传漏洞原理与实例测试的相关文章

【Web安全】文件上传漏洞原理分析

0x01 文件上传漏洞简介 为了让用户将文件上传到网站,就像是给危机服务器的恶意用户打开了另一扇门.即便如此,在今天的现代互联网的Web应用程序,它是一种常见的要求,因为它有助于提高业务效率.企业支持门户,给用户各企业员工有效地共享文件.允许用户上传图片,视频,头像和许多其他类型的文件.向用户提供的功能越多,Web应用受到攻击的风险和机会就越大,这种功能会被恶意用户利用,获得到一个特定网站的权限,或危及服务器的可能性是非常高的.上传文件本身没有错,问题与漏洞在于服务器怎么处理上传的文件. 0x0

文件上传漏洞原理以及防范

1. 什么是文件上传漏洞 程序员由于没有对上传的文件进行严格限定,导致黑客可以通过工具上传其他格式的程序文件(比如:webshell),这样黑客就会拿到一个可执行环境,在服务器上搞破坏. 一个常见的例子,很多网站存在上传图片的功能,如果不对上传图片的扩展名进行检测.过滤就会造成上传漏洞. 2. 如何防范上传漏洞 步骤:前端JS代码限定--->后台代码检测--->取消文件目录执行脚本的权限. 以如何防范图片上传漏洞做个过程分析: 新建一个解决方案: 2.1 第一步前端用JavaScript对上传

1_文件上传漏洞原理

0x00 文件上传 File Upload 文件上传是大部分Web应用具有的功能,例如:头像上传,分享图片,视频,上传附件等等 正常的文件一般是图片,视频,文档等,web应用收集后放到后台存储,等到调用的时候调用返回. 如何恶意文件PHP,asp等绕过web应用后直接执行,则相当于黑客直接拿到了webshell 一旦黑客拿到webshell,则黑客可以得到web应用的数据,删除web文件,本地提权,进一步拿到整个服务器,甚至内网. SQL注入攻击的对象是数据库服务,文件上传漏洞的对象是Web服务

《白帽子讲WEB安全》学习笔记之第8章 文件上传漏洞

第8章 文件上传漏洞 8.1 文件上传漏洞概述 文件上传漏洞是指用户上传一个可执行的脚本文件,并通过此脚本文件活动执行服务器端的能力. 原理:由于文件上传功能实现代码没有严格限制用户上传的文件后缀以及文件类型,导致允许攻击者向某个可通过 Web 访问的目录上传任意PHP文件. 文件上传漏洞安全问题: q  上传文件是WEB脚本文件,服务器的WEB服务器解释并执行了用户上传的脚本,导致代码执行: q  上传文件是Flash的策略文件crossdomain.xml,黑客用以控制Flash在该域下的行

owasp文件上传漏洞简析

0x01: 文件上传漏洞起因于,上传程序没有对上传文件格式进行正确判断,导致可执行程序上传到网站目录. 常见的验证上传文件有两种:1.js本地验证,通过js获取上传文件后缀名,并和白名单比较,匹配则上传成功.由于js代码是本地验证,存在绕过风险(去除js代码,构造表单数据,直接绕过). 2.后端程序验证,通过post数据到file_upload()函数,$_FILES['file']['type']判断上传程序后缀名. function file_upload(){ $file_name = $

文件上传漏洞攻击与防御

前言 从一年前开始学习web安全以来,一直都是在吸收零碎的知识,不断地看书与一些前辈的文章,中间也经过一些实践,学习相关的工具,但是却没真真正正地在脑中形成一套完整的体系.从不久前就想着要写一些博客,趁着这个机会,便好好梳理一下所学的知识,只是这些文章所写大部分内容也是搬运前辈的文章,鲜有自己所想所悟. 关于文件上传漏洞,百度一下便有许多文章出来,在这里我也稍稍做整理. 0x00 文件上传漏洞所需满足的条件 一是文件可上传(感觉这一句是废话).二是上传文件路径可知,如果路径不可知就没法访问,亦无

【原创】JEECMS v6~v7任意文件上传漏洞(1)

文章作者:rebeyond 受影响版本:v6~v7 漏洞说明: JEECMS是国内Java版开源网站内容管理系统(java cms.jsp cms)的简称.该系统基于java技术开发,继承其强大.稳定.安全.高效.跨平台等多方面的优点:采用SpringMVC3+Spring3+Hibernate3+Freemarker主流技术架构.广泛应用于政府(部委和省级政府部门.市.县.乡及委办局).教育科研(大.中.小学及各地方教育局).电信运营商.金融(证券.保险及银行).企业(矿业.煤炭.旅游.石油集

PHP任意文件上传漏洞CVE-2015-2348浅析

昨晚安全新闻爆出一个“PHP任意文件上传漏洞”,CVE编号为:CVE-2015-2348. 当时楼主正准备收拾东西回家,看到这个新闻心里一惊:失传江湖多年的0字符截断上传漏洞又重现了?而且还影响这么多版本!如果漏洞属实,看来今晚又要通宵打补丁了啊. 不过经过简单分析后,发现漏洞的利用条件相当苛刻(很多人好奇到底有多苛刻),楼主简单记录自己的分析过程和大家分享一下,如有不当,请多多指正. 一.漏洞概述 漏洞报告者说php的上传函数 move_uploaded_file的目的路径参数可以使用空字符截

文件上传漏洞及解析漏洞总结

文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力.这种攻击方式是最为直接和有效的,"文件上传"本身没有问题,有问题的是文件上传后,服务器怎么处理.解释文件.如果服务器的处理逻辑做的不够安全,则会导致严重的后果. 文件上传后导致的常见安全问题一般有: 1)上传文件是Web脚本语言,服务器的Web容器解释并执行了用户上传的脚本,导致代码执行. 2)上传文件是Flash的策略文件crossdomain.xml,黑客用以控制Flash在该域下的行为(