先前因某原因進行研究Botnet,本文以僵尸網絡BotenaGo中核心代碼loader_multi.go為例,對源代碼進行代碼審計,梳理攻擊邏輯。

概述

該框架源代碼總共僅包含2891行代碼(包括空行和注釋)。

注釋中提及包含反向shell加載程序和Telnet加載程序,可以根據攻擊者的命令創建后門便于下一步攻擊行動。

同時,框架包含以下EXP(見下圖),其中存在部分CVE漏洞,可以憑借這些EXP針對不同設備或操作系統進行攻擊。

另外,引用以下包在后續代碼會使用到。

圖1 包聲明和注釋

聲明部分

聲明包括常量、結構體、變量三個部分。

常量聲明

首先是常量聲明。

EI_NIDENT、EI_DATA、EE_LITTLE、EE_BIG分別為e_ident[]大小、數據編碼、值為小端的EI_DATA標識、值為大端的EI_DATA標識。

EM_ARM、EM_MIPS、EM_AARCH64、EM_PPC、EM_PPC64、EM_SH分別為ELF頭中所需運行架構為ARM框架的標識符、ELF頭中所需運行架構為MIPS框架的標識符、ELF頭中所需運行架構為AARCH64框架的標識符、ELF頭中所需運行架構為PowerPC框架的標識符、ELF頭中所需運行架構為PPC64框架的標識符、ELF頭中所需運行架構為SH框架的標識符。

DVRIP_NORESP、DVRIP_OK、DVRIP_FAILED、DVRIP_UPGRADED為狀態碼的標識。

echoLineLen用于telnetLoadDroppers函數的dataBuf切片長度。

echoDlrOutFile用于telnetLoader函數的cat命令。

loaderTvtWebTag等Tag類常量用于構造EXP。

loaderDownloadServer、loaderBinsLocation、loaderScriptsLocation屬于對C&C服務器的配置。

loaderDownloadServer為包含Bins和SH 文件的C&C服務器遠程IP地址,loaderBinsLocation為Bins文件路徑,loaderScriptsLocation為SH 文件路徑。

圖2 常量聲明

結構體聲明

elfHeader 文件格式頭結構體,e_ident[EI_NIDENT]即Magic Number,e_type為類型。

e_machine為運行該程序需要的體系結構,e_version為文件版本。

smapsRegion結構體,成員region用于標識smaps內存所屬區域,成員size為進程使用內存空間,rss為int型,pss為Rss中私有的內存頁面,成員shared_clean,shared_dirty,private_clean,private_dirty分別為Rss中和其他進程共享的未改寫頁面、Rss和其他進程共享的已改寫頁面、Rss中改寫的私有頁面頁面、 Rss中已改寫的私有頁面頁面。

echoDropper結構體用于木馬相關的變量使用,成員payload與payload_count。

圖3 結構體聲明

變量聲明

聲明了一個time包中的time.Duration類型變量,初始值為30。

聲明了兩個WaitGroup變量workerGroup、magicGroup。

兩個string類型變量mode、doExploit。

集合exploitMap、dropperMap,前者為EXP集合、后者為木馬集合。

變量telShells和payloadSent用作計數器,分別為telnet連接的shell數量和發送的payload數量。

后面為各設備的EXP和攻擊設置的構造部分。分別為uc、tvt、magic、lilindvr、烽火通信設備、vigor VPN設備、broadcom路由器、宏電IOT設備、Tenda路由器、totlink路由器、zyxel NAS 系統、Alcatel NAS系統、linksys路由器、中興路由器、NETGEAR路由器、GPON路由器、D-Link路由器。

圖4 變量聲明1

圖5 變量聲明2

函數

函數zeroByte

生成字節”0“。函數getStringInBetween獲取字符串內容。函數randstr從大小寫A到Z中選取生成隨機字符串。函數hexToint將hex碼轉換成int型。

圖6 函數1

telnet加載程序模塊

telnetLoadDroppers函數

telnetLoadDroppers函數用于Droppers加載部分,遍歷路徑下文件并讀取。

首先短聲明變量files,err,值為OpenFile函數的結果,參數分別為打開文件的文件路徑、flag、權限碼。之后異常處理,如果error就執行continue。聲明結構體變量mapval為結構體echoDropper的變量。其中的成員payload_count賦值為0。

循環結構首先聲明string型變量echoString,聲明databuf按照128字節的byte型數組。聲明length,err,值為Read函數的結果,參數為databuf。異常處理:如果error或者length異常,break跳出循環。

循環處理聲明echoByte,值為以dataBuf為輸入按照\x%02x格式化處理,并且以uint8類型輸出。echoString每次填充echoByte。如果payload_count為0,則打印首次輸出命令行;如果payload_count不為0,則打印后續輸出命令行。最后按照循環次數依次增加payload_count計數器。

回到函數部分,逐次獲取文件名執行處理。然后關閉文件流。打印telnetLoadDroppers函數執行結果。

telnetHasPrompt函數

telnetHasPrompt函數用于判斷是否包含特殊符號。首先將string類型的buffer作為參數,使用Contains函數進行判斷。如果buffer中包含"#"、">"、"$"、"%"、"@"這些特殊符號其中一種,則返回true;如果都不包含,則返回false。

telnetBusyboxShell函數

telnetBusyboxShell函數用于調用busybox中相關命令于該攻擊框架。

注:BusyBox 是一個集成了三百多個最常用Linux命令和工具的軟件。BusyBox 稱為 Linux 工具里的瑞士軍刀。

其中前三句命令推測用于部分BCM路由器。因為第一句 conn.Write([]byte("sh\r")) 在后續再次出現。

可以看到攻擊常用的命令,例如sh,ping,system等等。

infectFunctionComtrend函數

infectFuctionTenda函數用于Comtrend路由器。

根據函數內容判斷,EXP為CVE-2020-10173(Comtrend VR-3033 路由器多認證命令注入漏洞)

infectFuctionTenda函數

infectFuctionTenda函數用于Tenda路由器。

根據函數內容判斷,EXP為CVE-2020-10987(Tenda AC系列路由器遠程命令執行0day漏洞)。

聲明一個rdbuf數組,類型為byte。

Main函數

01

一個循環結構執行顯示當前加載程序結果。

02

定義dropperMap,分片從echoDropper獲取。

03

調用telnetLoadDroppers函數、scannerInitExploits函數。

04

聲明li、err,調用net包的Listen聲明,根據TCP協議配置監聽設置,根據ucRshellPort作為監聽端口。recvServ、err,調用net包的Listen,根據TCP協議在本地接收監聽的流量,用19412端口接收。

05

循環執行reverseShellUchttpdLoader函數,參數是conn,直到err != nil。根據緩沖區循環執行httpBannerCheck函數,參數是buf,直到err != nil。

06

循環結構。聲明reader、input變量,分別為以os.Stdin為參數調用bufio包的NewReader,以reader為參數調用bufio包的NewScanner。

結束語

本文為僵尸網絡BotenaGo的代碼審計文章,將核心代碼loader_multi.go進行了前期分析,預計不定期會跟進,梳理成后續文章。

往期推薦