简体   繁体   中英

32 bit intel stack frame format string exploit

I have a program that looks like this

Test program:

#include <stdio.h>

void foo(char *input)
{
    char buffer[64];
    strncpy(buffer, input, sizeof(buffer));
    printf(buffer);
}

int main(int argc, char **argv)
{
    foo(argv[1]);
}

I compile my program with all stack related protection turned off.

gcc fmthck.c -w -m32 -O0 -ggdb -std=c99 -static -D_FORTIFY_SOURCE=0 -fno-pie -Wno-format -Wno-format-security -fno-stack-protector -z norelro -z execstack -o hacks

sudo sysctl -w kernel.randomize_va_space=0

Then I supply the compiled program with the following arguments:

./hacks "AAAA %p %p %p %p %p %p %p %p %p %p"

And I get an output that looks like this

AAAA 0xffffd3cb 0x40 0x8048d3c 0x41414141 0x2e702520 0x252e7025 0x70252e70 0x2e70252e 0x252e7025 0x70252e70

I know that A=0x41 in HEX. So I'm guessing that the starting address of the buffer corresponds to the 4th %p. I was just wondering what the stuff around it means . I was given a stack diagram that looks like this. I know that 0x8048d3c corresponds to the return address but some things don't line up

High Memory Address

  • Input parameters
  • Return Address
  • Saved Frame Pointer
  • Local Variables
  • Saved Registers

Low Memory address

Could someone please elaborate on what is happening to the stack as I do this?

If you compile your program with option -S, the compiler will generate assembly output which you can examine. In your case, the relevant generated code is:

foo:
    pushl   %ebp
    movl    %esp, %ebp
     subl    $88, %esp
    movl    $64, 8(%esp)
    movl    8(%ebp), %eax
    movl    %eax, 4(%esp)
    leal    -72(%ebp), %eax
    movl    %eax, (%esp)
    call    strncpy
    leal    -72(%ebp), %eax
    movl    %eax, (%esp)
    call    printf

Your output was

    AAAA 0xffffd3cb 0x40 0x8048d3c 0x41414141 0x2e702520 0x252e7025 0x70252e70 0x2e70252e 0x252e7025 0x70252e70

which has to be interpreted as a piece of system stack at the moment of invocation of printf . The meaning of the output is:

AAAA       == string from argument printed by printf
0xffffd3cb == garbage left from previous function invocation, in fact the input argument argv[1] previously sent to `strncpy`
0x40       == garbage left from previous function invocation, in fact it is the constant 64 previously sent to strncpy
0x8048d3c  == ??? I don't know why gcc left this unused space.
0x41414141 0x2e70252 ... is the content of local variable `buffer` which contains the string "AAAA %p %p %p %p %p %p %p %p %p %p".

Return address from your function as well as saved base pointer are beyond your output.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM