Home
HTB - SECRET

Scanning and Enumeration
Starting with an NMAP scan, we have...nmap -sC -sV --min-rate=1000 $Secret
Starting Nmap 7.92 ( https://nmap.org ) at 2022-01-14 08:33 WAT
Stats: 0:00:02 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan
SYN Stealth Scan Timing: About 70.65% done; ETC: 08:33 (0:00:00 remaining)
Stats: 0:00:08 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 33.33% done; ETC: 08:33 (0:00:02 remaining)
Stats: 0:00:14 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 33.33% done; ETC: 08:34 (0:00:14 remaining)
Nmap scan report for 10.10.11.120
Host is up (0.49s latency).
Not shown: 997 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 97:af:61:44:10:89:b9:53:f0:80:3f:d7:19:b1:e2:9c (RSA)
| 256 95:ed:65:8d:cd:08:2b:55:dd:17:51:31:1e:3e:18:12 (ECDSA)
|_ 256 33:7b:c1:71:d3:33:0f:92:4e:83:5a:1f:52:02:93:5e (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: DUMB Docs
3000/tcp open http Node.js (Express middleware)
|_http-title: DUMB Docs
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
It appears we have two web servers running on this machine. Let's view the first one...Web Server - TCP 80


http://localhost:3000/api/user/register
-- For registering a userhttp://localhost:3000/api/user/login
-- For log inhttp://localhost:3000/api/priv
-- To confirm the privilege and validity of your auth-tokenYou'll also find the link
http://secret.htb/download/files.zip
. A downloadable zip file that contains the source code of the web application.
Let's interact with the second webserver and see what we can find...Web Server (API) - TCP 3000




/api/priv
endpoint. The result is...

Next let's check the source code we downloaded. Looking through it's contents, two things can be found. The first is a JWT_TOKEN SECRET contained in the
.env
file; but first you
have to revert the git repo to a previous commit called "added /downloads". The Token SECRET can be used to sign and create legitimate tokens for the web application.
The second thing is contained in the routes folder in a file called
private.js
which contains the following code...

/api/logs
which takes a query parameter called "file" that is used in an execution to retrieve git information about the file.If there is an improper input validation of the query parameter used to interact with this endpoint it would be possible to perform RCE using this endpoint. But if you look carefully at the code, only an admin can make use of this endpioint to perform an execution. We need to get an admin auth-token before we can make use of this endpoint. Since we have the JWT_TOKEN SECRET we can make a admin auth-token.
To create a JWT token we can use a site called
jwt.io
using it's Debugger. In the Encoded box put in your normal user token so that we can view the contents contained in it's payload. Create a payload
with the same information but change the "name" value to "theadmin". It is best you don't edit the payload contents of your token as you'll be working on an already generated token. A way you can go about this is to
copy your payload, clear the contents of the Encoded box, then paste back the payload and edit it. Finally we need to sign the generated token, paste your JWT_TOKEN SECRET into the Verify Signature box.
The result should look like this...


RCE Through Hidden Endpoint
As we did with all the other endpoints let's create a python script that would help us interact with this one...
COMMAND
in the url to...whoami
-- To get the current user, andcat /home/[user]/user.txt
-- To view the user flagNow, let's get a shell, we know from the "whoami" command that the user running the application is called
dasith
; which is great news as this user is a real user.
Since we have an SSH server running, we should be able to make use of SSH to get a shell. All we need to do is generate our ssh keys
and paste the public key into the authorized_keys
file of the user. Generate SSH keys with the command...

To copy our public key to the authorized_keys file our URL should look like this...
http://10.10.11.120:3000/api/logs?file=local-web;echo [public_key] >> /home/dasith/.ssh/authorized_keys
If this doesn't work properly you can always use CURL
utility to copy it. We can then SSH into the machine...


Privilege Escalation
As usual the first thing to check is for executables that have their SUID bit set...
count
. After executing it, we have...


ps
to obtain the Process-id of the execution so that we can
kill it. Killing it resulted in it's memory being dumped.Now to access the contents of the dumped memory we have to go to the
/var/crash
folder. You should see a file with an extension of ".crash" and in it's name the name of the executable should be present. Next we have to extract
the fields of the report to separate files. This can be done using apport-unpack...

CoreDump
file as asides other things, it contains the memory contents of an application upon crashing. Since it is a binary, we can view the content we want using the strings
utility...
dasith@secret:/tmp/count_crash$ strings ./CoreDump
Congrats, you have the ROOT flag 😁.Although, we have successful gotten the hash for both USER and ROOT, we haven't gotten a root shell yet, and our exploitation is not over. Since we can use the
count
utility to access any file, it means we can access the root user's SSH private key. Perform the same crash and dump operation but this time access the root user's private key...

CoreDump
like we did earlier on we should have the root's private key...

SECRET
using the private key...

Thank you for reading my writeup 😀 | Home