• [CISCN2021 Quals]upload(PNG-IDAT块嵌入马)


    
    if (!isset($_GET["ctf"])) {
        highlight_file(__FILE__);
        die();
    }
    
    if(isset($_GET["ctf"]))
        $ctf = $_GET["ctf"];
    
    if($ctf=="upload") {
        if ($_FILES['postedFile']['size'] > 1024*512) {
            die("这么大个的东西你是想d我吗?");
        }
        $imageinfo = getimagesize($_FILES['postedFile']['tmp_name']);
        if ($imageinfo === FALSE) {
            die("如果不能好好传图片的话就还是不要来打扰我了");
        }
        if ($imageinfo[0] !== 1 && $imageinfo[1] !== 1) {
            die("东西不能方方正正的话就很讨厌");
        }
        $fileName=urldecode($_FILES['postedFile']['name']);
        if(stristr($fileName,"c") || stristr($fileName,"i") || stristr($fileName,"h") || stristr($fileName,"ph")) {
            die("有些东西让你传上去的话那可不得了");
        }
        $imagePath = "image/" . mb_strtolower($fileName);
        if(move_uploaded_file($_FILES["postedFile"]["tmp_name"], $imagePath)) {
            echo "upload success, image at $imagePath";
        } else {
            die("传都没有传上去");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    检查文件是不是图片,然后还要求宽高需要是1,上传的文件名被 urldecode解码以后检查是否有 c、i、h、ph 这些字符
    文件名 mb_strtolower 转成小写保存

    然后就是 example.php,可以通过扫目录发现

    
    if (!isset($_GET["ctf"])) {
        highlight_file(__FILE__);
        die();
    }
    
    if(isset($_GET["ctf"]))
        $ctf = $_GET["ctf"];
    
    if($ctf=="poc") {
        $zip = new \ZipArchive();
        $name_for_zip = "example/" . $_POST["file"];
        if(explode(".",$name_for_zip)[count(explode(".",$name_for_zip))-1]!=="zip") {
            die("要不咱们再看看?");
        }
        if ($zip->open($name_for_zip) !== TRUE) {
            die ("都不能解压呢");
        }
    
        echo "可以解压,我想想存哪里";
        $pos_for_zip = "/tmp/example/" . md5($_SERVER["REMOTE_ADDR"]);
        $zip->extractTo($pos_for_zip);
        $zip->close();
        unlink($name_for_zip);
        $files = glob("$pos_for_zip/*");
        foreach($files as $file){
            if (is_dir($file)) {
                continue;
            }
            $first = imagecreatefrompng($file);
            $size = min(imagesx($first), imagesy($first));
            $second = imagecrop($first, ['x' => 0, 'y' => 0, 'width' => $size, 'height' => $size]);
            if ($second !== FALSE) {
                $final_name = pathinfo($file)["basename"];
                imagepng($second, 'example/'.$final_name);
                imagedestroy($second);
            }
            imagedestroy($first);
            unlink($file);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    解压文件,然后检查了一下文件是不是 zip 结尾,然后解压图片到 临时目录

    后面开始遍历这个目录找图片,重新计算了图片的大小,然后又重新写到了一个新的文件中,又删掉了旧的图片

    所以在图片末尾添加的马是不会被重新写入新的文件中,必须把马嵌到图片数据中

    所以我们的思路就是上传一个嵌有马的图片的压缩包,然后被解压,重新写入新的文件

    压缩文件名需要是 zip 结尾,但是上传的地方限制了 i 字符,查文档发现可以使用 Unicode 绕过

    php文档

    在这里插入图片描述

    下面也有例子,拉丁文里,大写的 I 上面有个点,小写的 I 上面没有点,可以这样绕过检测 i

    在这里插入图片描述

    可以测试一下

    
    
    $name = "ab.z%c4%b0p";
    
    var_dump(mb_strtolower('İ')==='i');
    
    $fileName=urldecode($name);
    if(stristr($fileName,"i")) {
      die("有些东西让你传上去的话那可不得了");
    }
    echo "image/" . mb_strtolower($fileName);
    # bool(true) 
    # image/ab.zip
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    嵌入马到图片数据中,可以使用这个工具

    PNG-IDAT-Payload-Generator

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    修改后要保证长度不变,然后复制出来,替换回去

    在这里插入图片描述
    在这里插入图片描述

    重新生成马

    在这里插入图片描述
    在这里插入图片描述

    然后就可以压缩包上传了,但是这里会检查getimagesize 有没有图片的宽高等一些属性

    可以添加 #define width 1 #define height 1 绕过检查

    在这里插入图片描述

    解压,执行,在 /etc 目录下发现 flag

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    NFC技术的定义通信方式
    交换机命令
    20. 有效的括号
    前端开发重装系统,软件安装清单
    数仓架构演进
    springboot项目前后端搭建
    元宇宙侵权,虚拟世界还有法律吗?
    最新 Node 初始化 vue 项目报错(npm init vue@latest)以及配置淘宝镜像(cnpm)
    【QT】Osg开发(一)-- 环境配置
    2024年,我又开始用Linux桌面作为主力系统了~
  • 原文地址:https://blog.csdn.net/weixin_49656607/article/details/126904869