360安全衛士 · 2016/01/05 18:33linux
Author:王陽東(雲安全研究員)@360信息安所有redis
近期, 部署於360雲平臺(cloud.360.cn)的」360天眼威脅感知系統」發現系統告警某合做夥伴剛開通的雲主機存在異常流量,聯合排查後發現有惡意攻擊者利用redis crackit漏洞入侵服務器並種植了名爲unama的惡意程序。 360雲安全研究員 --「王陽東」對此惡意程序進行較爲深刻的分析,此樣本多是billgates僵屍網絡的一個變種。算法
billgates是一個近幾年很是活躍的DDoS僵屍網絡,此程序組成的僵屍網絡遍佈世界。網絡中bot節點可能是一些存在弱口令或軟件漏洞的linux主機,攻擊者利用ssh爆破、exploit、1day、2day等方式對大量IP進行攻擊嘗試得到服務器的控制權,並經過部署殭屍木馬被控端壯大僵屍網絡。僵屍網絡根據服務端命令能夠實現DDoS攻擊、反彈shell等多種操做。shell
捕獲到的樣本文件大小爲1223123
字節,MD5值爲EFF1CB4E98BCC8FBCBDCA671D4C4A050
。編程
經過readelf獲得的源代碼文件名共有44個,從源文件名猜想此程序有較多工做線程。安全
靜態分析後發現此樣本不一樣部分間的代碼風格差別較大:main函數的代碼比較簡單粗糙,而主功能類CManager及附屬類部分卻展示出病毒做者對C++的熟練應用。服務器
初始化操做:網絡
程序使用自定義算法從.rodata段解密出配置信息並保存,獲取程序文件大小與配置信息中的對應值進行對比實現簡單的自校驗,而後在父進程路徑中查找gdb實現反調試。併發
調用自定義解密函數,獲取硬編碼數據進行拼接,獲得如DbSecuritySpt、selinux、getty、/tmp/moni.lod、/tmp/gates.lod等字符串並存儲到全局變量。檢查當前程序路徑肯定要執行的功能。 路徑和功能的關係以下:app
程序路徑 | 後門種類 | 功能函數 | 主要功能 |
---|---|---|---|
/usr/bin/.sshd |
MainMonitor | Monitor,守護進程 | |
未知路徑 (與其它類型不匹配) | 1 | MainBeikong 安裝等操做,並執行主要功能 | |
/usr/bin/bsd-port/getty |
2 | MainBackdoor | 主要功能執行程序 |
/bin/ 、/usr/bin/ 、/usr/sbin/ 下netstat、lsof、ps或ss |
3 | MainSystool | 運行/usr/bin/dpkgd 下備份的系統工具並過濾輸出信息 |
如果0,1,2類後門則從硬編碼中拼接一串十六進制數字符串(實際上是兩部分十六進制數,以大寫字母O分隔,看似一串),
根據後門類型解密對應部分的十六進制數串,0,1類後門獲得的配置是173.254.230.84:3411:1:1:yz:1,
2類後門獲得的配置是fk.appledoesnt.com:30000:1:1:yz:1
。用冒號分隔字符串獲得6個配置項並保存。
檢測文件名是不是「update_temporary」,如果則執行DoUpdate並退出。
執行對應的功能函數。
MainMonitor(守護進程):
進入daemon,產生pid文件/tmp/moni.lod
,讀取/tmp/notify.file
內容並保存,建立線程類CThreadMonGates並啓動監視線程,主線程循環sleep掛起。監視線程每分鐘判斷一下/tmp/gates.lod
文件(MainBackdoor功能進程的pid file), 若文件不存在則複製自身到從notify.file中獲取到的文件路徑並執行新路徑下的程序。
MainBeikong(程序安裝):
進入daemon模式,調用KillChaos結束/tmp/moni.lod
和/tmp/gates.lod
指向的舊進程 (病毒做者搞錯了strcmp的返回值,因此這裏的代碼並無什麼卵用),再次結束/tmp/moni.lod
,結束/tmp/bill.lock
並刪除bill.lock。再次結束/tmp/gates.lod
並設置自身pid文件。在/etc/init.d
、/etc/rc(1-5).d
等路徑設置S97DbSecuritySpt啓動項。
結束/usr/bin/bsd-port/
下getty.lock和udevd.lock對應的進程,刪除udevd.lock,複製自身到/usr/bin/bsd-port/getty(對應MainBackdoor)
並啓動。將當前程序路徑寫入/tmp/notify.file
(守護進程使用),複製當前文件到/usr/bin/.sshd
(對應MainMonitor)並啓動。執行MainProcess函數。MainProcess函數包含了木馬的主要功能。
之因此在安裝操做中執行猜想是由於病毒的一處配置錯誤:
因爲以前以字母O分隔的兩串hex順序搞反了,致使2類後門(木馬功能主體)獲得的是fk.appledoesnt.com這一無效域名,而1類後門(安裝程序)卻能獲得173.254.230.84:3411這個有效IP,因此在沒有找到問題緣由的狀況下在安裝函數最後加入主功能函數(MainProcess)也不失爲一種臨時解決方案。
MainSystool(系統工具替換):
獲取當前程序名及參數,調用/usr/bin/dpkgd/
下對應的原始系統程序(netstat 、lsof、ps、ss)。從原始系統程序的輸出中過濾掉包含木馬所在目錄、服務端通訊端口等信息的行。
MainBackdoor(木馬功能主體):
進入daemon,設置pid文件,以 S99selinux爲服務名建立啓動項。移動系統程序ps、ss、netstat、lsof到/usr/bin/dpkgd/
目錄,複製自身到/bin
、/usr/bin
、/usr/sbin
下替換ps、ss、netstat、lsof等系統程序,執行主功能函數MainProcess。
MainProcess函數:
主功能函數MainProcess首先掛起2秒,刪除升級用的臨時文件(./update_temporary
),根據/etc/resolv.conf
和谷歌dns(8.8.8.八、8.8.4.4)初始化CDNSCache類的實例g_dnsCache
。
初始化g_cnfgDoing
(嘗試讀取conf.n文件)、g_cmdDoing
(嘗試讀取cmd.n文件)、g_statBase
類實例,將g_sProvinceDns
中330個IP轉爲數字形式存入g_provinceDns
對象。嘗試經過insmod加載當前目錄下的xpacket.ko驅動(未發現此文件)。從/usr/lib/libamplify.so
中讀取IP存入g_AmpResource
結構(未發現此文件)。初始化CManager(1076字節),設置信號處理函數,無限循環sleep。
CManager類包含了bot的全部功能,此類擁有不少成員,每一個成員實現必定的功能,其主要成員對應列表大體以下:
成員 | 偏移 | 功能 |
---|---|---|
vectorIPs | 0x00 | 控制服務器IP地址(可存在多個) |
CThreadSignaledMessageList
|
0x0c | CCmdMsg的消息隊列(線程安全) CCmdMsg包含控制服務器下發的控制指令 |
CThreadTaskGates | 0xe4 | 任務分發線程類,等待CCmdMsg消息隊列 |
CThreadClientStatus | 0xe8 | 狀態更新線程類,每秒更新cpu及網絡使用狀況 |
CThreadSignaledMessageList
|
0xf0 | CThreadConnection的隊列(線程安全) |
CThreadLoopCmd | 0x1c8 | 循環等待信號,並最終執行cmd.n文件配置的命令 |
CThreadFakeDetect | 0x1cc | 測驗bot有效性的類 |
CThreadSignaledMessageList
|
0x1d0 | CThreadShell的隊列(線程安全) CThreadShell用來保持一個反向鏈接的shell會話 |
CThreadDoFun | 0x2ac | 經過一些計算判斷bot文件有效性並設置g_bReal 變量 |
CThreadKillChaos | 0x2b0 | 每5分鐘檢查pid file並執行清理 |
CInitResponse | 0x2b4 | 初始化數據包,包含當前被控機器的一些狀態數據 |
CThreadMutex_Operation | 0x378 | CManager互斥量,線程安全 |
SetOfCThreadFXConn | 0x390 | CThreadFXConnection類組成的set (C++ STL) |
CTask | 0x400 | 包含控制服務器下發的命令信息 |
CManager::Initialize
函數對成員進行了初始化操做,根據g_cmdDoing
檢查是否有未處理的命令,如有則馬上執行。
初始化完成員變量後執行CManager::MainProcess
,根據g_iGatsIsFx
的值(此時爲1)設置程序工做在被控端模式,獲取vectorIPs中的IP (此時只有strConnTgts指向的IP)針對每一個IP初始化一個CThreadFXConnection並加入set,完成後無限循環sleep。
CThreadFXConnection線程類最終調用CManager::FXConnectionProcess
創建與控制服務器的TCP鏈接,鏈接創建後調用CManager::ConnectionProcess
初始化CInitResponse對象併發送一個通知數據包:
其中CInitResponse中包含IP(c0 a8 7a 87) 192.168.122.135,系統版本信息,Cpu及內存等信息。
發送完初始化包後,CManager::ConnectionProcess
進入收發數據的循環,經過CManager::RecvCommand
接收數據並封裝到CCmdMsg結構,將CCmdMsg加入CThreadSignaledMessageList<CCmdMsg>
隊列。
經過CManager::SendClientStatus
發送bot狀態。
CCmdMsg由CManager::TastGatesProcess
線程負責從接收隊列中取出並分發(CThreadTaskGates線程類啓動的線程)。
CCmdMsg大體類型以下:
類型 | 功能 |
---|---|
1 | 調用CManager::DoAtkStartCommand初始化一個DDoS攻擊 |
2 | 根據CManager狀態選擇執行CManager::StopUpdate中止更新或CManager::StopAtkTask中止攻擊 |
3 | 調用CManager::DoConfigCommand更新g_cnfgDoing及conf.n配置文件 |
5 | 調用CManager::DoUpdateCommand更新程序文件 |
7 | 調用CManager::DoCommandCommand更新CCmdDoing對象 |
8 | 調用CManager::DoFakeDetectCommand |
9 | 調用CManager::DoShellCommand創建到指定IP及端口的反彈shell鏈接 |
CManager類大體結構以下:
DDoS攻擊最終經過CManager::DoAtkStartCommand
實現,這個函數讀取CCmdMsg中的CTask對象,根據CConfigDoing(conf.n)全局配置設置CThreadAtkCtrl線程對象。CThreadAtkCtrl::ProcessMain
會根據配置執行普通攻擊或內核級攻擊。普通攻擊經過CThreadAtkCtrl::DoNormalSubTask
執行,該函數最終調用CThreadAtkCtrl::StartNormalSubTask
,根據每一個任務初始化一個CThreadNormalAtkExcutor線程類。最終線程函數爲CThreadNormalAtkExcutor::ProcessMain
,此函數會根據CSubTask.taskType的值初始化一個CPacketAttack的子類用於執行相應的攻擊,type值與攻擊類型的對應關係以下:
CSubTask.taskType | 子類 | 攻擊方式 |
---|---|---|
0x十、0x11(var_06=0) | CAttackSyn | SYN半鏈接 |
0x十、0x11(var_06=1) | CAttackCompress | 自定義IP、TCP頭 |
0x20 | CAttackUdp | UDP |
0x2一、0x2三、0x24 | CAttackDns | 隨機子域名攻擊 |
0x22 | CAttackAmp | DNS放大 |
0x25 | CAttackPrx | 某種DNS攻擊 |
0x30 | CAttackIcmp | ping |
0x40 | CTcpAttack | 任意TCP數據,發送攻擊者自定義的數據內容 |
0x41 | CAttackCc | CC |
0x42 | CAttackIe | 未實現,從新設置成0x41 |
CThreadNormalAtkExcutor::ProcessMain
根據配置調用Create成員構造特定類型所需的數據。
調用成員函數Do,Do調用MakePacket構造攻擊數據包,調用UpdateCurVariant修改數據包的一些屬性(如TCP順序號等),調用SendPacket發送數據包。Do函數被循環調用,直到預約數目的攻擊完成。
內核攻擊經過調用CThreadAtkCtrl::DoKernelSubTask
執行(type 0x43),
該函數最終調用CThreadAtkCtrl::StartKernelSubTask
,初始化CThreadKernelAtkExcutor。
最終執行線程爲CThreadKernelAtkExcutor::ProcessMain
。
此函數fork當前進程,在每一個CPU上執行函數CThreadKernelAtkExcutor::KCfgDev
,此函數發送命令rem_device_all
(移除全部設備)、add_device ethN
(添加網卡N)、max_before_softirq
(改變數據包內核中斷閾值)到pktgen設備,N爲0、一、2等,指向網卡名稱。pktgen設備位於/proc/net/pktgen/kpktgend_X
,其中X爲當前cpu號。病毒做者在這裏犯了一個錯誤,kpktgend_X
中X指關聯到當前包產生器的cpu號,但病毒做者在這裏用的是網卡號,這個錯誤致使病毒在生成數據包時只用到了一個cpu,沒法充分利用多核多cpu的性能。完成pktgen設備的初始化後,CThreadKernelAtkExcutor::ProcessMain
調用CThreadKernelAtkExcutor::KCfgCfg
,此函數經過/proc/net/pktgen/ethN
配置包產生器。配置包含攻擊目標IP端口、發送攻擊數據包數目、包大小隨機範圍、數據包之間的等待時間、源IP隨機範圍、源端口隨機範圍等信息。設置完pktgen的參數後CThreadKernelAtkExcutor::ProcessMain
向/proc/net/pktgen/pgctrl
寫入start來啓動攻擊。
修改bot的控制服務器IP到本機並編寫簡單的控制端腳本,在虛擬機中進行tcp rst攻擊實驗:
在設置攻擊目標爲192.168.122.1:9876,數據包大小範圍爲128-500,線程數目爲200,攻擊次數100並關閉Cpu負載均衡開關後獲得的攻擊數據包以下:
能夠看到單個bot在這次攻擊中共發送了21268252個攻擊數據包,數量驚人。
因爲Cpu使用率限制選項設爲關閉,bot最大化使用系統資源,雙核cpu達到192.4%的利用率。
經過此樣本能夠發現黑產團隊的DDoS攻擊實力已經到了」比較嫺熟」的地步,而根據樣本中不一樣部分的不一樣代碼風格猜想黑產團隊可能存在多人多團隊合做的編程方式或「黑吃黑」的代碼盜用狀況,也許。
IT基礎技術不斷髮展的今天,追逐利益的黑產團隊依然在不懈的利用剛暴露出來的漏洞攻擊着那些疏忽的操做系統,威脅着用戶的數據安全。用戶願意將他們的數據、過程實現、想法放到咱們的雲平臺,是由於他們相信咱們能讓這些數據的隱私和安全獲得有力的保證,360雲安全團隊持續爲您構建一個安全雲。