On my summer holiday, I have spent a couple of day to learn pwnable at protostar where has interesting challenges. With newbie, i believe that if you try to follow from Stack 0 to Stack 5 (i wanna more, but now i haven’t finished all of them), you will got steady base about Stack and have plan to dig deeper for the Buffer over Flow technique in the future.
After reading my previous articles, you know my English is too terrible. I will try with my best, and blogging is one of my efforts to improve my English.
Here we go,
STACK 0
This is the first (easiest, too) level. They’ve given us a piece of code:
Our goal is modify modified’s value through gets(buffer) function. “Sound fabulous, how can i change this variable’s value when i cant touch it ?”. However, when you use gdb to debug that file, you will recognize that buffer’s address is just below modified’s address in STACK. So, if we overload the buffer, the leftover will overwrite modified => the payload we need in this level is a string contains 70 * A (try more if you want).
STACK 1
In this challenge, we have a code which is much the same as previous one.
123456789101112131415161718192021222324
/* stack1.c */
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
volatile int modified;
char buffer[64];
if(argc == 1) {
errx(1, "please specify an argument\n");
}
modified = 0;
strcpy(buffer, argv[1]);
if(modified == 0x61626364) {
printf("you have correctly got the variable to the right value\n");
} else {
printf("Try again, you got 0x%08x\n", modified);
}
}
Not only overload buffer, we need make modified’s value same as 0x61626364 (equal to dcba in ascii).
Cuz the execute environment belongs to Little Endiance system, so you must pack(‘<I’, targetvalue)
In the end of this piece of code, the program call the function which has address stored in fp ’s value. So, how to force the program to call win function ? The first thought is overwrite win ’s address to fp value.
This piece of code is so brief. Same idea as Stack 3, we must change code flow to win function, however there is no fb for us overwrite.
It’s time for EIP.
When disassembly main function, we have:
123456789101112131415
➜ gdb -q stack4
Reading symbols from stack4...done.
gdb-peda$ disass main
Dump of assembler code for function main:
0x08048408 <+0>: push ebp
0x08048409 <+1>: mov ebp,esp
0x0804840b <+3>: and esp,0xfffffff0
0x0804840e <+6>: sub esp,0x50
0x08048411 <+9>: lea eax,[esp+0x10]
0x08048415 <+13>: mov DWORD PTR [esp],eax
0x08048418 <+16>: call 0x804830c <gets@plt>
0x0804841d <+21>: leave
0x0804841e <+22>: ret
End of assembler dump.
gdb-peda$
After leave instructor in *main+21, the program will call the function which has address equal to EIP register’s value. The easiest way to pass this level is overwrite EIP.
First of all, we need EIP ’s offset. Try inject AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1234567
There is not win() function, just two line for initialization and read input. “Have you ever forgetten copying some thing ?”
Don’t worry, it is the great chance for us to make friend with shellcode.
We should overwrite EIP (using technique from previous challenge) in order to redirect program execution to our shellcode, which also was injected to input data.