Mirai概述
mirai,2016年一個備受關(guān)注的DDoS攻擊程序,與傳統(tǒng)的僵尸網(wǎng)絡(luò)不同的是,mirai的控制的僵尸主要是攝像頭等嵌入式設(shè)備,mirai的出現(xiàn)將一大波安全研究者引入了IoT安全領(lǐng)域。
mirai的事跡主要有:
- 2016.9.20 ,攻擊Brian Krebs個人網(wǎng)站,攻擊流量達(dá)到665Gbps,據(jù)稱有150萬僵尸發(fā)起攻擊。
- 2016.9.21, 攻擊法國網(wǎng)絡(luò)服務(wù)商OVH,攻擊流量達(dá)到1Tbps
- 2016.9.30,mirai開源
- 2016.10.21, 攻擊Dyn DNS,導(dǎo)致Github、Twitter等美國大半個互聯(lián)網(wǎng)下線
- 2016.11.28, 攻擊德國電信,mirai出現(xiàn)新變種
mirai已經(jīng)成為IoT DDOS攻擊的母體。
mirai能夠控制如此大規(guī)模的僵尸網(wǎng)絡(luò),主要原因是各個設(shè)備提供商對安全的不重視,包括雄邁設(shè)備、浙江大華等企業(yè),所有設(shè)備密碼都一樣且不能由用戶修改,且開放telnet端口以致mirai輕易爆破成功。
當(dāng)然,mirai開源了,不看白不看。
Mirai特點
- bot能夠感染多種架構(gòu),包括:Arm、Arm7、MIPS、PowerPC、X86、SPARC等
- 服務(wù)端實施感染,而不是僵尸自己感染其他bot
- 強(qiáng)制清除其他IoT類僵尸,獨占資源
- 強(qiáng)制關(guān)閉telnet服務(wù)、SSH服務(wù)和web服務(wù),并占用端口防止復(fù)活
- 內(nèi)置感染白名單,過濾國防部等無效IP
架構(gòu)
mirai主要由三部分構(gòu)成,源碼對應(yīng)四個模塊:
- loader :監(jiān)聽bot的report,并上傳payload到要感染的設(shè)備
- cnc: command&control,即控制服務(wù)器,主要功能是處理用戶登錄和下發(fā)命令
- bot: 即payload,僵尸程序
- tools: 工具
loader源碼分析
- 發(fā)起telnet連接
- 維護(hù)狀態(tài)機(jī)
CNC源碼分析
CNC部分由golang編寫,golang能用goroutine+channel寫出高性能的服務(wù)器。
CNC源碼主要分為:
- 用戶管理
- 攻擊命令管理
- 感染節(jié)點管理
- 數(shù)據(jù)庫管理
bot源碼分析
bot源碼主要分為:
- attack模塊:解析下發(fā)的命令,發(fā)起DoS攻擊
- scanner模塊:掃描telnet弱口令登錄,上報給loader
- killer模塊:占用端口,kill同類僵尸(排除異己)
- public模塊: utils
1、bot主流程
1、關(guān)閉watchdog,防止設(shè)備重啟
2、Ensure_single_instance 綁定48101,防止多個實例執(zhí)行
3、生成隨機(jī)數(shù),加密進(jìn)程路徑和進(jìn)程名
4、建立daemon,關(guān)閉stdin、stdout、stderr
5、attack_init 主進(jìn)程, add_attack() 添加攻擊類型和回調(diào)函數(shù)
6、kill_init 創(chuàng)建killer子進(jìn)程,根據(jù)端口號找到pid殺死進(jìn)程,killer_kill_by_port
7、scanner_init, 掃描子進(jìn)程,一個死循環(huán)
8、主進(jìn)程,死循環(huán),監(jiān)聽CNC連接,解析攻擊參數(shù),發(fā)起攻擊
2、attack模塊
①從table.c獲取CNC的域名和端口(cnc.changeme.com,可以在loader中修改),建立連接,然后一個select監(jiān)聽CNC connection
②定時發(fā)送心跳,保持連接
③attack_parse解析攻擊參數(shù) ,主要包括攻擊時長、攻擊類型、攻擊目標(biāo)、攻擊選項,attack_start發(fā)起dos攻擊
攻擊方式
以attack_tcp_syn為例,用raw socket 構(gòu)造指定數(shù)量的tcp syn包,并sendto給指定目標(biāo)地址。
- attack_app.c
- attack_gre.c
- attack_tcp.c
1、attack_tcp_syn()
2、attack_tcp_ack()
3、attack_tcp_stomp() - attack_udp.c
1、attack_udp_generic()
2、attack_udp_vse()
3、attack_udp_dns()
4、attack_udp_plain()
3、scanner模塊
1、用raw socket試探性掃描telnet的23號端口,有回應(yīng)才進(jìn)行telnet登陸嘗試
2、用scanner_init中硬編碼的弱口令字典去嘗試登陸telnet
3、進(jìn)入登錄狀態(tài)機(jī),執(zhí)行一系列命令來判斷是否登錄成功
4、如果登錄成功,開啟一個子進(jìn)程,將IP、端口、用戶名、密碼按照固定格式上報給loader,loader的scanListen.go處理接收暴力掃描的結(jié)果
4、killer模塊
其實整個killer就做了兩件事:
1.殺死端口22,23,80對應(yīng)的進(jìn)程,并占用此端口,防止端口被重新啟用,killer_kill_by_port
2.查找到anime程序?qū)?yīng)的進(jìn)程并結(jié)束進(jìn)程,并刪除文件,即干掉同類競爭對手。
5、public模塊
- talbe.c 存了一些硬編碼的數(shù)據(jù),并對數(shù)據(jù)進(jìn)行加密,向外提供加解密、取出成員和添加成員的接口。
- resolve.c 提供了根據(jù)域名向DNS服務(wù)器8.8.8.8查詢IP的接口resolv_lookup
tools源碼分析
1、scanListen.go
scanListern.go是一個golang實現(xiàn)的服務(wù)器,運行在loader那臺服務(wù)器上,監(jiān)聽48101,每一個bot上報時,新啟一個go程處理連接,將收到的
func main() {
l, err := net.Listen("tcp", "0.0.0.0:48101") //INADDR_ANY 通配地址
if err != nil {
fmt.Println(err)
return
}
for {
conn, err := l.Accept()//多線程服務(wù)器
if err != nil {
break
}
go handleConnection(conn) //go 開啟一個線程
}
}
- 異或加密
- 反gdb調(diào)試
- 接收掃描結(jié)果