lesson_07.md 2.8 KB

Computer Security - lesson 7

Stefano Zanero

14 April 2016

ASM function call

ESP and EBP registers delimit the current location of the stack, they point to the frame of activation The call intruction saves the current EIP on the stack, The equivalent instructions to call 0x8048484 <foo> are:

push %eip
jmp 0x8048484 ~foo()

The difference with the sole call of jmp is that the call saves the current state of EIP to return to it later. After the jump the stack allocation is done:

  • Save the EBP on the stack
  • Set the net EBP to current ESP
  • Allocate space on the stack incrementing ESP

    push %ebp
    mov %esp, %ebp
    sub %0x4, %esp
    

    To view this result I should disable the optimization with -O0 and -preferred-stack-boundary=2 turning off some optimization that store multiple (short) variables per stack word. Before the function return, the return value is moved into EAX The return from function is made with the leave op

    mov %ebp, %esp
    pop %ebp
    ret
    

    That deallocates the current stack, and the ret op pops the last value on the stack to EIP to restore it.

Stack Smashing

Suggested reading: Smashing the stack for fun and profit This works in C because it doesn't do memory management for you like Python or Java If we have a code like this

char buf[8];
gets(buf);

And we input during execution a sequence longer than 8 we get a segmentation fault That is actually raised by the jmp op trying to jump to a meaningless position in memory, since we overwritten EIP that was stored on the stack, by growing the heap. Maybe it would have been enough to overwrite the return value wothout overwriting EBP and EIP, and that is another security vulnerability itself.

To jump to any function i would need to setup the parameters correctly on the stack. I can also jump into a function of a library loaded into memory This is called return to library or in particular return to libc. Also the environment variable loaded with a program are stored on top of the stack always in the same place, so i can put code in there and jump to it. Requirement for stack smashing:

  • The size of the buffer is not checked
  • Overflowed buffer has enough room for code Also we need to know at what address the stack is

Get the address of the stack

We can use a debugger to stop the execution before the vulnerability and get the address of memory where ESP is stored On our own machine i can use a code to print to screen the position of ESP (see slides) The debugger method is not so reliable because some debuggers like gdb add an offset to allocated memory. We can reduce the need of precision filling the heap area with nop forming a nop sled that make the processor go through to the right exploit code. This is a measure to make the exploit work reliably on remote machines, ans this is part of weaponizing an explloit