4

I have been playing with some wargames and I ported some of then on my Linux machine as well. I noticed that when not using -mpreferred-stack-boundary=2, gcc might compile "main" with an interesting prologue/epilogue: effectively "relying on $ecx (which relies on $ebp-4) for $esp value before ret". Has anyone else come across this observation?

This means you can not overwrite normal ret address staying at $ebp+4, but instead you have to overwrite $ebp-4 (that is ecx) and reposition the stack pointer and your return address (effectively using a stack pivot) to further the exploitation.

Kindly find an example code and related assembly below:

$ cat stack4.c
/* stack4-stdin.c                               *
 * specially crafted to feed your brain by gera */

#include <stdio.h>

int main() {
    int cookie;
    char buf[80];

    printf("buf: %08x cookie: %08x\n", &buf, &cookie);
    gets(buf);

    if (cookie == 0x000d0a00)
        printf("you win!\n");
}

$ objdump -D ./stack4_normal | grep -A31 main.:
0804845b <main>:
 804845b:   8d 4c 24 04             lea    0x4(%esp),%ecx
 804845f:   83 e4 f0                and    $0xfffffff0,%esp
 8048462:   ff 71 fc                pushl  -0x4(%ecx)
 8048465:   55                      push   %ebp
 8048466:   89 e5                   mov    %esp,%ebp
 8048468:   51                      push   %ecx
 8048469:   83 ec 64                sub    $0x64,%esp
 804846c:   83 ec 04                sub    $0x4,%esp
 804846f:   8d 45 f4                lea    -0xc(%ebp),%eax
 8048472:   50                      push   %eax
 8048473:   8d 45 a4                lea    -0x5c(%ebp),%eax
 8048476:   50                      push   %eax
 8048477:   68 50 85 04 08          push   $0x8048550
 804847c:   e8 8f fe ff ff          call   8048310 <printf@plt>
 8048481:   83 c4 10                add    $0x10,%esp
 8048484:   83 ec 0c                sub    $0xc,%esp
 8048487:   8d 45 a4                lea    -0x5c(%ebp),%eax
 804848a:   50                      push   %eax
 804848b:   e8 90 fe ff ff          call   8048320 <gets@plt>
 8048490:   83 c4 10                add    $0x10,%esp
 8048493:   8b 45 f4                mov    -0xc(%ebp),%eax
 8048496:   3d 00 0a 0d 00          cmp    $0xd0a00,%eax
 804849b:   75 10                   jne    80484ad <main+0x52>
 804849d:   83 ec 0c                sub    $0xc,%esp
 80484a0:   68 68 85 04 08          push   $0x8048568
 80484a5:   e8 86 fe ff ff          call   8048330 <puts@plt>
 80484aa:   83 c4 10                add    $0x10,%esp
 80484ad:   8b 4d fc                mov    -0x4(%ebp),%ecx
 80484b0:   c9                      leave
 80484b1:   8d 61 fc                lea    -0x4(%ecx),%esp
 80484b4:   c3                      ret

I have found several StackExchange topics and explanation about why this happens. Nevertheless, I am looking for a guide/tutorial that specifically deals with the exploitation part. Perhaps someone smarter than me has standardised this exploitation in a much better way than I do.

It seems that most people, in tutorials, just use -mpreferred-stack-boundary=2 to avoid this problem and continue normally with the exploitation tutorial.

I find it hard to believe that no-one has mentioned this in a tutorial as new versions of gcc compile like this by default (at least at my machine).

In any case, the question is:

  • Is this the optimal way to exploit this (using a stack pivot)?

  • If no, can someone please point me to a tutorial or explanation of a better way?

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.