This box was created by ‘rastating’.
Let’s start the journey!
I added the ip[10.10.10.58] of the box to /etc/hosts as ‘node.htb’
Enumerations
First, let’s do the nmap scan.
nmap -A -sC -sV -Pn node.htb > nmap.scan
Open ports are : 22, 3000
Let’s go and see what’s in the HTTP Apache server running in port 3000
We can’t run gobuster
or dirb
or other, because the machine blocked those with some type of filtering methods.
Let’s use burpsuite
to crawl the website and see if it finds something.
So, the burp found some interesting things. Let’s look at the /api/users/ directory.
And, we got a list of possible user accounts and also an admin account. INTERESTING!!
All the passwords here are hashes. Let’s decrypt those. We can use Crackstations or hashes.com
And after decrypting the hashes we get :
Let’s log in with the admin account.
Download the backup file. [Sometimes it gives an error when downloading the file, but I bypassed with the burp proxy on (intercept off)]
It requires a password to unzip it. We can try the brute-force method.
fcrackzip
will do the trick here.
So, the password is ‘magicword’.
Unzipping it gives us a folder named ‘var’ which has the full source code of the myplace web application. We can now analyze the code and let’s see if we can find something interesting.
Getting Shell — mark
In app.js
file, we find mongo-db credentials for user mark.
And, user mark used the same password for his ssh.
From /etc/passwd
, we see that another user is ‘tom’ .
To get the user flag we need to get access to tom’s account.
Let’s run LinEnum. Using the python HTTP server I transferred the LinEnum.sh file to the machine.
LinEnum gave us some interesting things to look at.
First, we see all the users in the system and second, in the process/service section, we see that a node service is compiling a file named /var/scheduler/app.js.
After analyzing the systemd scheduler service file, we see that it’s a mongo-db process/task scheduler. and it restarts every 3 sec.
Let’s analyze the /var/scheduler/app.js
file.
Okay. Basically, we can see that the service executes a command from a document in the tasks list and delete it later to stop it being executed again.
And, it is using the same credentials as before and we can access the scheduler db with user mark
.
So, we can edit and put a reverse shell command that will give us shell as tom [Because TOM is the user running that service ].
# Getting Shell(privesc) — TOM
Set up a netcat
listener in the attacker machine, in the victim machine, log in to the mongo and access the scheduler db as mark, put the reverse shell command there, and wait for it to execute. Simple as that.
I don’t know much about mongo-db and its commands. So, yeah..Documentations.
The documentation is pretty clear about how to interact with the db. So, I will use `db.tasks.insert()` to insert a document with a command inside. and that’s it.
We have a shell as TOM now. However, working on this shell is a real pain, it doesn’t have the usual tab completion, up-down arrow key doesn’t work, basically, it’s not a proper shell that we are used to. So, let’s change that first.
So, the shell is upgraded.
Now, we can read the user flag from user.txt file.
Now, that’s done, we have to look for some way to privesc to root.
PrivEsc — ROOT
I am gonna check for SUID files —
Here, we can see that the backup binary is owned by root
and the admin
group has the permit to run it. and the user tom
is also a member of the admin
group.
If we remember correctly, the /var/www/myplace/app.js
file contains a function that uses this backup binary file.
As we can see, the binary needs 3 arguments — ./backup -q <the_backup_key> < a directory >
Using ltrace
on the binary we get to know the allowed ‘backup keys’ for the binary.
/etc/myplace/keys
The /etc/myplace/keys
file also has a newline at the and so, ‘ ’ also a valid key.
After running `backup -q ‘ ‘ /root` it gives us a base64 string. Decoding that will give us a zip file. I extracted the files from the zip file [password : magicword], and we get a root.txt file.
It’s a troll face.
Okay, so there is a problem. Let’s analyze the binary again with ltrace
.
There is a strstr
function check and the below image explains what strstr() does.
That means ‘/root’ or ‘root’ is filtered.
If I run it on /tmp directory, it reveals more filters —
Now, one interesting thing here as you can at the last line, there is a strcpy() function. And strcpy is known to be vulnerable to Buffer Overflow.
read here — https://man7.org/linux/man-pages/man3/strcpy.3.html
Buffer OverFlow
To test the BoF, we need to copy that binary file in to our machine.
and I also created a /etc/myplace/keys
file..with a blank key there.
Now, let’s run the binary in our machine. and Test the BoF in the ‘directory argument’.
Okay..There is a BoF.
First checking the protections are enabled -
NX is enabled, so we can’t just put something on memory stack and execute it. And also, we see that the ASLR is on -
This means we need to do a ret2libc
attack.
Let’s open it with gdb[I am using gdb-pwndbg; [You can use your fav one.]
gdb-pwndbg ./backup
Checking the available functions -
Okay. Here are the steps for this
ret2libc
attack —
1. Find the Offset
2. Find the base address of LIBC
3. Find the offset addresses for the system, exit and /bin/sh
4. Add (2+3) to get the system, exit and /bin/sh addresses respectively.
5. To bypass this ASLR, we can use brute-force method.
6. Execute the script and wait.
First, finding the offset -
We can use cyclic
in gdb-pwndbg
to create a long pattern.
So the OFFSET = 512
Now, the libc
base address -
Because of the ASLR, the libc address changes every time but look closely — the address always starts with 0xf7 and ends with 000 . So, only the middle 3 values change.
So, we can grab one of the addresses, and later use it in the brute-force method because the address will be used again when the exploit runs multiple times.
libc_base = 0xf756c000
now, the system
, exit
, and /bin/sh
offset addresses -
Now, let’s write the script — [In python]
And when we run the script `python3 exp.py` —
Unintended methods to get root
There are also some unintended methods like using Wildcards, Command injections, Symlinks etc but I wont be discussing those in here. I just wanted to discuss the Buffer OverFlow method and about `ret2libc` attack.
You can find the other methods here -
rastating(Official), Oxdf, Rana Khalil and Ippsec
I hope, now you have a fair understanding of the concept discussed above.