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.