This box was a fun way to learn about how JWT works and why you should be extremely paranoid when uploading code.
Recon is the standard nmap scan: nmap -sT -sV -v -O -p - -n <target ip> with a pretty standard result of ports 22, 80, and 3000.
We can ignore 22 (as it's almost never of any interest) and checkout port 80. It shows the docs page for an API. Reading through reveals the API runs on port 3000. Further reading shows how to create a user, authenticate, and test connections.
Near the bottom of the page is a link to download a zip of the source code. The source code reveals a .git directory, which shows the git history where the author removed a secret from .env. We can find the author's GitHub by going to their website -> Projects (top menu) -> "view more projects in my Github"
Navigating to the Github repo (auth-api), we can see the commit changes, where one is commented "Updated .env". Checking it out reveals a previously redacted token secret. This secret is used to sign JWT tokens used to authorize users.
Going to JWT.io, we can create a token with the values "name":"theadmin" (). We only need this one value because in the source code, under routes/private.js we can see that the only admin verification is the name.
We can verify our admin status with:
Once we have admin, we can exploit the /logs path (found in routes/private.js of the source code) to inject code and get a reverse shell. The code looks for the "file" parameter in a GET request and inserts it into a git command. We can exit the git command and writre any command we want. Start a netcat listener and using curl, call the API with the code injection (remember to change the IP at the end!):
Once we get the connection back, we can see we're logged in as "dasith", indicating we are a normal user (as compared to the normal "www-data" web user). Get the user flag from /home/dasith/user.txt
After getting user, we can look for SUID binaries  and find one in /opt named "count". This binary will read a file and show information on it such as the numberof characters. To get root we need to let it read a target file (in this case "/root/root.txt"), crash it, then read the core dump to find the contents of the target file .
In order, we need to:
After that jsut submit and party!
JWT builder [EXTERNAL]
SUID Core Dump [EXTERNAL]
Last edit: 2022.02.27