GHOST系统之家 - Windows系统光盘下载网站!
当前位置:GHOST系统之家>电脑问题 > 利用Ghidra逆向分析Go二进制程序(上篇)

利用Ghidra逆向分析Go二进制程序(上篇)

来源:Ghost系统之家浏览:时间:2023-04-16 18:05:47

Go(又称Golang)是Google公司于2007年设计的一种开源编程语言,并于2012年向公众开放。多年来,它在开发者中广受欢迎,但它并不总是被用于“善意”的用途。正如经常发生的那样,它也吸引了恶意软件开发者的注意。

对于恶意软件开发者来说,使用Go语言是一个诱人的选择,因为它支持交叉编译,也就是说,可以把Go语言编写的代码编译成在不同操作系统上运行的二进制文件。这样的话,就能够让攻击者的生活变得更加轻松,因为他们不必为每个目标环境开发和维护不同的代码库了,岂不快哉。

对Go二进制程序进行逆向分析的必要性

由于Go编程语言的某些特性的原因,逆向工程师在处理Go二进制文件时通常会遇到许多阻力。尽管目前的逆向分析工具(例如反汇编器)可以很好地分析非常流行的语言(例如C、C++、.NET)编写的二进制文件,但是Go语言却带来了新的挑战,使得分析工作变得更加繁琐。

Go二进制文件通常是静态链接的,这意味着所有必要的库都包含在编译后的二进制文件中。这会导致二进制文件的块头变大,从而使得恶意软件的分发对攻击者来说更加困难。另一方面,一些安全产品在处理大文件时也存在问题。这意味着大型二进制文件可以帮助恶意软件避开检测。静态链接的二进制文件对攻击者的另一个好处是,恶意软件可以直接在目标系统上运行,而不会遇到依赖问题。

当我们看到用Go编写的恶意软件持续增长,并预计会出现更多的恶意软件家族时,我们决定更深入地研究Go编程语言,并增强我们的工具集,以便更有效地调查Go恶意软件。

在本文中,我将讨论逆向工程师在分析Go二进制代码的过程中所面临的两个难题,以及相应的解决方案。

Ghidra是美国国家安全局开发的一个开源逆向分析工具,我们经常使用它来进行恶意软件的静态分析。我们可以为Ghidra创建自定义脚本和插件,以按需实现特定的功能。在这里,我们将利用Ghidra的这个特性,通过创建自定义的脚本来帮助我们分析Go二进制程序。

本文讨论的主题是在Hacktivity2020在线会议上公布的,相关的幻灯片和其他材料可以在我们的Github存储库中下载。

剥离型二进制代码中丢失的函数名

实际上,我们面对的第一个问题并不是Go二进制文件所特有的,而是所有剥离型二进制代码(strippedbinaries,译者注:就是去掉调试信息后的二进制代码)所共同面对的一个问题。实际上,编译后的可执行文件是可以包含调试符号的,这能让调试和分析工作变得更加容易。当分析人员逆向分析带有调试信息的二进制代码时,他们不仅可以看到内存地址,还可以看到函数和变量的名称。然而,恶意软件作者通常在编译代码时剥离这些调试信息,从而创建所谓的剥离型二进制代码。他们这样做的目的有两个,一是为了减小文件的大小,二是增加逆向分析的难度。在使用剥离型二进制文件时,分析人员无法依赖函数名来帮助他们在代码中找到自己感兴趣的函数。在处理使用静态链接的Go二进制文件(其中包含所有必需的库)时,逆向分析的过程会显著减慢。

为了说明这个问题,我们将分别通过C语言和Go语言编写一个简单的“HelloHacktivity”示例代码,并将它们编译成剥离型的二进制代码。在这里,请大家注意两个可执行文件在大小方面的差异。

利用Ghidra逆向分析Go二进制程序(上篇)

Ghidra的Functions窗口列出了二进制文件中已经定义的所有函数。在非剥离型的编译版本中,函数名称都会显示出来,这对逆向工程师来说具有很大的帮助。

利用Ghidra逆向分析Go二进制程序(上篇)

图1 hello_c的函数列表

利用Ghidra逆向分析Go二进制程序(上篇)

图2 hello_go的函数列表

对于剥离型的二进制文件来说,其函数列表如下所示:

利用Ghidra逆向分析Go二进制程序(上篇)

图3 hello_c_strip的函数列表

利用Ghidra逆向分析Go二进制程序(上篇)

图4 hello_go_strip的函数列表

这些例子清楚地表明,即使像“helloworld”这样简单的G0程序的二进制代码,它们的体积也是非常庞大的:竟然含有一千多个函数。而在剥离型的二进制版本中,逆向工程师则无法依靠函数名来进行辅助分析。

注:由于剥离了调试信息,不仅函数名消失了,Ghidra也只能识别出1790个函数中的1139个。

我们感兴趣的是,是否有办法恢复剥离型二进制文件中的函数名。首先,我们运行了一个简单的字符串搜索来检查二进制文件中是否还有函数名。在C语言的例子中,我们找到了函数“main”,而在Go语言的例子中找到的则是“main.main”。

利用Ghidra逆向分析Go二进制程序(上篇)

图5 在hello_c中,可以找到字符串“main”

利用Ghidra逆向分析Go二进制程序(上篇)

图6 在hello_c_strip中,无法找到字符串“main”

利用Ghidra逆向分析Go二进制程序(上篇)

图7 在hello_go中,可以找到字符串“main.main”

利用Ghidra逆向分析Go二进制程序(上篇)

图8 在hello_go_strip中,可以找到字符串“main.main”

我们可以看到,虽然strings工具无法在C语言的剥离型二进制文件中找到函数名,但是,我们却可以在Go语言的剥离型二进制文件中找到字符串“main.main”。这个发现给我们带来了一丝希望,即在剥离型的Go二进制文件中可以恢复函数名。

实际上,将二进制文件加载到Ghidra中,然后搜索“main.main”字符串,就可以看到它的确切位置。如下图所示,函数名字符串位于.gopclntab段。

利用Ghidra逆向分析Go二进制程序(上篇)

图9 Ghidra显示的hello_go_strip的main.main字符串

众所周知,从Go1.2开始,就开始提供pclntab结构体了,并且提供了详尽的说明文档。该结构体以一个魔力值开头,后面是架构信息,再往后,是函数符号表,用于保存二进制代码中的函数信息,每个函数的入口点地址后面是函数元数据表。

利用Ghidra逆向分析Go二进制程序(上篇)

在函数元数据表中,除其他重要信息外,还存储了函数名称的偏移量。

利用Ghidra逆向分析Go二进制程序(上篇)

也就是说,我们可以通过这些信息来恢复函数名。为此,我们的团队为Ghidra创建了一个脚本(go_func.py),通过执行以下步骤来恢复剥离型GoELF文件中的函数名:

  • 找到pclntab结构体
  • 提取函数地址
  • 查找函数名偏移量

执行我们的脚本后,不仅可以恢复函数名,而且还可以定义以前未被识别的函数。

利用Ghidra逆向分析Go二进制程序(上篇)

图10 执行go_func.py脚本后的hello_go_strip的函数列表

接下来,我们将以真实世界中的样本(eCh0raix勒索软件)为例,来展示该脚本的威力:

利用Ghidra逆向分析Go二进制程序(上篇)

图11 eCh0raix的函数列表

利用Ghidra逆向分析Go二进制程序(上篇)

图12 执行go_func.py脚本后eCh0raix的函数列表

这个例子展示了函数名恢复脚本在逆向工程中所带来的巨大帮助:安全分析师只需瞄一眼函数名,就可以判断出当前处理的是一个勒索软件。

注意:在WindowsGo二进制文件中,并没有专门为pclntab结构体提供相应的段,因此,研究人员需要显式地搜索该结构体的相关字段(如魔力值、可能的字段值)。对于macOS系统来说,_gopclntab段是可用的,类似于Linux二进制文件中的.gopclntab段。

挑战:未定义的函数名字符串

如果一个函数名字符串没有被Ghidra定义,那么函数名恢复脚本将无法重命名该特定函数,因为它无法在给定位置找到函数名字符串。为了解决这个问题,我们的脚本总是检查函数名地址是否有定义的数据类型,如果没有,则尝试在重命名函数之前在给定的地址定义一个字符串数据类型。

在下面的例子中,eCh0raix勒索软件样本中并没有定义函数名字符串“log.New”,所以在没有事先创建字符串的情况下,是无法重命名相应的函数的。

利用Ghidra逆向分析Go二进制程序(上篇)

图13 eCh0raix中log.New的函数名未定义

利用Ghidra逆向分析Go二进制程序(上篇)

图14 eCh0raix中log.New函数无法重命名

在我们的脚本中,以下几行代码专门用于解决这个问题:

利用Ghidra逆向分析Go二进制程序(上篇)

图15 go_func.py

Go二进制文件中无法识别的字符串

我们的脚本要解决的第二个问题与Go二进制文件内的字符串有关。让我们回到“Hello Hacktivity”的例子,看看Ghidra内定义的字符串。

在C语言编译而成的二进制代码中定义了70个字符串,“Hello,Hacktivity!”就在其中。同时,Go语言版本的二进制代码中则包含了6,540个字符串,但搜索“hacktivity”字符串却没有任何结果。如此多的字符串已经让逆向工程师很难找靠肉眼到相关的字符串,但是,我们期望找到的字符串甚至没有被Ghidra识别出来。

利用Ghidra逆向分析Go二进制程序(上篇)

图16 hello_c中定义的字符串中含有“Hello, Hacktivity!”

利用Ghidra逆向分析Go二进制程序(上篇)

图17 hello_go中定义的字符串中未含有“hacktivity”

要理解这是怎么回事,您需要知道Go语言处理字符串的方式。在类似C这样的编程语言中,字符串是以空字符结尾的字符序列;而在Go语言中,字符串则被视为具有固定长度的字节序列。也就是说,对于Go语言来说,字符串是一种特殊的数据结构,由指向字符串位置的指针和整数(即字符串的长度)构成。

利用Ghidra逆向分析Go二进制程序(上篇)

在Go二进制文件中,这些字符串将以大字符串blob的形式存储,而blob则是由多个字符串串联而组成的,并且字符串之间没有空字符。因此,在搜索“Hacktivity”时,对于C语言版本的二进制代码来说,能够得到预期的结果;对于Go语言版本的二进制代码来说,则会返回一个包含“hacktivity”的巨型字符串blob。

利用Ghidra逆向分析Go二进制程序(上篇)

图18 在hello_c中搜索“Hacktivity”字符串

利用Ghidra逆向分析Go二进制程序(上篇)

图19 在hello_go中串搜索字符“hacktivity”

由于Go语言对字符串的定义不同于其他语言,并且在汇编代码中引用它们的结果也与通常的类似C语言的解决方案不同,因此Ghidra在处理Go二进制文件中的字符串方面,会面临较大的困难。

字符串结构的分配方式有很多种,它既可以是静态创建的,也可以是运行时动态创建的;同时,在不同的架构中,具体的分配方式也是不同的,甚至在同一架构中可能存在多种解决方案。为了解决这个问题,我们团队创建了两个脚本来帮助识别字符串。

小结

在本文中,我讨论了逆向工程师在分析Go二进制代码的过程中所面临的两个难题及其解决方案,由于篇幅较长,我们将分为两篇进行介绍。更多精彩内容,我们将在下篇中进行介绍。

推荐系统

  • 电脑公司Ghost Win8.1 x32 精选纯净版2022年7月(免激活) ISO镜像高速下载

    电脑公司Ghost Win8.1 x32 精选纯净版2022年7月(免激活) ISO镜像高速下载

    语言:中文版系统大小:2.98GB系统类型:Win8

    电脑公司Ghost Win8.1x32位纯净版V2022年7月版本集成了自2022流行的各种硬件驱动,首次进入系统即全部硬件已安装完毕。电脑公司Ghost Win8.1x32位纯净版具有更安全、更稳定、更人性化等特点。集成最常用的装机软件,精心挑选的系统维护工具,加上绿茶独有

  • 微软Win11原版22H2下载_Win11GHOST 免 激活密钥 22H2正式版64位免费下载

    微软Win11原版22H2下载_Win11GHOST 免 激活密钥 22H2正式版64位免费下载

    语言:中文版系统大小:5.13GB系统类型:Win11

    微软Win11原版22H2下载_Win11GHOST 免 激活密钥 22H2正式版64位免费下载系统在家用办公上跑分表现都是非常优秀,完美的兼容各种硬件和软件,运行环境安全可靠稳定。Win11 64位 Office办公版(免费)优化  1、保留 Edge浏览器。  2、隐藏“操作中心”托盘图标。  3、保留常用组件(微软商店,计算器,图片查看器等)。  5、关闭天气资讯。 

  • Win11 21H2 官方正式版下载_Win11 21H2最新系统免激活下载

    Win11 21H2 官方正式版下载_Win11 21H2最新系统免激活下载

    语言:中文版系统大小:4.75GB系统类型:Win11

    Ghost Win11 21H2是微软在系统方面技术积累雄厚深耕多年,Ghost Win11 21H2系统在家用办公上跑分表现都是非常优秀,完美的兼容各种硬件和软件,运行环境安全可靠稳定。Ghost Win11 21H2是微软最新发布的KB5019961补丁升级而来的最新版的21H2系统,以Windows 11 21H2 22000 1219 专业版为基础进行优化,保持原汁原味,系统流畅稳定,保留常用组件

  • windows11中文版镜像 微软win11正式版简体中文GHOST ISO镜像64位系统下载

    windows11中文版镜像 微软win11正式版简体中文GHOST ISO镜像64位系统下载

    语言:中文版系统大小:5.31GB系统类型:Win11

    windows11中文版镜像 微软win11正式版简体中文GHOST ISO镜像64位系统下载,微软win11发布快大半年了,其中做了很多次补丁和修复一些BUG,比之前的版本有一些功能上的调整,目前已经升级到最新版本的镜像系统,并且优化了自动激活,永久使用。windows11中文版镜像国内镜像下载地址微软windows11正式版镜像 介绍:1、对函数算法进行了一定程度的简化和优化

  • 微软windows11正式版GHOST ISO镜像 win11下载 国内最新版渠道下载

    微软windows11正式版GHOST ISO镜像 win11下载 国内最新版渠道下载

    语言:中文版系统大小:5.31GB系统类型:Win11

    微软windows11正式版GHOST ISO镜像 win11下载 国内最新版渠道下载,微软2022年正式推出了win11系统,很多人迫不及待的要体验,本站提供了最新版的微软Windows11正式版系统下载,微软windows11正式版镜像 是一款功能超级强大的装机系统,是微软方面全新推出的装机系统,这款系统可以通过pe直接的完成安装,对此系统感兴趣,想要使用的用户们就快来下载

  • 微软windows11系统下载 微软原版 Ghost win11 X64 正式版ISO镜像文件

    微软windows11系统下载 微软原版 Ghost win11 X64 正式版ISO镜像文件

    语言:中文版系统大小:0MB系统类型:Win11

    微软Ghost win11 正式版镜像文件是一款由微软方面推出的优秀全新装机系统,这款系统的新功能非常多,用户们能够在这里体验到最富有人性化的设计等,且全新的柔软界面,看起来非常的舒服~微软Ghost win11 正式版镜像文件介绍:1、与各种硬件设备兼容。 更好地完成用户安装并有效地使用。2、稳定使用蓝屏,系统不再兼容,更能享受无缝的系统服务。3、为

  • 雨林木风Windows11专业版 Ghost Win11官方正式版 (22H2) 系统下载

    雨林木风Windows11专业版 Ghost Win11官方正式版 (22H2) 系统下载

    语言:中文版系统大小:4.75GB系统类型:

    雨林木风Windows11专业版 Ghost Win11官方正式版 (22H2) 系统下载在系统方面技术积累雄厚深耕多年,打造了国内重装系统行业的雨林木风品牌,其系统口碑得到许多人认可,积累了广大的用户群体,雨林木风是一款稳定流畅的系统,一直以来都以用户为中心,是由雨林木风团队推出的Windows11国内镜像版,基于国内用户的习惯,做了系统性能的优化,采用了新的系统

  • 雨林木风win7旗舰版系统下载 win7 32位旗舰版 GHOST 免激活镜像ISO

    雨林木风win7旗舰版系统下载 win7 32位旗舰版 GHOST 免激活镜像ISO

    语言:中文版系统大小:5.91GB系统类型:Win7

    雨林木风win7旗舰版系统下载 win7 32位旗舰版 GHOST 免激活镜像ISO在系统方面技术积累雄厚深耕多年,加固了系统安全策略,雨林木风win7旗舰版系统在家用办公上跑分表现都是非常优秀,完美的兼容各种硬件和软件,运行环境安全可靠稳定。win7 32位旗舰装机版 v2019 05能够帮助用户们进行系统的一键安装、快速装机等,系统中的内容全面,能够为广大用户