首页
社区
课程
招聘
[原创]GO恶意样本实例分析
2020-12-17 11:57 5621

[原创]GO恶意样本实例分析

2020-12-17 11:57
5621

GO恶意样本实例分析

  最近在工作中遇到不少的go语言编写的恶意样本,也整理了在分析go恶意样本的一些基础知识,各位同学可以先看看这篇文章《GO恶意样本分析》,对go语言的分析基础有一定了解。
  在平常的工作中遇到的情况来看,go语言的恶意样本可以分为如下的三个等级以及对应的等级的说明。

  • 非常简单:未去除符号以及未混淆的的恶意软件。
  • 一般简单:去除符号的恶意软件。
  • 困难:混淆的恶意软件。
    我找了几个对应的样本,大家可以一起学习学习。

未去除符号以及未混淆的的恶意软件

  WellMesss是疑似具有俄罗斯背景的APT组织,在今年披露的该组织的一个样本(Botlib)是使用go语言编写的,具有Linux和Windows双平台的版本,在这里分析了Linux版本的Botlib。
md5:4d38ac3319b167f6c8acb16b70297111
  通过函数名,我们可以很清楚的看到,该样本是未被去除符号的。通过函数名和源代码路径可以对该样本的功能有一个基本的认识。
Alt text

 

Alt text

 

  该样本在其中之后,与C2服务器交换数据,将ip地址,计算机名等信息计算sha256后拼接成用户信息,将其使用rsa算法加密之后,发送到C2,并通过http的cookie携带使用rc6加密的指令信息。通信成功后,会获取下一阶段的执行指令。
Alt text
Alt text
  如下图为发送的数据
Alt text

 

cookie携带的数据为如下数据加密后的

1
<;head;>3139322e3136382e35362e3132387c7c72656d6e75787c72656d6e7578e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/p<;head;><;title;>a:1_0<;title;><;service;>p<;service;>

有大佬分享了wellmess botlib cookie数据的解密脚本wellmess_cookie_decode.py
Alt text

 

在获取C2下发的数据后,解密后通过service字段的值执行不同的任务
Alt text

service 值 描述
p 初始化AES密钥
C 检验数据合法性
hi 修改运行周期
m 设置MaxPostSize
u 修改userAgent
fu 下载文件
fd 上传文件
其他 执行shell指令,当指令与上述指令没有匹配

去除符号的恶意软件

  Zebrocy downloader是APT28组织的一个用于初始攻击的攻击组件,常常和诱饵文档被打包都一起,诱惑目标用户点击执行,在2018年左右,APT28使用go语言写了第一个版本的zebrocy downloader版本,这也是我分析的第一个go语言的恶意程序。样本md5:6bc5f53d4082f12dd83aca45bae81e64
  go zebrocy 此版本使用时间范围在2018年左右,针对欧洲的外交机构进行攻击。功能方面与zebrocy的其他的版本无大的差别。在查阅了相关的信息确认后,这应该APT28首次将go语言纳入武器库开发语言,也是首次go zebrocy用于实际的攻击。
  go zebrocy将符号信息已经去除掉了,借用ida的插件IDAGolangHelper对go zebrocy符号进行还原。
  样本执行之后,首先判断文件名中是否包含“)”,以确定样本没有被使用hash进行命名,以躲避一些自动化分析。
Alt text
  接着获取目标计算机系统信息。主要获取的信息有system info,tasklist,磁盘信息以及屏幕截图
1.通过cmd执行systeminfo,获得系统基础信息
Alt text
2.通过cmd执行tasklist,获得系统进程信息
Alt text

 

3.通过cmd执行wmic命令,获取系统磁盘信息。
Alt text
4.通过调用第三方截图包screenshot,获取截图数据
Alt text
最后利用post对相关数据进行上传,并根据C2返回的数据利用cmd执行系统命令。
Alt text
Alt text

运行时符号

  IDAGolangHelper是通过什么来恢复二进制文件的符号的呢?
  IDAGolangHelper利用的是golang的运行时符号,在go编译的二进制文件中,存在一张表(pclntable)用于记录go二进制文件的运行时符号。在go编译的elf文件中,存在一个pclntable section用来存储这这张表。
Alt text

 

pclantable会保存什么数据呢?
1.funcs
2.src_path
  IDAGolangHeader的重命名函数的功能是通过pclntable来实现的,通过遍历二进制文件查找标记值0x0FFFFFFFB,从而确定pclntable的地址。
Alt text
pclntable的结构如下所示,通过遍历funcs表,得到func_struct,通过func_struct的name_offset字段获取函数名称,进而重命名函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
typedef struct Funcs
{
    DOWRD func_entry;
    DOWRD func_struct_offset;
}funcs;
typedef struct Pclntab
{
    DWORD magic;   //0x0FFFFFFFB
    WORD  reserve; //0x0000
    Byte  ptrsion;
    DWORD func_numbers;
    funcs funcs[func_numbers];
}pclntab;

func_struct的结构如下所示。
Alt text

混淆的恶意软件

近期,在看360net lab发布的一篇文章Blackrota, a heavily obfuscated backdoor written in Go时,看到了go语言的混淆手段,在文章中,攻击者使用开源的混淆工具gobfuscate对语言的源代码进行混淆,在对混淆之后的代码进行编译,以提高分析的难度。
Alt text
根据gobfuscate的描述,gobufuscate会在源码级别混淆如下的数据
1.包名
2.全局变量名
3.函数名
4.类型名
5.方法名
.
我们使用如下的代码来测试以下gobfuscate的混淆

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main
 
import(
    "fmt"
    "io/ioutil"
    "net/http"
)
var url = "https://www.baidu.com/";
func httpget() string {
    client := &http.Client{}
    req, _ := http.NewRequest("GET",url,nil)
    req.Header.Set("Connection","Keep-Live")
    res,err := client.Do(req)
    if err != nil{
        fmt.Println("do error\n")
        return "NULL"
    }
    defer res.Body.Close()
    body,err := ioutil.ReadAll(res.Body)
    return string(body)
}
func main(){
 
    var body = httpget()
    fmt.Println(string(body))
}

首先gobfuscate生成的二进制文件符号是被抹除掉的
Alt text
使用go_parser对生成的二进制文件的符号进行解析,可以发现其源代码路径也被混淆了,但是源代码的文件名并没有被混淆。
Alt text
函数名使用随机字符串混淆了。
Alt text
对于每一个字符串,都会产生一个对用的解密函数,使用xor会字符串进行混淆。
Alt text

学到了什么

1.IDAGolangHeader恢复go 符号的原理
2.gobfuscate的混淆原理

后续

go的其他混淆方法。

参考

Blackrota, a heavily obfuscated backdoor written in Go
deobfuscation-of-gobfuscate-golang-binaries


[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

收藏
点赞3
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回