Month: November 2021
htb-secret-nl
Hackthebox Secret writeup
Introduction@Secret:~$
| Column | Details |
|---|---|
| Name | Secret |
| IP | 10.10.11.120 |
| Points | 20 |
| Os | Linux |
| Difficulty | Easy |
| Creator | z9fr |
| Out On | 30 Oct 2021 |
Pwned
➜ Secret git:(master) ✗ ssh root@Secret.htb root@Secret.htbWelcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.0-26-generic x86_64) System information as of Thu 21 May 2020 06:11:30 AM UTC System load: 0.07 Usage of /: 46.0% of 15.68GB Memory usage: 13% Swap usage: 0% Processes: 218 Users logged in: 2 IPv4 address for br-836575a2ebbb: 172.20.0.1 IPv4 address for br-8ec6dcae5ba1: 172.30.0.1 IPv4 address for docker0: 172.17.0.1 IPv4 address for eth0: 10.10.11.120 Last login: Thu May 21 06:11:12 2020 from 10.10.XX.XX root@Secret:~#
Nmap
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.
I think it’s a source code of the api endpoint. first i check the .env file because in every project all creds 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.
I use gitTool extractor for that you can use any other tool which you like.
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
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.
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.
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.
hmm we register as theadmin but there is space in front of the username. let’s try to login with that creds and get the jwt token.
we got the jwt token let’s check on /priv endpoint that we are admin or not.
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.
Link: JWT
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.
i try to get the /etc/passwd file but i can’t. let’s try with semicolon.
Boom we got rce let’s try to get the rev shell.
First let’s create a file called rev.sh inside that file add bash rev shell and start the python3 server.
Before calling the file and pipe it over to bash start your netcat listner on 9001.
Boom we got the shell and get the user.txt file.
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.
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: PRCTL
Link: Apport
Link: 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
Now let’s go to /var/crash directory.
Now we need to convert this crash file into coredump file using apport-unpack.
Now let’s check the /tmp/dump directory.
Let’s strings the CoreDump file and check if there is any id_rsa of root.
And we got the id_rsa of root.
┌──(kali㉿puckie)-[~/htb/secret]
└─$ cat id_rsa
—–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—–
id_rsa_root
Now let’s ssh in and get the root.txt flag.
And we pwned it …….
root@secret:~# crontab -l
# Edit this file to introduce tasks to be run by cron.
#
--snip--
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
#@reboot sh -c 'cd /home/dasith/local-web/ && pm2 start /home/dasith/local-web/index.js'
root@secret:~#
Resources
| Topic | Url |
|---|---|
| JWT | https://jwt.io/ |
| PRCTL | https://man7.org/linux/man-pages/man2/prctl.2.html |
| Apport | https://wiki.ubuntu.com/Apport |
| CrashReporting | https://wiki.ubuntu.com/CrashReporting |