2016年11月6日 星期日

Mirai程式碼分析

Mirai程式碼分析

Mirai 是一網路殭屍病毒,名稱可能是取自日文「未来」,最近作者Anna-senpai開放原始碼,正好可以一窺殭屍病毒作法。本篇針對其程式流程做一介紹,希望在開發自家產品時,能夠避開這些攻擊方法,避免成為殭屍大軍一員。

針對殭屍病毒,需要先了解幾個名詞
Zombies: 被控制的電腦(又可稱為robot,一般簡寫為bot)
CNC: Command And Control,就是決定何時發動攻擊的控制中心

Mirai 的基本運作方式
  1. 每個 bot 會根據 Table.c 內的 TABLE_CNC_DOMAIN, 連到某一個 CNC, 因為是 domain name, 所以實際解析出來的 IP 位址是可變的。 
  2. 因為 TCP 有 3way handshake 機制 (SYNC, ACK, SYNC+ACK), bot 會利用 SYN scanner 找到網路上有開放 port(23) 的機器 (機器會回應 SYNC-ACK),並試著將字典內的所有帳號密碼都測試一次,若能夠登入Telnet,則將掃描結果回報另一台伺服器。
  3. bot 透過 port 48101 回傳結果給 scan receiver,mirai/tools/scanListen.go 會負責處理回傳結果,將找到的機器的 ip, username, password 都打印出來。
  4. 接著 scan receiver 便可以透過 telnet 登入機器,稱此機器為機器 A。
  5. 若機器 A 有現成的 wget 或 tftp,便會直接使用它們下載執行檔mirai,否則會使用一個自帶的wget下載mirai. (mirai/tools/wget.c)接著執行mirai, 然後機器 A 就變成了一個新的殭屍電腦(bot)。
基本上要測試此方法,最少要有兩台伺服器。其伺服器用途如下:
2 servers: 1 for CNC + mysql, 1 for scan receiver
最好是能夠將 mysql 分別架設在另一台伺服器,並且額外提供 load balancing server

Mirai 程式碼分析

1. bot
main(),
一旦程式開始執行之後,首先做的就是隱藏自己,包含以下動作
  • 首先把自己刪除 (刪除檔案系統內的 mirai 執行檔)。 
  • 接著註冊 SIGTRAP,避免有人利用 gdb 了解程式運作流程。
  • 關掉 watchdog,避免機器因為 watchdog 重啟。命令是ioctl(wfd, 0x80045704, &one); 
  • 試著 bind port 48101,若成功,就進行 listen等待連接。若失敗,表示有其他行程正在使用 48101,刪除現在正在占用 48101 的行程並且再試一次。此處 killer_kill_by_port() 函數的作法值得一看。 
  • 亂數產生程式名稱,改變 argv[0] 以及 行程的名稱,並且在STDOUT內加入此執行檔的紀錄。因為是亂數產生的名稱,因此使用 ps 檢視可以很容易看出問題。所以後面要關閉可能使用 ps 檢視系統資訊的各種遠端登入方式。(如:telnet,ssh, http) 
  • 接著執行 attack_init(), killer_init(), scanner_init(),然後建立連線至 CNC Server,此連線記錄在 fd_serv。 
  • 最後執行下列程式邏輯 
if (pending_connection)
    pending_connection = FALSE;
    通知 CNC, 送出初始訊息, 會先送出 0x00000001, 再送出 id
else
    等待 CNC送來的命令,若收到攻擊命令,就開始進行 DOS 攻擊。attack_start()

attack_init()
初始化攻擊類型,目前共提供十種攻擊方法,所有攻擊方法都放在 Attack_*.c
各種攻擊基本上都是使用 setsockopt(IP_HDRINCL),根據各種漏洞,自行製作會引發問題的 IP 封包。
killer_init()
刪除 port 23, 22, 80 對應的行程,也就是關閉 telnet, ssh, http 服務,
並且占用這三個對應的 port,如此便可以避免 telnet, ssh, http 服務重啟。 如此沒有人可以登入這台機器,也就避免 mirai 被發現。
scanner_init()
將各種預設帳號密碼加入 mysql,這些帳號密碼都會使用 0xdeadbeef 作 XOR 運作。
接著產生 connection table,共可記錄 128 組連線資訊
隨意產生 160 組 Public IP 位址,試著看看這些 IP 是否會對 port 23 有反應。(回SYNC-ACK)
若有回應,則會將此連線資訊紀錄至 connection table
若 connection table 有值,則隨意從資料庫內挑一組帳號密碼,試試能否正確登入機器。總共會測試十次,每次使用不同帳號密碼
若發現可以正確連線,會將可正確建立TELNET連線的資訊告知 scan receiver.
由 scan receiver 負責針對機器植入木馬。

establish_connection()
自動連線到 CNC Server
注意:此處 table_lock_val() 與 table_unlock_val() 都是同樣的處理邏輯,
把記憶體內容與 0xdeadbeef 作 XOR 運算,並且設定 val->locked = !val->locked; 此作法值得參考

2. Loader (scan receiver)
先載入 bins/ 目錄下的所有執行檔,後續可以根據此時所在的硬體平台,直接呼叫當作函數檔案內對應的直接呼叫。此處 binary_init() 值得參考
啟動一個 Server Process, 並且根據CPU個數,分別建立對應的 worker threads。 
主程式會從 STDIN 讀取 telnet 相關資訊,分析後進行連線,並將此事件透過 epoll_ctl 加入監聽列表重複上述 STDIN 讀取動作,直到 STDIN 沒有值可讀取。 
worker thread 則會等待 epoll_wait()返回,一旦有事件觸發,便會呼叫 handle_events,根據事件的狀態,進行相對應的任務。 
任務的終極目的是登入機器,找到可以寫入的磁碟空間,透過 wget 或 tftp 將 Mirai 搬移至機器內,並且執行Mirai(bot)。


3. CNC
先參考 main.go
此程式會建立 clientlist 與 database,
接著在 port 23 與 101 各建立一個 socket, 等待資料
port 101 接收的資料由 initialHandler() 負責處理
port 23 接收的資料由 apiHandler() 負責處理
initialHandler() 可參考 bot.go
若收到的訊息長度為四,且符合 0x0000000x,x>0,便會在 clientList 新增一筆資料,記錄新的 bot。否則便是新增一個新的管理者帳號 (ADMIN)。
apiHandler() 可參考 api.go
收到訊息後,會先呼叫 CheckApiCode() 取得使用者的資訊,接著解析收到的訊息,並通知 bot 進行攻擊,共可採用十種攻擊方法

當設備有下列缺陷,便可能成為殭屍大軍一員
1. 預設開放 Telnet 
2. 設備的預設帳號密碼列在 mirai source code 之中。
    下面列出 mirai 收集的帳號密碼
// root xc3511
// root vizxv
// root admin
// admin admin
// root 888888
// root xmhdipc
// root default
// root juantech
// root 123456
// root 54321
// support support
// root (none)
// admin password
// root root
// root 12345
// user user
// admin (none)
// root pass
// admin admin1234
// root 1111
// admin smcadmin
// admin 1111
// root 666666
// root password
// root 1234
// root klv123
// Administrator admin
// service service
// supervisor supervisor
// guest guest
// guest 12345
// guest 12345
// admin1 password
// administrator 1234
// 666666 666666
// 888888 888888
// ubnt ubnt
// root klv1234
// root Zte521
// root hi3518
// root jvbzd
// root anko
// root zlxx.
// root 7ujMko0vizxv
// root 7ujMko0admin
// root system
// root ikwb
// root dreambox
// root user
// root realtek
// root 00000000
// admin 1111111
// admin 1234
// admin 12345
// admin 54321
// admin 123456
// admin 7ujMko0admin
// admin 1234
// admin pass
// admin meinsm
// tech tech
// mother fucker

建議避免 Mirai 感染的方式便是

  1. 機器預設不要開放 Telnet
  2. 強制使用者登入機器之後,就得要修改帳號密碼。