I have a code snippet which has the classic strcpy vulnerability

int main(int argc, char argv[][]){
    char buffer[8];
    strcpy(buffer, argv[1]);

By disassembling the binary file, we can see rsp is decreased by 0x10 bytes (=16)

So we can actually overwrite the rbp after 16 bytes and return address after 24 bytes. Before the function returns, rax is pointing to the beginning of our shellcode.

Here is my approach to attacking the program. Our shellcode will be in the following format

"A"*16 + "B"*8 + "C"*8

As ASLR is enabled, I replaced return address to an address of jmpq *%rax, so the payload will now become

"A"*16 + "B"*8 + "\x77\x04\x40"

and by stepping through in gdb, I can see execution is being directed to the beginning of "A"s. However, the buffer is too small to put in a (system(/bin/sh)) shellcode. What am I supposed to do here?

Here is what I am thinking:

  1. Use egghunter approach. However, I am not able to send more than 24 bytes data to the application, as the return address include null bytes, it terminates my shellcode.

  2. Find a shellcode that is smaller than 24 bytes for 64 bits Linux. (I guess this is not possible)

  3. ROP approach, however, ASLR is enabled, I can't figure out the base address of libc

I have read through many tutorials and most of them have a big buffer like char buffer[500] instead char buffer[8]. It will be great if someone can guide me to the right place.

  • 2
    The problem isn't the 24 bytes limit. If you send it more bytes, those bytes would still end up somewhere on the stack that you can call through jmpq instruction. However, execution from stack is disabled due to DEP. In order to bypass ASLR, you need a memory leak which can point to a system library and from there to construct the ROP.
    – void_in
    Commented Aug 30, 2015 at 12:35
  • @void_in Thank you for your reply and it seems like I cant send more than 24 bytes, because return address have to be 0x0000000000400477 . If I send more bytes after \x77\x04\x40, I will not able to run jmp eax instruction. And I guess DEP is disabled in my case
    – user50312
    Commented Aug 30, 2015 at 12:37
  • Similar Question here : security.stackexchange.com/questions/42852/…
    – user50312
    Commented Aug 30, 2015 at 12:39
  • 3
    3 years later, but in case someone comes across. There are other places where you could store your shellcode (argv[2], envp[]).
    – domen
    Commented Aug 14, 2018 at 14:01
  • 3 years later, @domen is right. Just need to be creative and find some place to store shellcode in the memory
    – user50312
    Commented Nov 30, 2018 at 4:28

1 Answer 1


There are multiple possible ways around this, it's just a matter of being creative.

Here are some things you could try:

  • If you know your current libc's version, you could find a one-gadget with constrains meeting your register values.

  • Also, if you know your current libc's version, there should be enough size for a small shellcode that overwrites the least significant bytes for the strcpy()'s GOT entry to point to system() instead.

  • There is a nice 23 bytes long 64 bits Linux shellcode you could use here: https://www.exploit-db.com/exploits/46907.

  • Depending on the way this binary was compiled, there might be just enough gadgets for you to build a 1st stage ROP chain that increases your buffer size before jumping back to strcpy() to get the rest of the payload from the stack.

I hope this few examples shed some light on the endless possibilities you have here.

You must log in to answer this question.