1

I was doing some tests to train myself to ROP when ASLR is ON and NX is enabled.

I created this small program for testing purpose

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char ** argv) {
    char buff[128];

    gets(buff);

    char *password = "I am h4cknd0";

    if (strcmp(buff, password)) {
        printf("You password is incorrect\n");
    } else {
        printf("Access GRANTED !\n");
    }

    return 0;
}

And I compiled it on a 64bits Ubuntu with this command

gcc -o rop rop.c -m32 -fno-stack-protector  -Wl,-z,relro,-z,now,-z,noexecstack -static

When I open the beast in gdb and disassemble the main function, I get the following

0x0804887c <+0>:       lea    ecx,[esp+0x4]
0x08048880 <+4>:       and    esp,0xfffffff0
0x08048883 <+7>:       push   DWORD PTR [ecx-0x4]
0x08048886 <+10>:      push   ebp
0x08048887 <+11>:      mov    ebp,esp
0x08048889 <+13>:      push   ecx
0x0804888a <+14>:      sub    esp,0x94
0x08048890 <+20>:      sub    esp,0xc
0x08048893 <+23>:      lea    eax,[ebp-0x8c]
0x08048899 <+29>:      push   eax
0x0804889a <+30>:      call   0x804f100 <gets>
0x0804889f <+35>:      add    esp,0x10
0x080488a2 <+38>:      mov    DWORD PTR [ebp-0xc],0x80bb388
0x080488a9 <+45>:      sub    esp,0x8
0x080488ac <+48>:      push   DWORD PTR [ebp-0xc]
0x080488af <+51>:      lea    eax,[ebp-0x8c]
0x080488b5 <+57>:      push   eax
0x080488b6 <+58>:      call   0x8048280
0x080488bb <+63>:      add    esp,0x10
0x080488be <+66>:      test   eax,eax
0x080488c0 <+68>:      je     0x80488d4 <main+88>
0x080488c2 <+70>:      sub    esp,0xc
0x080488c5 <+73>:      push   0x80bb395
0x080488ca <+78>:      call   0x804f280 <puts>
0x080488cf <+83>:      add    esp,0x10
0x080488d2 <+86>:      jmp    0x80488e4 <main+104>
0x080488d4 <+88>:      sub    esp,0xc
0x080488d7 <+91>:      push   0x80bb3af
0x080488dc <+96>:      call   0x804f280 <puts>
0x080488e1 <+101>:     add    esp,0x10
0x080488e4 <+104>:     mov    eax,0x0
0x080488e9 <+109>:     mov    ecx,DWORD PTR [ebp-0x4]
0x080488ec <+112>:     leave  
0x080488ed <+113>:     lea    esp,[ecx-0x4]
0x080488f0 <+116>:     ret

It's the first time I have these function prologue and epilogue

Prologue

0x0804887c <+0>:       lea    ecx,[esp+0x4]
0x08048880 <+4>:       and    esp,0xfffffff0
0x08048883 <+7>:       push   DWORD PTR [ecx-0x4]

Epilogue

0x080488e9 <+109>:     mov    ecx,DWORD PTR [ebp-0x4]
0x080488ec <+112>:     leave  
0x080488ed <+113>:     lea    esp,[ecx-0x4]
0x080488f0 <+116>:     ret

Because of these, I need to know ESP value when the main function is called when exploiting the vulnerable binary with ROP, but since ASLR is enabled, it's not possible.

PS : I assure you this is a program I wrote myself for training purpose, it's not part of any challenge or CTF.

Thanks for your time and knowledge :)

2 Answers 2

2

This is not a protection but juste a prologue / epilogue that your compiler will produce. You can check the produced assembly with different versions of gcc right there: https://gcc.godbolt.org/

And in your context, you can control ECX. But what if you just control the last byte only ? Then you might fall on some of your input in the stack.

1
  • Thank you for your answer. That's totally right. I tried to use another compiler and did the following command clang -o rop rop.c -m32 -fno-stack-protector -Wl,-z,relro,-z,now,-z,noexecstack -static and now I have a perfect well know prologue/epilogue :)
    – Hackndo
    Commented Oct 25, 2016 at 8:40
1

While not a part of the official 386 SysV ABI, there is a de-facto requirement that the stack pointer is aligned to 16 bytes at all times when calling system functions (enforced by the de-facto standard compiler (GCC) since several years ago:1,2). That's why the prolog of the main function contains the and esp,0xfffffff0 instruction. Only the main() function needs to do that, other functions usually don't perform stack realignment since they assume they're already called with 16-byte alignment (unless you use -mrealignstack).

So instead of using another compiler you could try putting the vulnerable code in a separate function, not main directly.

1
  • Thanks for this useful information. I already published my article but I'll think about putting the vulnerable code in a separate function.
    – Hackndo
    Commented Oct 26, 2016 at 10:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.