githubEdit

Precious

https://app.hackthebox.com/machines/Precious

Summary

Precious is a Linux-based target hosting a "Web to PDF" conversion utility powered by Ruby on Rails. The assessment identified a critical Command Injection vulnerability (CVE-2022-25765) within the underlying pdfkit library, allowing for unauthenticated Remote Code Execution (RCE). Post-exploitation enumeration uncovered cleartext credentials stored within a user's Bundler configuration, facilitating lateral movement via SSH. Final privilege escalation to root was achieved by exploiting an Insecure Deserialization flaw in a sudo-enabled Ruby script that utilized YAML.load on untrusted input.

MITRE Kill Chain

1

Reconnaissance

Network enumeration identified a web server on TCP port 80 and SSH on port 22.

2

Resource Development

A local HTTP server was staged to host malicious payloads for the target application to retrieve.

3

Initial Access

A Command Injection vulnerability in pdfkit v0.8.6 was exploited via a crafted URL parameter to execute arbitrary code.

4

Execution

A Ruby-based reverse shell was executed to establish an interactive session as the ruby user.

5

Credential Access

Cleartext credentials for a secondary user were harvested from the .bundle/config file.

6

Lateral Movement

The compromised credentials were used to authenticate via SSH as the user henry.

7

Privilege Escalation

A Ruby script running with sudo privileges was exploited via Insecure Deserialization (YAML), resulting in full root compromise.


Reconnaissance

#attack/T1018 #attack/T1595_001 #attack/T1592

Initial Connectivity & Host Discovery

The assessment began with a connectivity check to the target host. An ICMP echo request was transmitted to verify the status of the asset and estimate the underlying operating system.

attacker> ping -c 1 10.10.11.189
PING 10.10.11.189 (10.10.11.189) 56(84) bytes of data.
64 bytes from 10.10.11.189: icmp_seq=1 ttl=63 time=208 ms

--- 10.10.11.189 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 208.190/208.190/208.190/0.000 ms
circle-info

The TTL (Time to Live) value of 63 indicates the target is likely a Linux-based system, accounting for a single hop in transit.

Network Service Enumeration

To map the attack surface, a full TCP port scan was performed using nmap. The scan targeted all 65,535 ports to identify open listeners.

Following the identification of open ports, a targeted service scan was executed to determine version information and default script output for the discovered services on ports 22 and 80.

The service enumeration revealed the following:

  • Port 22: Running OpenSSH 8.4p1 on Debian Bullseye.

  • Port 80: Running nginx 1.18.0. The web server responded with a 302 Found redirect to http://precious.htb/, indicating a virtual host-based configuration.

Virtual Host Configuration

To interact with the web application, the local /etc/hosts file was updated to map the IP address 10.10.11.189 to the precious.htb domain.


Web Exploitation

#attack/T1592 #attack/T1593

Initial technology profiling was performed on http://precious.htb to identify the underlying web stack and potential points of interest.

circle-info

The target is a Ruby on Rails application served via Phusion Passenger 6.0.15 behind Nginx 1.18.0.

The application is a "Convert Web Page to PDF" utility running on Ruby-on-Rails and served by Phusion Passenger 6.0.15. A search for known vulnerabilities in Phusion Passenger was conducted; however, the results were primarily legacy Windows exploits and did not align with the target environment.

Functional Analysis: PDF Conversion

The web interface presents a single input field requesting a URL to be converted into a PDF document.

To test the application's behavior and verify its ability to reach external resources, a local HTTP server was started, and a request was initiated from the web interface.

The application successfully retrieved the content from the attacker-controlled server and rendered a PDF.

Vulnerability Discovery: PDFKit Command Injection

#attack/T1190 #owasp/A05_2025 #owasp/A03_2025

Analysis of the generated PDF was performed using exiftool to identify the backend processing engine.

circle-info

The application uses pdfkit v0.8.6 for document generation.

Further research into this version revealed CVE-2022-25765arrow-up-right, a critical command injection vulnerability. The flaw exists because the library does not properly sanitize URL parameters. If a URL contains a query string with an encoded shell command (e.g., using backticks or $( )), pdfkit executes the command during the conversion process.

triangle-exclamation

Finding: Command Injection in pdfkit v0.8.6 (CVE-2022-25765)

Exploit Verification

A proof-of-concept was executed to confirm the vulnerability by attempting to echo the current user within the PDF content. By passing the command as a URL parameter, the backend executed the instruction and embedded the output into the resulting document.

The resulting PDF confirmed successful execution, displaying the username ruby.

Remote Code Execution (RCE)

The vulnerability in pdfkit v0.8.6 was leveraged to gain arbitrary code execution. By injecting shell commands into the URL parameters passed to the PDF generator, the underlying system executed the commands under the context of the ruby user.

Initial validation was performed by executing the id and hostname -I commands. The payload was structured to satisfy the URL requirement while escaping the application's intended logic.

The resulting PDF document rendered the output of the commands, confirming the execution context and network configuration.

circle-check

Reverse Shell Establishment

To obtain an interactive session, a Ruby-based reverse shell payload was crafted. An HTTP listener was not required for the final payload; instead, a Netcat listener was staged on the attacker machine to intercept the outgoing connection.

The listener successfully captured the connection, providing a remote shell.

Shell Stabilization

The initial shell was upgraded to a fully interactive TTY to support advanced terminal features and job control.


Lateral Movement

#attack/T1552_001 #attack/T1021_004

Internal Enumeration

Following the establishment of the foothold, the system was enumerated for sensitive files and additional user accounts.

The enumeration identified a secondary user, henry. Investigation of the ruby user's home directory revealed a hidden .bundle directory containing a configuration file.

circle-exclamation

The discovered credentials were used to authenticate as henry via SSH, granting more persistent access and access to the user's data.

Upon successful login, the user flag was retrieved from the home directory.


Privilege Escalation

#attack/T1548_003 #attack/T1210 #owasp/A08_2025

Sudo Rights Enumeration

The user henry was found to have specific sudo privileges that allowed the execution of a Ruby script as the root user without providing a password.

The target script, /opt/update_dependencies.rb, is owned by root and is not writable by the current user.

Vulnerability Analysis: Insecure Deserialization

Analysis of the Ruby source code revealed a critical security flaw in the way the script handles external configuration files.

The script utilizes the YAML.load method to process a file named dependencies.yml. Because the script uses a relative path and the insecure load method (as opposed to safe_load), an attacker can control the execution flow by placing a malicious YAML file in the current working directory.

triangle-exclamation

Finding: Insecure Deserialization in update_dependencies.rb

Vulnerability Verification (PoC)

To verify the vulnerability, a malicious dependencies.yml was created using a known Ruby YAML deserialization gadget chainarrow-up-right. The first test aimed to execute the id command as root.

The output confirmed that the command was successfully executed with root privileges.

Root Access Acquisition

The payload was modified to establish a persistent root-level access point. Specifically, the bash binary was copied to the /tmp directory and assigned SUID permissions.

Executing the script again triggered the payload:

By executing the SUID bash binary with the -p (preserve permissions) flag, a root shell was obtained.

circle-check

Last updated