A PDF converter hiding a command injection CVE, credentials buried in a Ruby config file, and a YAML deserialization gadget to finish it off - Precious stacks three clean techniques on top of each other.
Machine info
| Name | Precious |
| Platform | HackTheBox |
| OS | Linux |
| Difficulty | Easy |
TL;DR
- Web app converts URLs to PDFs using pdfkit v0.8.6, which is vulnerable to CVE-2022-25765 (command injection)
- Initial shell as
ruby, Bundler config at~/.bundle/configleaks credentials for userhenry - Henry can run a Ruby script as root with
sudo; the script usesYAML.load- exploitable via deserialization to get a root shell
Recon
Nmap
| |

Ports 22 (SSH) and 80 (HTTP). Nginx 1.18.0, redirects to precious.htb - add it to /etc/hosts.
Enumeration
PDF converter app

The site takes a URL and generates a PDF from it. Set up a Python HTTP server on Kali and point it at my IP:

The app fetches the URL and returns a PDF:

Download the PDF and check the metadata:

Creator: Generated by pdfkit v0.8.6. That version is vulnerable to CVE-2022-25765 - a command injection in the URL parameter when pdfkit processes a URL containing a % character followed by a shell command.

Foothold
CVE-2022-25765 - pdfkit command injection
| |

The exploit sends a crafted URL with an embedded Ruby reverse shell payload targeting the pdfkit sink. The listener catches it:

Shell as ruby.
Privilege Escalation
Credentials in Bundler config
Poking around the home directory:

~/.bundle/config holds a BUNDLE_HTTPS__RUBYGEMS__ORG entry with credentials: henry:Q3c1AqGHtoI0aXAYFH. SSH in as henry:
| |
Ruby YAML deserialization RCE
| |

Henry can run /opt/update_dependencies.rb as root without a password. The script calls YAML.load(File.read("dependencies.yml")) - YAML.load in older Ruby versions deserializes arbitrary objects, making it a classic gadget for RCE.
Craft a malicious dependencies.yml in henry’s home directory:

| |
| |
Root shell on the listener:

Takeaways (for OSCP)
- Always extract PDF metadata when a site generates documents. The PDF creator field regularly leaks the library name and version - and libraries like pdfkit, wkhtmltopdf, and LibreOffice all have CVEs worth checking.
- Ruby config files hold credentials in plaintext.
~/.bundle/config,.gemrc, and similar files are easy to miss during manual enumeration - check hidden directories in every home folder. YAML.loadis a deserialization sink. In Ruby,YAML.load(as opposed toYAML.safe_load) can instantiate arbitrary objects. If you see it in a root-owned script, look for a YAML gadget chain.
References
- HackTheBox - Precious
- CVE-2022-25765 - pdfkit command injection
- Exploit-DB #51293
- Lain Kusanagi list (OSCP prep)
