GO恶意样本实例分析
? ? 最近在工作中遇到不少的go語言編寫的惡意樣本,也整理了在分析go惡意樣本的一些基礎知識,各位同學可以先看看這篇文章《GO惡意樣本分析》,對go語言的分析基礎有一定了解。
? ? 在平常的工作中遇到的情況來看,go語言的惡意樣本可以分為如下的三個等級以及對應的等級的說明。
- 非常簡單: 未去除符號以及未混淆的惡意軟件。
- 一般簡單: 去除符號的惡意軟件。
- 困難:混淆的惡意軟件。
- 我找了幾個對應的樣本,大家可以一起學習學習。
未去除符號以及未混淆的的惡意軟件
??WellMesss是疑似具有俄羅斯背景的APT組織,在今年披露的該組織的一個樣本(Botlib)是使用go語言編寫的,具有Linux和Windows雙平臺的版本,在這里分析了Linux版本的Botlib。
md5:4d38ac3319b167f6c8acb16b70297111
??通過函數名,我們可以很清楚的看到,該樣本是未被去除符號的。通過函數名和源代碼路徑可以對該樣本的功能有一個基本的認識。
該樣本在其中之后,與C2服務器交換數據,將ip地址,計算機名等信息計算sha256后拼接成用戶信息,將其使用rsa算法加密之后,發送到C2,并通過http的cookie攜帶使用rc6加密的指令信息。通信成功后,會獲取下一階段的執行指令。
如下圖為發送的數據
cookie攜帶的數據為如下數據加密后的
<;head;>3139322e3136382e35362e3132387c7c72656d6e75787c72656d6e7578e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/p<;head;><;title;>a:1_0<;title;><;service;>p<;service;>有大佬分享了wellmess botib cookie數據的解密腳本wellmess_cookie_decode.py
在獲取C2下發的數據后,解密后通過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進行命名,以躲避一些自動化分析。
? ? ? ? 接著后去目標計算機系統信息。主要獲取的信息有system info,tasklist,磁盤信息以及屏幕截圖。
1.通過cmd執行systeminfo,獲得系統基礎信息
2.通過cmd執行tasklist,獲得系統進程信息
3.通過cmd執行wmic命令,獲取系統磁盤信息。
4.通過調用第三方截圖包screenshot,獲取截圖數據
最后利用post對相關數據進行上傳,并根據C2返回的數據利用cmd執行系統命令。
運行時符號
??IDAGolangHelper是通過什么來恢復二進制文件的符號呢?
? ? ? ?IDAGolangHelper利用的是golang的運行時符號,在go編譯的二進制文件中,存在一張表(pcIntable)用于記錄go二進制文件的運行時符號。在go編譯的elf文件中,存在一個爬蟲Intable section用來存儲這張表。
pclantable會保存什么數據呢?
1.funcs
2.src_path
??IDAGolangHeader的重命名函數的功能是通過pcIntable來實現的,通過遍歷二進制文件查找標記值0XFFFFFFFB,從而確定pcIntable的地址。
pcIntable的結構如下所示,通過遍歷funcs表,得到func_struct,通過func_struct的name_offset字段獲取函數名稱,進而重命名函數。
typedef struct Funcs {DWORD func_entry;DWORD func_struct_offset; } funcs;typedef struct PcIntab {DWORD magic; //0x0FFFFFFFBWORD reserve; //0x0000Byte ptrsion; DWORD func_numbers;funcs funcs[func_numbers]; } pcIntab;func_struct的結構如下所示.
混淆的惡意軟件
近期,在看360net lab發布的一篇文章(https://blog.netlab.360.com/blackrota-an-obfuscated-backdoor-written-in-go-en/)時,看到了go語言的混淆手段,在文章中,攻擊者使用開源的混淆工具gobfuscate對語言的源代碼進行混淆,在對混淆之后的代碼進行編譯,以提高分析的難度。
Usage: gobfuscate [flags] pkg_name out_path-keeptestskeep _test.go files-noencryptno encrypted package name for go build command (works when main package has CGO code)-nostaticdo not statically link-outdiroutput a full GOPATH-padding stringuse a custom padding for hashing sensitive information (otherwise a random padding will be used)-tags stringtags are passed to the go compiler-verboseverbose mode-winhidehide windows GUI根據gobfuscate的描述,gobufuscate會在源碼級別混淆如下的數據:
1.包名 2.全局變量名 3.函數名 4.類型名 5.方法名我們使用如下的代碼來測試以下gobfuscate的混淆:
package mainimport ("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生成的二進制文件符號是被抹除掉的
使用go_parser對生成的二進制文件的符號進行解析,可以發現其源代碼路徑也被混淆了,但是源代碼的文件名并沒有被混淆。
函數名使用隨機字符串混淆了。
對于每一個字符串,都會產生一個對應的解密函數,使用xor對字符串進行混淆。
學到了什么
1.IDAGolangHeader恢復go 符號的原理
2.gobfuscate的混淆原理
后續
go的其他混淆方法。
參考
Blackrota, a heavily obfuscated backdoor written in Go
deobfuscation-of-gobfuscate-golang-binaries
總結
以上是生活随笔為你收集整理的GO恶意样本实例分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Pyppeteer 使用笔记
- 下一篇: 堕落小白的前台sql注入cms代码审计