Skip to main content

Starting the box

Link to the box: https://app.hackthebox.com/machines/CodePartTwo

Port Scan

We start off the box by running a port scan on the provided IP.
Attacker Linux
Output of Rustscan:
Terminal Output
Output of Nmap:
Terminal Output
A few key notes:
  • Port 22 (SSH) is open. Running OpenSSH 8.2p1 — we’ll keep this in mind for later.
  • Port 8000 (HTTP) is open, served by Gunicorn 20.0.4 — a Python WSGI HTTP server.
  • OS is Linux (Ubuntu).

Edit the Hosts file

We don’t see any redirect in the Nmap output, so we’ll skip the hosts file for now. If we discover a hostname later during enumeration, we’ll add it then.

Initial Foothold

Enumerating Port 22: SSH

While there could be vulnerabilities in OpenSSH 8.2p1, it is rarely the intended attack vector in HTB settings. Without credentials, SSH isn’t useful right now. Let’s focus on the web server.

Enumerating Port 8000: Web Server

Manual Enumeration

Let’s browse to the web application at http://10.10.11.82:8000:
  • The landing page shows “Welcome to CodePartTwo” — a simple web interface.
  • There’s a login page and registration functionality.
  • After registering an account and logging in, we reach a dashboard.
The dashboard mentions something about running code snippets. Let’s keep exploring to understand what this application does.

Directory Busting

Let’s run directory enumeration to find hidden endpoints:
Attacker Linux
Terminal Output
  • We found a /download endpoint — let’s check it out.
Accessing http://10.10.11.82:8000/download triggers a file download: app.zip.
  • This appears to be the application source code.
  • Let’s unzip and review it.

Reviewing the Source Code

After extracting app.zip, we find the Flask application source code. The main file is app.py. Key findings in app.py: Flask secret key:
app.py
  • This could be useful for session manipulation if needed.
Hidden endpoint:
app.py
  • There’s a /run_code endpoint that accepts JavaScript code via POST request.
  • It uses js2py.eval_js() to evaluate the JavaScript code server-side.
  • This is a potential Remote Code Execution (RCE) vector.

Exploiting js2py RCE (CVE-2024-28397)

The application uses js2py to evaluate JavaScript code. A quick search reveals CVE-2024-28397 — a sandbox escape vulnerability in js2py that allows arbitrary Python code execution. Reference:

Testing the Endpoint

Let’s first verify the endpoint works without authentication:
HTTP Request
HTTP Response
  • Nice! The endpoint is accessible and evaluates our JavaScript code.

Building the Exploit

The CVE-2024-28397 exploit uses JavaScript prototype pollution to escape the sandbox and access Python’s subprocess module. Here’s the exploit payload structure:
This payload:
  1. Accesses Python’s object model through JavaScript prototype chain
  2. Traverses Python’s class hierarchy to find the subprocess.Popen class
  3. Executes a shell command using Popen

Getting a Reverse Shell

Let’s set up a listener and send a reverse shell payload:
Attacker Linux
Now we send the exploit with a reverse shell command:
HTTP Request
We successfully receive a reverse shell:
Terminal Output
Victim Linux
Terminal Output
  • We have a shell as the app user.

Post-Initial Enumeration (as app)

Finding Credentials in the Database

Let’s check the Flask application directory for the user database:
Victim Linux
Terminal Output
The instance directory typically contains the SQLite database:
Victim Linux
SQLite Console
  • We found two users: marco and app.
  • Both have MD5 password hashes.
Let’s check /etc/passwd to see which users have shell access:
Victim Linux
Terminal Output
  • Both users have valid shell accounts.
  • Let’s focus on marco as they’re likely the primary user.

Cracking the Hashes

Let’s crack marco’s MD5 hash using hashcat:
Attacker Linux
Terminal Output
Credentials:
Terminal Output

Logging in as marco

Let’s use SSH to get a proper shell as marco:
Attacker Linux
Terminal Output
  • User flag: 54e94cff6a20dbb93844ad2e0a8ca4ad.

Privilege Escalation

Post-ex Enumeration

Let’s list the contents of marco’s home directory:
Victim Linux
Terminal Output
A few interesting findings:
  • backups/ directory owned by root with restricted permissions.
  • npbackup.conf configuration file owned by root but world-readable.
  • This looks like a backup tool setup — potentially a cronjob or service running as root.
Let’s check our sudo privileges:
Victim Linux
Terminal Output
  • Interesting! We can run /usr/local/bin/npbackup-cli as root without a password.

Abusing npbackup-cli for Privileged File Read

Let’s explore the intended privilege escalation path using the npbackup-cli binary.

Understanding npbackup

First, let’s try running npbackup-cli:
Victim Linux
Terminal Output
  • It requires a configuration file to run.
  • We already have one in marco’s home directory: npbackup.conf.

Reviewing the Configuration File

Let’s examine the existing configuration:
Victim Linux
The configuration file contains encrypted repository URI and password, plus backup settings:
npbackup.conf snippet
  • The default configuration backs up /home/app/app/ to the repository.

Testing with the Default Configuration

Let’s run a backup with the existing configuration:
Victim Linux
Terminal Output
  • The backup runs successfully as root.
  • Since it runs as root, we can modify the configuration to back up privileged directories.

Backing Up /root

Let’s create our own configuration file to back up /root:
Victim Linux
We modify the paths section:
Now let’s run a backup of /root:
Victim Linux
Terminal Output
  • Successfully backed up /root.

Listing Snapshots

Let’s verify our snapshot was created:
Victim Linux
Terminal Output
  • Our /root snapshot is ID 844bc0a9.

Dumping Files from the Snapshot

The --dump option allows us to extract files from snapshots. Let’s dump the root flag:
Victim Linux
Terminal Output
  • Root flag: 46e970d8ddc27f5723b1ceb158d3755c.

Listing Root Directory Contents

We can also list all files in the snapshot to find more interesting targets:
Victim Linux
Terminal Output
  • We can see root’s SSH private key is available: /root/.ssh/id_rsa.

Extracting Root’s SSH Key

Let’s dump the SSH private key for persistence:
Victim Linux
Terminal Output
Now we can SSH in as root:
Attacker Linux
Terminal Output
  • We now have a root shell via SSH.

Learning

1. js2py Sandbox Escape (CVE-2024-28397)

The js2py library allows Python applications to execute JavaScript code. CVE-2024-28397 is a sandbox escape vulnerability that allows attackers to access Python’s object model through JavaScript’s prototype chain. By traversing Python’s class hierarchy (__class__.__base__.__subclasses__()), we can find and execute the subprocess.Popen class to run arbitrary shell commands. Applications should never execute untrusted JavaScript code using js2py, especially in versions prior to the security patch.

2. Blind RCE Detection with Reverse Shells

When testing for RCE vulnerabilities, you don’t always get immediate feedback. If you suspect a blind RCE exists (commands execute but no output is returned), immediately try a reverse shell connection back to your machine instead of trying to debug command execution in place. Use busybox nc or other available tools on the target to establish the connection.

3. Credential Hunting in Application Databases

Web applications often store user credentials in local SQLite databases. After gaining initial access, always check for:
  • Application directories (/home/app/app/, /var/www/, etc.)
  • Instance or data folders containing .db files
  • Weak password hashes (MD5, SHA1) that can be quickly cracked with hashcat and rockyou.txt

4. Abusing Backup Tools for Privileged File Read

Backup utilities that run as root can be abused to read any file on the system. When you have sudo access to a backup tool like npbackup-cli, restic, or similar:
  1. Create a custom configuration file pointing to the target directory (e.g., /root)
  2. Run a backup as root using the custom configuration
  3. Use the tool’s restore/dump functionality to extract specific files from the snapshot This technique works even if you can’t directly read the files due to permission restrictions.

Tags

Initial Access

#Web_Exploit #Python #js2py #CVE-2024-28397 #Sandbox_Escape #RCE #Source_Code_Review #Credentials_Hunting #Hash_Cracking

Privilege Escalation

#Sudo #Backup_Abuse #Privileged_File_Read #npbackup #SSH_Keys
Last modified on February 17, 2026