要么全力以赴,要么干脆放弃:分析 Golang
ztj100 2025-07-23 19:25 9 浏览 0 评论
GO BIG OR GO HOME (AND OTHER TERRIBLE GO PUNS) TIPS FOR ANALYZING GOLANG MALWARE
免责声明:本博客文章仅用于教育和研究目的。提供的所有技术和代码示例旨在帮助防御者理解攻击手法并提高安全态势。请勿使用此信息访问或干扰您不拥有或没有明确测试权限的系统。未经授权的使用可能违反法律和道德准则。作者对因应用所讨论概念而导致的任何误用或损害不承担任何责任。
几天前,Dr. Josh Stroschein 邀请我在他的 YouTube 频道 上讨论 Golang 恶意软件。为了趁热打铁,我决定将直播内容整理成这篇博客。以下是直播讨论的精华总结。如果你不想阅读文章,可以直接观看直播 回放 。那么,让我们开始吧。
Go(或 Golang)在过去几年中不仅受到开发者的青睐,也越来越受到寻求灵活性和可移植性的恶意软件作者的关注。作为逆向工程师和恶意软件分析师,这意味着我们需要更熟悉 Go 二进制文件,了解它们的结构,并知道它们与用 C、C++ 或 Delphi 编写的传统恶意软件有何不同。
什么是 Go,为什么它重要?
Go 是 Google 开发的一种静态类型、编译型编程语言。它设计简单、编译快速且高效。Go 的一些优点包括:
从开发者的角度来看,它高效且实用。从恶意软件分析师的角度来看,它带来了一些有趣的挑战。
为什么使用 Go 编写恶意软件?
Go 提供了几个对恶意软件作者有吸引力的优势:
分析 Go 恶意软件的常见陷阱
1. 大文件体积
即使是一个简单的 Go 程序,编译后的二进制文件也可能达到几十 MB。这是由于 Go 运行时和标准库的静态链接。对于分析师来说,这意味着需要筛选更多代码,因为通常无法立即确定恶意代码的起始和结束位置。
2. 大量合法代码
Go 的标准库非常广泛,恶意软件通常使用常见的包,如 net
、 os
、 crypto
和 io
。二进制文件中的大部分代码可能是良性的。挑战在于在大量合法功能中识别出小部分自定义或恶意逻辑。这就像在针堆里找针。
3. 混淆(Garble 等)
Go 恶意软件越来越多地使用混淆工具,如 Garble ,它会剥离或随机化符号名称、重新排序包,并破坏常见的静态分析工作流程。这些技术并不一定使恶意软件更复杂,但确实增加了逆向工程的难度。
其他常见的混淆技术可能包括:
让我们分析一个非常基础的 Go 二进制文件。最好的方法是我们自己编写代码。
分析一个基础的 Go 程序
Go 代码相当直接且易于编写。以下是最基础的 Go 应用程序,打印我们最喜欢的 "Hello World"(在这里是 "Hello Earth")字符串:
使用 go build
命令编译后,二进制文件相当大(2MB+)。由于 Go 将大量库代码打包到每个编译后的可执行文件中,即使这个简单的 Hello World 二进制文件也相当大。
让我们在 IDA 中打开它,这是我最喜欢的 Golang 反汇编工具。较新版本的 IDA(我认为是 8+ 版本)能够很好地识别 Go 标准库代码。IDA 将这些库分组在 "文件夹" 中,如下面的截图所示:
每个文件夹代表一个库。例如," internal
"、" runtime
" 和 " math
" 都是导入到这个 Go 程序中的库。IDA 能够识别这些库和函数并适当地命名它们。如果你的反汇编工具不是为 Golang 设计的,你会看到这些函数的一堆通用名称,这使得分析 Go 二进制文件更加困难。一个工具( GoReSim )可以帮助识别这些函数,然后可以将该工具的输出重新导入到一些反汇编工具中,如 Ghidra。
在未混淆的 Golang 二进制文件中,程序的主要功能通常位于 main.main
或 main_main
函数中,IDA 已经为我们识别了这一点:
提示:每当我分析 Go 二进制文件时,我总是首先寻找 main_main
或其他包含 " main_*
" 名称的函数。
在 main_main
中,我们可以看到我们的 Hello World
代码。你可能会在下面的代码中发现 "Hello Earth!" 字符串:
这个 "Hello Earth!" 字符串还包含一堆其他垃圾。这些也是二进制文件中的字符串。分析 Golang 代码时的一个挑战是,字符串不像 C 程序那样以 null 结尾。每个字符串实际上是一个结构,包含字符串本身和一个表示字符串长度的整数。我提供了一些糟糕的伪代码来可视化这一点:
struct string (
value = "Hello Earth!"
length = 12
)
在这种情况下,IDA 不知道 "Hello Earth!" 是与 "152587…" 等字符串分开的。这是分析 Golang 时需要考虑的一点。
好了,Hello World 应用程序很酷,但让我们更进一步。许多用 Go 编写的恶意软件二进制文件会被混淆。 Garble 就是这样一个混淆器。Garble... 嗯... 混淆了 Go 二进制文件的元数据。它通过在编译时剥离符号、函数名称、模块和构建信息以及其他元数据来实现这一点。
如果我们在 IDA 中打开同一个 Hello World 二进制文件,但在编译时进行了 "Garbled" 处理,它看起来大不相同:
我们所有漂亮的 Golang 函数名称都被替换为丑陋的通用 IDA 函数名称(" sub_xxxxxx
")。那么我们现在如何找到我们的主函数代码呢?我们找不到——Golang 赢了。是时候收拾东西回家了。
不,开个玩笑。我们只需要更努力一点。我发现 Golang 需要几个关键库才能正常运行,其中之一是 " runtime
" 库,它包含大量 Go 的运行时代码。通常,runtime 库名称不会被混淆,就像我这个用 Garble 编译的二进制文件中的情况一样( 注意:我认为 Garble 也可以从 "runtime" 中剥离模块名称,但我没有测试过。无论如何,"runtime" 模块名称通常不会被混淆 )。这意味着我们可以在代码中找到对 runtime 函数的交叉引用,并追踪回程序的主函数!让我们试试看。
如果我们在 IDA 的函数列表中搜索 "runtime",我们会得到以下结果:
一个常见的 runtime 函数是 runtime_unlockOSThread
。我们可以双击这个函数并选择 CTRL+X 来查看它的交叉引用。查看所有交叉引用的函数会引导你到一个看起来像这样的代码块:
当你发现包含大量 "runtime" 函数的功能时,你可能接近程序的主代码位置。在这种情况下,我们的主代码就在不远处的 sub_49A9E0
。你可能会想:"Kyle,你怎么这么聪明,这么快就找到了?"。好吧,除了智力之外,这主要是因为在代码中进行了大量搜索。没有什么疯狂的技巧。
这是我们在 sub_49A9E0 处的主代码:
提示:Garble 和其他混淆器不仅可以混淆函数名称,还可以混淆字符串。我使用了默认的 Garble 设置来处理这个二进制文件。然而,分析方法是一样的。
额外资源
一些关于 Golang 的额外资源,我觉得非常有帮助:
关键要点
Go 语言编写的恶意软件越来越普遍,并且可能会持续存在。虽然它带来了一些独特的挑战,但许多逆向工程的基本原则仍然适用。你只需要调整你的方法和工具。
逆向分析 Go 恶意软件的 5 个技巧
1. 从 main.main
(main_main
) 开始 - 这几乎总是 Go 二进制文件的入口点,可以为你提供进入其余逻辑的切入点2. 使用正确的工具 - IDA、带有 GoReSym
的 Ghidra(其他反汇编器可能也有效,但我没有测试过),以及名为 UnGarbler 的反混淆工具3. 忽略噪音 - 跳过大部分标准库代码,除非它直接参与恶意行为 4. 寻找关键 API - 即使经过混淆,像 " net.Dial
"、"os/exec
" 或 "http.Get
" 这样的模式也能帮助缩小可疑区域的范围5. 结合静态和动态分析 - 特别是对于混淆的二进制文件,动态跟踪或调试可能是理解实际行为的最快方法。Ivan Kwiatkowski 在这个 视频 中提供了一些关于调试 Go 语言的实用技巧
相关推荐
- 10条军规:电商API从数据泄露到高可用的全链路防护
-
电商API接口避坑指南:数据安全、版本兼容与成本控制的10个教训在电商行业数字化转型中,API接口已成为连接平台、商家、用户与第三方服务的核心枢纽。然而,从数据泄露到版本冲突,从成本超支到系统崩溃,A...
- Python 文件处理在实际项目中的困难与应对策略
-
在Python项目开发,文件处理是一项基础且关键的任务。然而,在实际项目中,Python文件处理往往会面临各种各样的困难和挑战,从文件格式兼容性、编码问题,到性能瓶颈、并发访问冲突等。本文将深入...
- The Future of Manufacturing with Custom CNC Parts
-
ThefutureofmanufacturingisincreasinglybeingshapedbytheintegrationofcustomCNC(ComputerNumericalContro...
- Innovative Solutions in Custom CNC Machining
-
Inrecentyears,thelandscapeofcustomCNCmachininghasevolvedrapidly,drivenbyincreasingdemandsforprecisio...
- C#.NET serilog 详解(c# repository)
-
简介Serilog是...
- Custom CNC Machining for Small Batch Production
-
Inmodernmanufacturing,producingsmallbatchesofcustomizedpartshasbecomeanincreasinglycommondemandacros...
- Custom CNC Machining for Customized Solutions
-
Thedemandforcustomizedsolutionsinmanufacturinghasgrownsignificantly,drivenbydiverseindustryneedsandt...
- Revolutionizing Manufacturing with Custom CNC Parts
-
Understandinghowmanufacturingisevolving,especiallythroughtheuseofcustomCNCparts,canseemcomplex.Thisa...
- Breaking Boundaries with Custom CNC Parts
-
BreakingboundarieswithcustomCNCpartsinvolvesexploringhowadvancedmanufacturingtechniquesaretransformi...
- Custom CNC Parts for Aerospace Industry
-
Intherealmofaerospacemanufacturing,precisionandreliabilityareparamount.Thecomponentsthatmakeupaircra...
- Cnc machining for custom parts and components
-
UnderstandingCNCmachiningforcustompartsandcomponentsinvolvesexploringitsprocesses,advantages,andcomm...
- 洞察宇宙(十八):深入理解C语言内存管理
-
分享乐趣,传播快乐,增长见识,留下美好。亲爱的您,这里是LearingYard学苑!今天小编为大家带来“深入理解C语言内存管理”...
- The Art of Crafting Custom CNC Parts
-
UnderstandingtheprocessofcreatingcustomCNCpartscanoftenbeconfusingforbeginnersandevensomeexperienced...
- Tailored Custom CNC Solutions for Automotive
-
Intheautomotiveindustry,precisionandefficiencyarecrucialforproducinghigh-qualityvehiclecomponents.Ta...
- 关于WEB服务器(.NET)一些经验累积(一)
-
以前做过技术支持,把一些遇到的问题累积保存起来,现在发出了。1.问题:未能加载文件或程序集“System.EnterpriseServices.Wrapper.dll”或它的某一个依赖项。拒绝访问。解...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- 10条军规:电商API从数据泄露到高可用的全链路防护
- Python 文件处理在实际项目中的困难与应对策略
- The Future of Manufacturing with Custom CNC Parts
- Innovative Solutions in Custom CNC Machining
- C#.NET serilog 详解(c# repository)
- Custom CNC Machining for Small Batch Production
- Custom CNC Machining for Customized Solutions
- Revolutionizing Manufacturing with Custom CNC Parts
- Breaking Boundaries with Custom CNC Parts
- Custom CNC Parts for Aerospace Industry
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)
- vmware17pro最新密钥 (34)
- mysql单表最大数据量 (35)