原文地址:https://blog.sucuri.net/2021/02/whitespace-steganography-conceals-web-shell-in-php-malware.html
去年11月,我们写过一篇文章,介绍了攻击者是如何使用JavaScript注入技术从合法的CSS文件中加载恶意代码的。
乍一看,这些注入的文件中除了一些正常的CSS规则外,似乎没有其他方面的内容。实际上,如果对.CSS文件进行更深入的分析的话就会发现,其中有56,964行貌似空行,但其实却包含了不可见的制表符(0x09)、空格符(0x20)和换行符(0x0A)等内容——这些字符首先被转换为二进制字符表示形式,之后被进一步转换为可执行JavaScript代码的文本形式。
没过多久,我们就发现PHP恶意软件中也采用了同样的方法。以下是我们的恶意软件分析师Liam Smith最近在处理一个包含多个后门和黑客上传的webshell的网站时发现的样本。
实际上,Liam在该网站上发现了许多可疑文件,其中就包括system/license.php
。
正如该文件名所暗示的那样,该文件中保存的是许可证协议的文本,更具体地说,是GNU通用公共许可证第3版的文本。
通过观察,我们发现这些许可证文本被放在一个多行的PHP注释中。然而,在第134行,我们看到两个注释之间有一个明显的空隙,并且其中含有可执行的PHP代码。
隐藏在license.php
文件中的PHP代码
实际上,在注释块中隐藏恶意代码是黑客惯用的一种混淆技术。
很明显,这些被隐藏的代码肯定是恶意的,但乍看起来,根本搞不清楚该恶意软件的代码都放到了这里,还是这里只是其中的部分代码,而其他部分则位于文件中的其他地方。但是,有一点是不难看出的,即它试图用file_get_contents(basename($_SERVER[‘PHP_SELF’])))
来读取自身内容并进行某些处理。然而,迅速检查该文件后,并没有发现任何其他可以转换为有效的PHP代码的空隙。
为了了解恶意代码到底做了什么,我们对所有的语句都进行了逐条分析。
其中,第一个子句的作用是,以分号为分隔符,将文件的内容用分割成若干部分,并将最后一部分分配给$cache
变量。通俗的说,这段代码的作用是处理文件中位于最后一个分号之后的内容。
事实上,文件中最后一个分号也是许可协议的最后一个字符:“But first, please read <http://www.gnu.org/philosophy/why-not-lgpl.html>;
”。 在原始的许可协议中,最后一个字符是句号,说明攻击者对这个条款的文本做了手脚。
在这最后一个分号之后,并没有什么清晰可见的内容。为了理解文件的末尾部分是如何处理的,我们需要分析被恶意修改的条款后面的内容。
for($i=0;$i<strlen($cache);$i++){ $out.=chr(bindec(str_replace(array(chr(9),chr(32)),array('1','0'),substr($cache,$i,8)))); $i+= 7; }
在这里,我们可以看到,代码每次以8个字符为单位读取文件的其余部分(substr($cache,$i,8)
),并将制表符(9)和空格符(32)转换为1和0组成的表示形式。然后,它会将得到的二进制字符串转换为十进制数(bindec),再使用chr()
函数将十进制数转换为字符。这样,每次一个八位字节,就能逐渐将文件中其余的空格符逐个转换为可见的字符串。
此时,这个字符串既看不出具体含义,也无法执行。为了完全解码并执行payload,需要使用以下函数组合:“base64_decode(str_rot13(gzdecode(…
”。
作为执行payload的备份方式,该恶意软件还试图将解码后的内容保存到一个名为“ ”(该文件名只是一个空格,使其在文件列表中不容易被察觉)的文件中,并使用include $cachepart;
动态包含该文件。之后,这个文件会被删除,以逃避检测。
根据相关报告称,由于某些原因,在受感染的站点上仍然可以找到其中一些以空白符命名的文件。
现在我们已经知道,这个恶意软件正在寻找最后一个分号后的所有制表符和空格符,下面,让我们找到并解码这个隐藏的payload。
结果发现,在license.php
文件的最后一行之后,竟然还有近300Kb的隐形制表符和空格符,而可见的许可证文本却只有30Kb。
如果您查看最后一行的十六进制代码,或者在文本编辑器中选择最后一个“;”之后的内容,就可以看到这些隐形的字符。
license.php
最后一行的十六进制形式
通过文本编辑器查看隐形的内容
如您所见,上图中的内容类似于摩斯码,与去年11月描述的JavaScript恶意软件相似,它也采取了混淆处理,但这个样本并没有使用换行符(0x0A)。这意味着隐形的内容不会在文件底部产生大量可疑的空行。
当我们使用恶意软件的算法对空行进行解码时,我们会得到一个大小为74Kb的web shell文件,该文件用于存放黑客对服务器上的文件和数据库进行各种处理所需的工具,例如收集敏感信息、感染文件,并进行蛮力攻击。此外,它还可以作为服务器控制台或anonymizer来隐藏攻击者的真实IP地址。
对空白符解码后得到的Web shell
正如我们在调查中经常发现的那样,恶意软件中发现的许多技巧和算法并不是黑客发明的。许多代码都是早就存在于互联网上面了,例如,许多代码都是直接从StackOverflow等网站复制过来的。
通过搜索引擎查找该空白符解码器的代码片段,我们在流行的俄语IT社区网站Habr.ru上发现了的一篇发表于2019年的相关文章。该文章的作者分享了他们的PHPwhitespace混淆算法的概念验证代码,其灵感来自于2011年发表的一篇关于混淆处理方面的文章,该文章讨论了仅使用制表符和空格符进行编码的思路。
实际上,该恶意软件的作者只是简单地从那篇文章中提取了空白符解码器的相关代码,并且未作任何修改,然后,又添加了一些代码,来实现额外的混淆处理,并执行解码后的payload。
在被入侵的服务器上只找到一种类型的后门,是一种非常罕见的事情。通常情况下,被入侵的服务器上面会存在多种类型的后门程序,分别用于完成不同的任务。
例如,由于license.php
文件不容易引起人们的怀疑,所以,即使其他恶意软件被发现和删除了,仍然可以通过这种文件来访问被入侵的网站。
攻击者最初植入服务器以感染网站的文件或代码则是另一种类型的后门。这些后门通常在受感染的环境中以小文件的形式出现,攻击者可以通过它们来执行任意代码或创建特定文件。它们甚至根本无需进行隐身处理或复杂的混淆处理——黑客通常会在使用后立即删除它们以掩盖自己的踪迹。
在这个特殊的案例中,我们发现了恶意Uploader,它可以创建虚假的license.php
文件,并将恶意软件注入.htaccess
和index.php
文件中。
https://m.habr.com/en/post/458710/
创建虚假的license.php
文件的恶意Uploader
虽然使恶意内容肉眼无法分辨似乎是一个不错的主意,但该恶意软件中使用的基于空白符的混淆技术,在隐身方面做的并不是非常理想。因为它包含了一个易于检测的PHP部分——如果将其删除,将导致不可见的payload无法正常使用。这种方法的另一个缺点是会令文件尺寸变得过于臃肿。例如,这里的恶意软件令文件大小增加了10倍,这很容易引起人们的怀疑。
黑客通常会借助于混淆技术来隐藏代码和恶意行为。就目前已知的混淆类型来说,已经多达成百上千种之多,但是,攻击者仍在努力寻找绕过安全检测的新方法。
对于网站管理员来说,好消息是您不必对恶意文件进行解码或了解如何查找和删除这种类型的恶意软件。一个简单的完整性控制解决方案就足以检测出可疑的文件修改行为。
每当您发现文件遭到了修改,但是不确定是否为恶意修改时,最安全的方法是将文件替换为已知的干净版本——毕竟您早已经做好了备份,对吧?