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—–
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
—–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 |