-
-
[翻译]如何将 PHP Phar 包转化成图像以绕过文件类型检测
-
发表于: 2018-11-24 16:30 5155
-
2018年的美国黑帽大会表明可以从PHAR包中获取RCE,并且可通过调整其二进制内容,将其伪装成完整的有效图像,从而绕过安全检查。
接下来就让我们一起看看这是如何做到的吧。
在2018年的美国黑帽大会期间,Sam Thomas召开了一个关于利用PHP中的Far://流包装器在服务器上执行代码的会议(幻灯片在此)。
在执行PHAR包时,PHP会将其内容反序列化,允许攻击者启动PHP对象包含链。最有趣的部分是如何触发有效负载:存档上的任何文件操作都将执行它。最后,没有必要猜测正确的文件名,因为失败的文件调用也需要PHP来反序列化其内容。
作为奖励点,完全可以将PHAR包伪装成100%有效的图像。
在这篇文章中,我们将展示如何做到这一点。
有时我们会忘记文件只是遵循预定义结构的一堆字节而已。
应用程序将检查它们是否可以管理这样的数据流,如果它们成功,它们将产生输出。
在他的演讲中,Thomas对如何创建具有有效JPEG标头的PHAR包做出提示。
(图片来自Sam Thomas的演示PPT)
我们要做的就是创建一个包含JPEG头的文件,并相应地更新PHAR校验和。通过这种方式,它将被视为一个图像,但PHP能够执行它。
更改几个字节并更新校验和应该可以轻松完成,对吧?
并不是。
最后,(至少对我来说)计算校验和是一件痛苦的事情。我就在想:是否能用PHP来为我做这些工作呢?
于是,我对Thomas的源码进行了修改:
正如你看到的,我们将原始HEX字节添加到PHAR归档的存根部分。这是原始的HEX结果:
它是一个有效的PHAR包和JPEG图像吗?
PHP成功将其识别为图像,我们可以继续探索存档的内容。
主要内容请查看存根部分并注意看它是如何缺少打开的PHP标记。这是躲过大多数扫描程序的关键部分。使存档有效的关键是__HALT_COMPILER()函数; 我认为PHP会用它作为标记来知道它应该跳过多少数据。
我们有一个文件可以避开所有基于文件头的检查,但不能避开比检测文件头更复杂的一些检查。例如,检查图像的getimagesize将返回false,因为我们没有一个真实的图像文件:
糟糕!
等等,我们完全可以在__HALT_COMPILER()函数之前注入尽可能多的乱码。
如果我们要制作整个图片呢?
花了太多时间来讨论JPEG规范和阅读PHP源代码(我不希望其是我最大的敌人),我决定再次装傻。
我可以简单地使用GIMP创建一个10x10黑色图像,并把它嵌入进去吗?
现在,是检验的时刻了:
最后,我们成功啦!文件是一个PHAR包,其中包含了我们想要利用的类,但它仍然是一个有效的图像(它甚至可以用系统的图像查看器打开):
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!