Gera's Insecure Programming Advance Buffer Overflow #3
This exercise is compiled on Debian 2.6.32 with NX and ASLR enabled. However, those
protections do not effect the difficulty of the exercise. Exploiting this challenge could have been performed with or without those protections.
ABO #3 source code:
{% highlight c %}
/* abo3.c *
- specially crafted to feed your brain by gera */
/* This'll prepare you for The Next Step */
int main(int argv,char **argc) {
extern system,puts;
void (fn)(char)=(void()(char))&system;
char buf[256];
fn=(void(*)(char*))&puts;
strcpy(buf,argc[1]);
fn(argc[2]);
exit(1);
}
{% endhighlight %}
It may seem that a straight-forward buffer overflow is possible; however, this is not the case due to exit(). The exercise takes two user arguments. The binary will display the second user argument using puts(). Exploiting this challenge requires the need to overwrite a function pointer to avoid the exit() "restriction." If the function pointer fn is overwritten with the address to system(), the second argument will be used as system()'s argument.
{% highlight bash %}
lixor@debian:~/InsecureProgramming/abo3$ ./abo3 AAAA BBBB
BBBB
{% endhighlight %}
The functions puts() and system() are compiled into the binary. Since the function pointers (puts()/system()) are declared (extern), the pointers to system() and puts() can be found in the disassemble during assignment or from within gdb.
Modified output of objdump -M intel -d abo3. The full dump can be found here
{% highlight bash %}
..snip..
8048480: c7 84 24 1c 01 00 00 mov DWORD PTR [esp+0x11c],0x8048364
8048487: 64 83 04 08
804848b: c7 84 24 1c 01 00 00 mov DWORD PTR [esp+0x11c],0x8048394
8048492: 94 83 04 08
..snip...
{% endhighlight %}
In the snippet above, the instructions are assigning system and puts to fn. The addresses 0x8048364 and 0x8048394 are system() and puts(), respectively. When you look at the source code, the function pointer fn was assigned two values; first assigned to system() followed by puts().
The next issue is to determine the offset between buf and fn.
This is a modified output of gdb (using mammon_'s .gdbinit) while stepping through the binary.
{% highlight bash %}
lixor@debian:~/InsecureProgramming/abo3$ gdb -q --args ./abo3 AAAA BBBB
..snip (stepped through program until function pointer is called)..
eax:BFFFF669 ebx:B7FCCFF4 ecx:00000000 edx:00000005 eflags:00200282
esi:00000000 edi:00000000 esp:BFFFF300 ebp:BFFFF428 eip:080484B9
cs:0073 ds:007B es:007B fs:0000 gs:0033 ss:007B o d I t S z a p c