Stack Warmup #5: Solution! – Part 1
May 17, 2010
At the begginning I got the impression that abo#5 will be a pice of cake.. so I sat on this for a couple of weeks confident in my prediction.
Today I picked it up just for noticing that I was WRONG! Abo #4 and Abo #5 are really difficult, and 5 “requires” 4′s solution. Today, I’m gonna solve Abo #5, well… I’ll try to give the basic ideas for my solution and on part 2 I’ll complete the explanation
/* stack5.c *
* specially crafted to feed your brain by gera */
int main() {
int cookie;
char buf[80];
printf("buf: %08x cookie: %08x\n", &buf, &cookie);
gets(buf);
if (cookie == 0x000a0d00)
printf("you lose!\n");
}
Where is the “you win!” string? It says you lose! There are not way to win!!!!! Wait, we are trying to be hackers so we should think a path to print you win!
What have we done to solve Abo #4? We has changed the return’s address to make the program to jump inside the if. This time, may be there are other options but my thought is calling the printf function but changing their arguments to print “You win!” instead of “you lose!\n!”.
First of all, I propose to make a list with all the steps required:
- Fill the buffer with some information
- Change program’s flow to jump to printf with the desired parameters.
- Continue Execution
Changing program’s flow is the complicated step, so we need to have a perfect understanding of what’s going on with the stack pointers (ebp, esp) and return address. To make the perfect understanding, take a look at asm stack5′s code:
.file "stack5.c" .section .rodata .LC0: .string "buf: %08x cookie: %08x\n" .LC1: .string "you lose!" .text .globl main .type main, @function main: pushl %ebp movl %esp, %ebp subl $96, %esp leal -4(%ebp), %eax movl %eax, 8(%esp) leal -84(%ebp), %eax movl %eax, 4(%esp) movl $.LC0, (%esp) call printf leal -84(%ebp), %eax movl %eax, (%esp) call gets movl -4(%ebp), %eax cmpl $658688, %eax jne .L2 movl $.LC1, (%esp) call puts .L2: movl $0, %eax leave ret .size main, .-main .ident "GCC: (Gentoo 4.3.4 p1.0, pie-10.1.5) 4.3.4" .section .note.GNU-stack,"",@progbits
The normal program’s flow takes us to execute a leave and then a ret instruction to finish our program. We need something different, don’t terminate just jump to “call printf” instruction with a different parameter: a pointer to “you win!” string.
Time to explain what do clean and ret do
leave instruction
On a normal program execution, leave is executed before a ret instruction. Her work is let the stack as it was before entering to the current function (thinking our program as a function: int main() { … }). So the example here imagines a running program on some state:
It is important to imagine that we are restoring the stack as it was before our program was called, because ret is gonna call the next instruction where our program was invocated. Our flow control will change here the stack and set our desired stack with leave… And ret will… (continue reading if you can’t imagine)
ret instruction
This ret instruction is useful to change the instruction pointer, to jump to other function usually. How does it works on some state:
Recapitulate our idea, we are going to change program’s flow using the buffer overflow to write over the “previous ebp” and the ret address, to make the program jump the place we want (printf with the specified parameter).

