第六关其实没什么思路,就是对比了一下和第五关的代码发现
第六关代码没有这个
因为后缀名对大小写不敏感的问题,
我们第五关采用了大小写混合注入,那么这关,给后缀名加上留白,能否达到效果呢?我们用burp抓包修改
将.php之前加上留白,forward,ok,成功
老套路,比较第六关和第七关的不同,
发现,第七关缺少这个
意思是我们可以采用末尾加点来绕过判断机制
ok,成功
对比第七关,他少了这个
???这是个嘛呀!!!!靓仔落泪!!算了,百度一波
在php+windows的情况下:如果文件名+":: D A T A " 会 把 : : DATA"会把:: DATA"会把::DATA之后的数据当成文件流处理,不会检测后缀名. 且保持 " :: D A T A " 之 前 的 文 件 名 。 利 用 w i n d o w s 特 性 , 可 在 后 缀 名 中 加 ” : : DATA"之前的文件名。利用windows特性,可在后缀名中加” :: DATA"之前的文件名。利用windows特性,可在后缀名中加”::DATA”绕过
这里和前面几关的代码比较过后发现,已经没有提示了。
$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",".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)) {
$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 . '文件夹不存在,请手工创建!';
}
比较后发现,这就是第一关补了几个漏洞
这里采用叠加注入 后缀名改为(shell.php+点+空格+点)
他每种过滤一个,咱其中一种加两个(机智如我)
测试一下
菜刀试一下,ok成功
第十关和第九关思想差不多,查看代码
他采用了替换函数,将后缀名php替换成了空格,但是,他只替换一次,咱们双写就好了。
把中间的php替换为空格后,剩下的也正好组合成php
注意 不能双写为phpphp
webshell.pphphp
测试
分析代码侯会发现,上传路径是可控的。
那么我们就采用%00截断法,在url中%00是隔断符号,相当于注释符 --+和#
将路径改为path=“upload/webshell.php%00”,那么拼接之后,文件上传时就变成了
“upload/webshell.php%00webshell.jpg”,这时上传便将.php上传进去,而.jpg则被截断
本关需要php的magic_quotes_gpc为OFF状态,所以得先在相应的php版本目录下找到配置文件php.ini,然后把magic_quotes_gpc的状态修改为OFF,修改完之后重启一下服务就可以了
分析一下源代码
$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传进来。
但是这次不能直接抓包在后面加上%00,因为post不会像get一样对%00进行自动解码,
所以得换另一种方法进行%00绕过,
用Burp Suite代理构造sava_path=/upload/webshell.php%00,然后再filename处修改文件拓展名为png(或jpg、gif),由于这一关不能对%00进行自动解码,所以还需要在二进制中进行修改,把webshell.php对应的二进制数后面一位改成00。
这里我们需要先制作图片木马
copy 1.jpg /b + 1.php /a shell.jpg\png\gif
之后上传即可
同上
这里介绍一下
exif_imagetype() 读取一个图像的第一个字节并检查其签名。 如果发现了恰当的签名则返回一个对应的常量,否则返回
FALSE。返回值和 getimagesize() 返回的数组中的索引 2 的值是一样的,但本函数快得多。
这一关,具体参照16关通关详细解说
他提示我们需要代码审计
$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 = '上传出错!';
}
}
这段代码重要的点在于先将文件上传到服务器,再判断后缀名,如果合法则保留下来,如果不合法,则删除在服务器的文件。
所以根据这个流程,可以通过条件竞争的方式在unlink()函数删除之前,访问上传文件,在此之前先来了解一下条件竞争
条件竞争漏洞是一种服务器端的漏洞,由于服务器端在处理不同用户的请求时是并发进行的,因此,如果并发处理不当或相关操作逻辑顺序设计的不合理时,将会导致此类问题的发生。
在burp中不断发送上传webshell的数据包,然后不断在浏览器中访问,发现通过竞争可以访问到
在嗅探抓包过程中,常见的有两种200和304。这两个状态码都关系到能否获取重要信息。当客户第一次请求服务器资源,服务器成功返回资源,这时状态码为200。所以,状态码为200的数据包往往包含用户从服务器获取的数据。
状态码200:请求已成功,请求所希望的响应头或数据体将随此响应返回。即返回的数据为全量的数据,如果文件不通过GZIP压缩的话,文件是多大,则要有多大传输量。
有200的返回码说明我们已经成功
$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 = '上传出错!';
}
}
这里先用move函数将上传的文件保存,再用renameFile函数重命名。所以也存在条件竞争,绕过方法和上面Pass-17差不多。
这关采取00截断法
先更改保存的文见名称
在用burp将save_name那里的webshell.php.jpg中php后面的点的十六进制(2e)改为00