0


文件上传漏洞upload-labs靶场通关教程 1-20(带原理)

Pass-01 (JS验证)

提示:本pass在客户端使用js对不合法图片进行检查

这里直接跳出弹窗提示 了,可以看出来这个验证是在前端进行的,众所周知,前端都是纸老虎直接禁用掉就好了

<form enctype="multipart/form-data" method="post" οnsubmit="return checkFile()">

从form表单可以看出他在使用了onsubmit这个函数,触发了鼠标的单击事件,

在表单提交 后马上调用了return checkFile这个函数对上传的文件进行检查

绕过方式:

第一种:第一种方式创建一个新的html文件,将页面的源代码复制下来,进行修改删除操作禁用掉里面的js脚本。

form表单中添加第一关的提交地址

第二种:直接按F12 把onsubmit这个直接删除掉

这里不推荐第二种,因为如果是在浏览器查看器中直接删除的话,可能他还有一些正常的js,

如果把正常的js给删除掉的话,可能正常的js会影响到上传操作

第三种:抓包修改(不推荐)

上传前,随便使用一张图片格式的照片进行上传比如1.png 使用bp进行拦截,将filename

=1.png 修改成1.php 并且把 图片的内容进行替换,替换成一句话代码绕过

这里在前端漏洞不推荐使用抓包修改数据。因为极大可能抓取不到数据包。

这里能抓取到的原因是因为他的代码是php+html+js的一个混编代码,他做了一个前后端的交互(向后端进行提交)才可以抓取到数据包。如果第一关的页面没有对php的页面进行接受,他可以单纯的只有js对网站的信息进行截取,并且保存。如果整个上传的流程到解析都 用js去写的话 ,就抓不到了,因为js所有的操作都在前端执行,不会发送到后端的服务器,不进行交互。所以在有的时候在对其他网站进行访问的时候抓取不到数据包,极大的可能就是因为对方的页面,没有发送到后端的服务器,全部都是本地端的代码(html,js)

Pass-02 (后端验证)文件类型校验(MIME校验)

提示:本pass在服务端对数据包的MIME进行检查!

从源代码中可以看出只对文件类型(type)进行了验证,必须要是image/jpeg或者image/png或者

image/gif的格式,没有对后缀进行验证,只需要使用bp抓包将Content-Type:的参数修改成

image/jpeg或者image/png或者image/gif其中的一种,进行绕过就好

科普一下什么是MIME

MIME:多用途互联网邮件扩展协议。用途为根据文件后缀名判断文件类型,用什么应用程序打开,但是在这里是根据文件类型判断后缀名。

$_FILES['myfile']['type']文件的MIME类型,需要浏览器提供该信息的支持,例如"image/gif"

MIME 给出的是文件的MIME信息 ,此信息可以用来在HTTP Conten-type 头 信息中发送 正确的信息,如:header("Cotent-type:image/gif")

文件格式
编辑
播报
最早的HTTP协议中,并没有附加的数据类型信息,所有传送的数据都被客户程序解释为超文本标记语言HTML 文档,而为了支持多媒体数据类型,HTTP协议中就使用了附加在文档之前的MIME数据类型信息来标识数据类型。
MIME意为多功能Internet邮件扩展,它设计的最初目的是为了在发送电子邮件时附加多媒体数据,让邮件客户程序能根据其类型进行处理。然而当它被HTTP协议支持之后,它的意义就更为显著了。它使得HTTP传输的不仅是普通的文本,而变得丰富多彩。
每个MIME类型由两部分组成,前面是数据的大类别,例如声音audio、图象image等,后面定义具体的种类。
七种大类别:
video
image
application
text
audio
multipart
message
常见的MIME类型(通用型):
超文本标记语言文本 .html text/html
xml文档 .xml text/xml
XHTML文档 .xhtml application/xhtml+xml
普通文本 .txt text/plain
RTF文本 .rtf application/rtf
PDF文档 .pdf application/pdf
Microsoft Word文件 .word application/msword
PNG图像 .png image/png
GIF图形 .gif image/gif
JPEG图形 .jpeg,.jpg image/jpeg
au声音文件 .au audio/basic
MIDI音乐文件 mid,.midi audio/midi,audio/x-midi
RealAudio音乐文件 .ra, .ram audio/x-pn-realaudio
MPEG文件 .mpg,.mpeg video/mpeg
AVI文件 .avi video/x-msvideo
GZIP文件 .gz application/x-gzip
TAR文件 .tar application/x-tar
任意的二进制数据 application/octet-stream

操作步骤:

第一步:开始BP抓包。

第二步:上传php的 文件,修改Conten-type

上传成功

以下关卡涉及到函数

函数解析:

trim():去除左右两侧的空白
deldot():删除末尾的店
strrchar(string,char):函数查找串,在string字符串中查找,char在string字符串中最后一次出现的位置,返回并从该位置截取到尾,如果没有找到字符,则返回false
strrchar('hello  wordld,i love you ','i')
输出结果: i love you 
strtolower():函数 把所有字符串装换成小写
str_ireplace(fine,replace,strin):替换,
在strin字符串中,去搜索fine字符串,如果
搜到到匹配上了,用replace字符串进行替换

Pass-03 (文件后缀名校验,黑名单 绕过)

提示:本pass禁止上传.asp|.aspx|.php|.jsp后缀文件!

查看原代码

分析一下代码:

这里使用了数组的方式,设置的黑名单,不允许.asp .aspx .php .jsp的后缀名进行上传。

绕过思路:php开发了这么久了,不止只有这一个文件名,我们可以使用其他的php的别名进行绕过:.php3 .php4 .php5 .phtml .phtm .phps .phpt .php345 (但是这里是有前提条件的)就是对方的服务器的配置有对这些php其他的文件名配置了解析的设置,否认就算你上传上去了,还是解析失败。

配置好了对应的解析,直接修改文件名就好了把1.php修改成你配置的对应的解析的文件名。

比如:1.php修改后1.phtml

Pass-04 (文件名后缀验证,配置文件解析控制)

提示:

本pass禁止上传.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.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进行验证,那么我们就可以使用.htaccess进行绕过

.htaccess功能介绍:htaccess文件是Apache服务器中的一个配置文件。这个文件的可以不用获得root的权限,就可以更改这个目录下的所有的文件配置。那么说明只要创建一个.htaccess的文件,并且写入php的 配置,上传到这个服务器上,那么这个.htaccess所在的目录下的所有文件的配置就会都修改成转换成php的解析格式。(.htaccess文件只对Apache服务器有效)。

操作步骤:

1.首先先创建一个.htaccess的文件在文件中写入

SetHandler application/x-httpd-php

保存下来 。

2.把这个文件上传到服务器上。

3.将一句话木马文件名修改成gif/png/jpe其中格式的一种。比如2.png

4.将1.gif(一句话木马的文件)上传到服务器

上传成功。

这里的关键点就是.htaccess这个文件,把所有的目录下的文件的解析方式都修改成了php,

所以我们第二次上传的图片2.png “png”不在黑名单中,但是由于.htaccess文件所以又把他解析成了php的格式,所以可以完成正常的解析。

Pass-05(文件名后缀验证 拼接绕过)

提示:上传目录存在php文件(readme.php

查看源码:

还是黑名单 验证:".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");

把.htaccess都进行了验证。

这关可以看出很难绕过了,对过滤也十分完整了

绕过思路:

$file_name = deldot($file_name);//删除文件名末尾的点,重点就是这里。在代码中可以看出对所有的过滤都是采用的是一次性过滤,这里删除末尾的点. 只删除了一次,那么我们就可以使用

点+空格+点绕过 ,deldot()这个函数的作用就是删除末尾的点,当检查到末尾的点时,他会进行删除,然后继续先前检测点,但是这个deldot这个函数遇到空格会停下来,相等于碰到空格就终止操作。所以我们 只要在上传文件的时候使用 点+空格+点 绕过就好了,这样我们在检查的文件

原本是1.php. . ,就变成了1.php. ,那么1.php. ,既不在黑名单中又可以成功进行绕过,又利用了系统的特性 ,在保存这个文件的时候系统又自动去除掉了1.php. 末尾的点。最终保存在电脑的文件就变成了1.php

操作步骤:

第一步:直接上传一句话木马的php文件。

第二步:使用bp进行抓包修改数据

直接.+空格+.

第三步:放包

完成

Pass-06 (文件名后缀验证,大小写绕过)

查看提示:

本pass禁止上传.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.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后缀文件!

查看源码

这里和之前的源码进行对比一下,可以发现没有使用strtolower()这个函数,把后缀都转换成小写,那么我们就可以使用大小写的方式绕过黑名单。

操作步骤:

第一步:上传一个.php的文件

第二步:开启bp抓包修改数据

第三步:放包

上传成功

Pass-07(文件名后缀验证,空格绕过)

提 示:
本pass禁止上传.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.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后缀文件!

查看源码

从源码中可以看出没有对文件名后缀的空白使用trim()进行过滤,借助windows系统的特性,文件名中的空格在最后保存文件时会被作为空处理,最后在保存的时候把后面的空格自动删除掉。

但是在程序中检查代码的时候检查到空格却不能自动删除空格。同时又绕过了黑名单的验证

操纵步骤:

第一步:上传一个.php的文件

第二步:开启bp抓包修改数据,在文件名的后缀添加空格

第三步:放包

上传成功

Pass-08(文件名后缀名验证,点绕过)

提示:本pass禁止上传所有可以解析的后缀!

查看源码

对比发现,没有对末尾的点使用deldot(),进行过滤,没有删除末尾的点,再次利用windows的特性,在文件名的后缀加上点号,在最终保存的文件windows系统自动去除掉后面的点,保存文件。同时绕过黑名单的验证。

操纵步骤:

第一步:上传一个.php的文件

第二步:开启bp抓包修改数据,在文件名的后缀添加点号 绕过

第三步:放包

上传成功

Pass-09(文件名后缀验证,::$DATA绕过)

提示:

本pass禁止上传.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.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后缀文件!

查看源码

对比之前的源码发现这里没有使用 str_ireplace()对::$DATA进行过滤,没有替换成空。

什么是::$DATA呢?

::$DATA这是一种windows操作系统处理文件时的特性,为文件流,如果文件名后有此标记::$DATA

,并且没有做过滤,windows会不检查,直接保存该文件。使用他的目的就是不检查后缀名。

所以我们只要在文件名后面加上::$DATA就可以成功绕过

操作步骤:

第一步:上传一个.php的文件

第二步:开启bp抓包修改数据,在文件名的后缀添加::$DATA绕过

第三步:放包 查看文件

把后面的::$DATA删除掉就可以看到刚刚上传的文件了

上传成功

Pass-10

绕过方式和第五关一样,重复了

Pass-11(文件后缀名验证 ,双写绕过)

提示:

本pass会从文件名中去除.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.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字符!

查看一下源码

这一关重点的是str_ireplace($deny_ext,"", $file_name);这个函数,将文件名中出现在黑名单的这些后缀都替换成空,假如我们上传一个phpinfo.php被过滤后就变成了phpinfo,就没有后缀无法解析了,但是她这次也是使用的是一次性过滤,比如说我们上传phpinfo.phpphp,那么在一次性被过滤后我们原本上传的phpinfo.phpphp,就变成了phpinfo.php。 前面的php被匹配到替换成功,但是后面的第二个php没有被替换成空。

操作步骤:

第一步:上传一个.php的文件

第二步:开启bp抓包修改数据,在文件名的后缀添加php绕过。

第三步:放包

成功

Pass-12(文件名后缀白名单验证,GET 型%00 截断)

提示:

本pass上传路径可控!

查看源码

分析源码:

1.$ext_arr = array('jpg','png','gif'); 这里使用了数组做了一个白名单

2.$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);

截取文件名的后缀从点的位置开始截取,并且使用的是循环的方式截取,不是采用 一次性

对($_FILES['upload_file']['name']进行验证

  1. if(in_array($file_ext,$ext_arr)){ 判断上传的文件名后缀是否在白名单中,如果在进入循环。

  2.   $temp_file = $_FILES['upload_file']['tmp_name']; 进入循环,给上传的文件放在一个临时的目录下,并且生成一个临时文件名
    

5.$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;(这一步是关键)

使用$_GET['save_path']接受自定义的路径,并且随机从10,99的数组在随机生成一个文件名,

在拼接上$file_Ext 前面截取的后缀名。

6.(move_uploaded_file($temp_file,$img_path)){

最终将前面保存的$temp_file临时文件移动 到$img_path

原理 :

00截断利用的是php的漏洞,php的基础是C语言实现的,在C语言中认为%00是结束的符号,所以就基础了c的特性,在PHP<5.3.4的版本中,在进行存储文件时碰见了move_uploaded_file这个函数的时候,这个函数读取到hex值为00的字符,认为读取结束,就终止了后面的操作,出现00截断

绕过思路:

首先使用的是白名单,从代码中可以看出他首先对上传的文件名的后缀进行了验证。

所以我们在第一步上传$_FILES['upload_file']['name'],文件名的时候必须后缀是.jpg.png.gif的格式。绕过后缀名的验证后,进入到循环。最后重点他保存的文件是

$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;,由上传路径决定的,原参数$_GET['save_path'],save_path=../upload/。 那么上传路径可控的 。我们就使用%00截断,把上传的路径修改为文件名。最后利用move_uploade_file这个函数发挥出%00截断的功能。

假如我们没有使用%00截断前最终上传的文件名可能是

../upload/ 237298 .png

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

使用%00截断后

../upload/1.php%00 237298 .png

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

最后 保存的文件就变成了

../upload/1.php

操作步骤:

第一步:上传一个.php的文件

第二步:开启bp抓包修改数据,filename="phpinfo.png" 后缀修改成图片格式,

替换文件中的内容。修改?save_path=../upload/1.php%00

访问图片 地址

将后面的参数删掉 ,因为我们最终保存在目录下的是1.php

上传成功

注意:过这关和下一个需要把php换成<5.3.4的版本,并且php.ini中关闭magic_quotes_gpc选项。

Pass-13(文件名后缀白名单验证,POST型%00 截断)

提示:本pass上传路径可控!

这关没啥好说的,原理和上一关一样,不过是使用POST 方式进行传参的。所以需要在%00的时候进行编码。

GET会自动解码%00

比如说你在url输入空格,他自己会进行判断并且把他进行编码知道你想要的%00,在url干嘛的。

但是POST里面 加%00 POST不会自动解码,你在POST中输入的%00 他会认为是普通文本的%00,那么普通文本他就会编码成%25%30%30.不是我们想要的%00,所以我们需要自己把他先进行编码 。

操作步骤:

第一步:上传一个.php的文件

第二步:开启bp抓包修改数据,filename="phpinfo.png" 后缀修改成图片格式,

save_path"=../upload/1.php%00

选中%00进行编码

放包

上传成功

Pass-14(文件内容检查 ,文件头验证)

提示:本pass检查图标内容开头2个字节!

查看一下源代码

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 = "上传出错!";
        }
    }
}

代码分析:这一关对图片的内容进行了验证,本题给了提示此关检查的是文件头部信息,通过检查文件的前2个字节,检查上传文件二进制的头部信息,来进行判断文件的类型。所以这一关修改后缀是没有用的。使用图片码的方式绕过。

操作步骤:

1。制作图片码 准备一张图片,在准备一个一句话木马的php文件

2.打开cmd 使用命令制作图片码

copy 1.jpg /b + 1.php /a  shell.php

3.直接上传

复制图片链接地址

4.点击"文件包含漏洞"的地址,进行传参。

Pass-15-16(文件内容检查)

绕过方式和上题一样。

不管代码写的在好,使用的啥函数进行过滤,只要图片码在浏览器中可以正常显示,打开。那么就可以使用文件解析漏洞绕过。(前提是有这个漏洞,如果这个没有漏洞,什么格式解析什么格式。图片格式就是解析图片格式,代码格式就是解析代码格式,不要妄想用图片解析出代码的效果)

Pass-17(文件内容检查,图片二次渲染)

提示:本pass重新渲染了图片!

查看源代码

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])){
    // 获得上传文件的基本信息,文件名,类型,大小,临时文件路径
    $filename = $_FILES['upload_file']['name'];
    $filetype = $_FILES['upload_file']['type'];
    $tmpname = $_FILES['upload_file']['tmp_name'];

    $target_path=UPLOAD_PATH.'/'.basename($filename);

    // 获得上传文件的扩展名
    $fileext= substr(strrchr($filename,"."),1);

    //判断文件后缀与类型,合法才进行上传操作
    if(($fileext == "jpg") && ($filetype=="image/jpeg")){
        if(move_uploaded_file($tmpname,$target_path)){
            //使用上传的图片生成新的图片
            $im = imagecreatefromjpeg($target_path);

            if($im == false){
                $msg = "该文件不是jpg格式的图片!";
                @unlink($target_path);
            }else{
                //给新图片指定文件名
                srand(time());
                $newfilename = strval(rand()).".jpg";
                //显示二次渲染后的图片(使用用户上传图片生成的新图片)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagejpeg($im,$img_path);
                @unlink($target_path);
                $is_upload = true;
            }
        } else {
            $msg = "上传出错!";
        }

    }else if(($fileext == "png") && ($filetype=="image/png")){
        if(move_uploaded_file($tmpname,$target_path)){
            //使用上传的图片生成新的图片
            $im = imagecreatefrompng($target_path);

            if($im == false){
                $msg = "该文件不是png格式的图片!";
                @unlink($target_path);
            }else{
                 //给新图片指定文件名
                srand(time());
                $newfilename = strval(rand()).".png";
                //显示二次渲染后的图片(使用用户上传图片生成的新图片)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagepng($im,$img_path);

                @unlink($target_path);
                $is_upload = true;               
            }
        } else {
            $msg = "上传出错!";
        }

    }else if(($fileext == "gif") && ($filetype=="image/gif")){
        if(move_uploaded_file($tmpname,$target_path)){
            //使用上传的图片生成新的图片
            $im = imagecreatefromgif($target_path);
            if($im == false){
                $msg = "该文件不是gif格式的图片!";
                @unlink($target_path);
            }else{
                //给新图片指定文件名
                srand(time());
                $newfilename = strval(rand()).".gif";
                //显示二次渲染后的图片(使用用户上传图片生成的新图片)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagegif($im,$img_path);

                @unlink($target_path);
                $is_upload = true;
            }
        } else {
            $msg = "上传出错!";
        }
    }else{
        $msg = "只允许上传后缀为.jpg|.png|.gif的图片文件!";
    }
}

代码分析:

这一关主要就是使用了imagecreatefrom系列的函数。

这个函数的主要功能就是,使用上传的图片去生成一张新的图片,生成的结果会返回一个变量,

成功返回ture,失败返回false。并且这个函数,可以在他进行重新创建图片的时候,会将我们图片的信息和非图片的信息进行分离,也就是说如果我们在一张图片中加入了代码,那么他会 在你上传后把这张图片在新建的时候把其中的代码筛选出来,并且去除。最后只保留你的图片信息,在进行排序重建。

图片的二次渲染的操作就是在imagecreatefrom这里进行的

操作步骤:

借助010 Editor工具

GIF 格式绕过

第一步:首先使用GIF的图片和代码的文件使用命令合并成一张图片

copy 1.gif /b + 1.php /a  blank.gif 

第二步。 将合并好的文件上传到服务器上

第三步。将第一步的合成好的GIF图片使用010 Editor 工具打开

并且把第二步上传完的图片,到upload目录下寻找,将上传完成后已经被二次渲染后的图片,也使用010 Editor工具打开。

第4步。把这两个文件进行比较,

寻找蓝色部分没有被排列重组的地方

在二次渲染后7907.gif图片中加入一句话代码,

保存下来。

第五步:把刚刚保存好的7907.gif图片从upload目录下,剪切到你要上传文件的目录。

第六步:将7907.gif图片重新上传到服务器上

第7步:点击文件包含漏洞url,传参。

成功

PNG 图片绕过
以为png和jpg的图片结构和gif不同,而且利受损这里要借助大牛的一个脚本完成

大牛脚本

<?php
$p = array(0xa3, 0x9f, 0x67, 0xf7, 0x0e, 0x93, 0x1b, 0x23,
           0xbe, 0x2c, 0x8a, 0xd0, 0x80, 0xf9, 0xe1, 0xae,
           0x22, 0xf6, 0xd9, 0x43, 0x5d, 0xfb, 0xae, 0xcc,
           0x5a, 0x01, 0xdc, 0x5a, 0x01, 0xdc, 0xa3, 0x9f,
           0x67, 0xa5, 0xbe, 0x5f, 0x76, 0x74, 0x5a, 0x4c,
           0xa1, 0x3f, 0x7a, 0xbf, 0x30, 0x6b, 0x88, 0x2d,
           0x60, 0x65, 0x7d, 0x52, 0x9d, 0xad, 0x88, 0xa1,
           0x66, 0x44, 0x50, 0x33);

$img = imagecreatetruecolor(32, 32);

for ($y = 0; $y < sizeof($p); $y += 3) {
   $r = $p[$y];
   $g = $p[$y+1];
   $b = $p[$y+2];
   $color = imagecolorallocate($img, $r, $g, $b);
   imagesetpixel($img, round($y / 3), 0, $color);
}

imagepng($img,'./1.png');
?>

第一步。将使用大牛的脚本创建一个.php文件
第二步。 准备好一张png格式的图片

第三步。进入cmd,使用php命令执行php脚本

php beffpng.php hh.png 生成一个新的1.png文件图片

第四步:使用1.png进行上传
第五步:将图片地址复制有文件包含的漏洞的url打开
第六步:对大牛脚本中的一句话代码进行传参 <?$_GET[0]($_POST[1]);?>
127.0.0.1/upload-labs/include.php?file=upload/126.png&0=assert
1=phpinfo();

完成

jpg 我实在搞不过去,找了一下午的方式,不是脚本过不去,就是图片过不去,
因为我这个实验没有成功 我就不放教程上来了,因为实验未成功,不确定。你们可以自己寻找寻找脚本
或者教程。

Pass-18 (逻辑漏洞,条件竞争)二次渲染

提示:

需要代码审计!

查看源码:

$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 = '上传出错!';
    }
}

代码分析:

$ext_arr = array('jpg','png','gif');使用数组的方式生成了一个白名单

$file_name = $_FILES['upload_file']['name'];使用超级全局变量接受文件

$temp_file = $_FILES['upload_file']['tmp_name'];将上传的文件存储到一个临时目录下,并且使用临时名存储。

substr($file_name,strrpos($file_name,".")+1); 使用循环的方式截取.的位置。截取文件后缀名

$upload_file = UPLOAD_PATH . '/' . $file_name; 设置上传的路径

 if(move_uploaded_file($temp_file, $upload_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);将$upload_file重命名成$img_path

这一关属于逻辑上的漏洞

由于开发者没有在第一步进行验证,导致文件在上传后在进行验证导致的。

if(move_uploaded_file($temp_file, $upload_file)){。在这步操作中可以看出来,在第一步的时候没有对文件进行验证,就直接将文件进行移动到服务器中了,那么说明,在没有验证之前,不管你上传的什么文件都上传到服务器了。

绕过思路:

我们可以使用条件竞争的方式绕过,我们在上传这个文件的时候,不断的向这个服务器进行发包,使用另外一个浏览器访问上传文件的路径,不断的去调用这个文件,占用这个文件的资源,阻止他下面的代码操作,那么他后面验证和过滤等一系列操作就不会执行,那么你上传的文件是什么格式的就是什么格式的

什么是条件竞争?

这是一种技术,不是属于漏洞的一种,相等于在文件进行下一步操作之前你就马上访问这个文件,

操作这个文件,占用这个文件,使得后面的操作无法执行。

举个例子 :你现在打开一个文本文件,在里面进行编写内容等操作,没有关闭这个进程。那么你在编辑内容的时候把他进行删除,你看看能不能删的掉。

什么是二次渲染?

二次渲染个人认为就是二次操作。但二次渲染并不是漏洞,只是他运用的技术叫二次操作,但并不是说二次渲染就有漏洞的。在这里有漏洞的原因是开发者没有在第一步就进行验证。如果他是在第一步做了这个验证,那么这个二次渲染技术没问题的

操作步骤:

第一步;从代码中可以看出,在第一步没有进行文件的验证,那么我们就直接上传个.php的文件

第二步:开启BP抓包,随便设置一个变量不断的向服务器进行发包。

发送到Intruder模块

清除掉默认的变量

设置成一个变量

设置一个向服务器不断发包的数量

第三步;点击Start attack开始发包

第四步:打开另外一个浏览器,访问图片的路径地址,加上你上传的文件名,不断刷新进行访问

成功。

Pass-19(逻辑漏洞,条件竞争)二次渲染

绕过步骤和上一关一样

Pass-20

提示:

本pass的取文件名通过$_POST来获取。

查看源码:

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

        $file_name = $_POST['save_name'];
        $file_ext = pathinfo($file_name,PATHINFO_EXTENSION);

        if(!in_array($file_ext,$deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH . '/' .$file_name;
            if (move_uploaded_file($temp_file, $img_path)) { 
                $is_upload = true;
            }else{
                $msg = '上传出错!';
            }
        }else{
            $msg = '禁止保存为该类型文件!';
        }

    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

分析代码 :

if (isset($_POST['submit'])) { 是否接收到submit的提交

if (file_exists(UPLOAD_PATH)) { 使用file_exists 检查文件或目录(upload/)是否存在

$deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess");

数组黑名单

$file_name = $_POST['save_name']; 接受post的save_name的值 =upload-19.jpg

 $file_ext = pathinfo($file_name,PATHINFO_EXTENSION);使用pathinfo函数

检查文件的扩展名

if(!in_array($file_ext,$deny_ext)) { 判断文件名是否在黑名单中

$temp_file = $_FILES['upload_file']['tmp_name']; 如果不在将文件移动到临时目录,并且给临时文件名

$img_path = UPLOAD_PATH . '/' .$file_name; 使用 UPLOAD_PATH/拼接$file_name组合成一个新路径

if (move_uploaded_file($temp_file, $img_path)) { 将临时目录下的临时文件,移动到新路径下。

绕过思路:

第一种(%00截断):从源代码可以看出,没有对上传的文件进行过滤,而是对$_POST['save_name'];这里进行了过滤save_name=upload-19.jpg.并且最后保存的路径也是

$_POST['save_name']来决定的。那么我们只要对最后save_name这个保存的文件名进行绕过就好

操作步骤:

第一步:因为没有对我们上传的原文件进行验证过滤,那么就直接上传一个.php的文件上去。

第二步:开启BP修改数据包,对sava_name的值使用%00截断

(这里不直接修改成.php的原因是因为,源代码中使用了pathinfo这个 函数对后缀进行了验证,如果直接修改成.php无法通过验证。所以必须在.php%00的后面加上.jpg 先进行后缀的验证,到最后移动目录时,因为使用的是move_upload_fie这个函数移动和保存目录 和文件名,那么move_upload_fie这个函数在碰见%00又会终止,所以在进行移动upload-19.php%00.jpg,最后保存到服务器的文件就变成了upload-19.php)

注意!!这里是使用POST方式传参的%00记得进行编码!!

第三步:放包

第四步:访问文件

成功

第二种绕过(文件夹名欺骗绕过)

因为知道他验证的是啊save_name
那么save_name的值又=upload-19.jpg
那么他路径的拼接应该是
UPLOAD_PATH . '/' .$file_name;
upload/ upload-19.jpg
使用
uplpad/ uplpad-19.php/. 进行绕过
以为他在进行验证的时候格式是php/. 那么他原的过滤是php 正巧是因为我们加了这个/.不在黑名单中
绕过了他的验证,但是最终文件在保存的时候原来的uplpad/uplpad19.php/.
他会强制保存成upload/upload-19.php 此时就变成了php的格式了。

成功


本文转载自: https://blog.csdn.net/m0_72755466/article/details/128499580
版权归原作者 DDosG 所有, 如有侵权,请联系我们删除。

“文件上传漏洞upload-labs靶场通关教程 1-20(带原理)”的评论:

还没有评论