THM: UltraTech

This box turned out to be a great reminder that APIs + poor input validation can quickly turn into full system compromise. What started as a simple web app ended with a Docker-based root shell — all because of a single exposed endpoint.

NMAP

Two web services immediately stood out:

  • 31331 → Apache-hosted website
  • 8081 → Node.js / Express API

That usually means logic lives in the API.

HTTP (31311)

Visiting port 31331 showed a generic corporate-style website.

Nothing interesting stood out during manual browsing, so I ran Gobuster.

This revealed a login page. Attempting to log in redirected the request to the API running on port 8081 — confirming the frontend was just a wrapper.

Time to pivot.

API (8081)

At first glance the API only exposed authentication functionality. I ran an API wordlist to check for hidden endpoints and found something interesting:

The /ping endpoint consistently returned server errors. Burp showed that the browser itself was making requests to this endpoint.

Testing the endpoint manually without the frontend confirmed it was executing a system ping command.

That immediately raised a red flag.

Exploitation — OS Command Injection

Since the API was directly executing system commands, I started testing for OS command injection. After some trial and error, newline characters (\n) worked as a command separator.

At this point I had command execution. Using that access, I searched the filesystem and found a database containing two user password hashes.

I cracked them using CrackStation.

SSH Access

Using the recovered credentials, I logged into the web app and was greeted with this message:

Hey r00t, can you please have a look at the server’s configuration?
The intern did it and I don’t really trust him.
Thanks!

That was a pretty clear hint.

I tried SSH using the cracked credentials — and it worked.

Privilege Escalation

Running id showed something important, the fact that i was part of the docker user group. At first, I assumed I was inside a Docker container and wasted some time trying to escape it — a wrong assumption that cost me time. Eventually I realized the real issue:

👉 The user was a member of the Docker group.

Docker group membership is effectively root. Using the technique described by Securitum, I spawned a root shell by mounting the host filesystem:

Root access achieved.

Learning Notes

  • OS command injection is still very real — especially in internal APIs.
  • Newline characters can bypass simple filters.
  • Docker group membership equals root access.
  • Always verify assumptions — not every Docker-related issue is container escape.

Final Thoughts

This box was a solid example of how small API design mistakes can lead to full compromise. No fancy exploits, no obscure CVEs — just bad input handling and dangerous permissions. Exactly the kind of machine that rewards careful enumeration and thinking things through.