I've been working on Buffer-Overflow Vulnerability Lab from SEED (Lab Description and Tasks). The environment is Ubuntu 12.04 32 bit. Please consider the following code:

/* stack.c */
/* This program has a buffer overflow vulnerability. */
/* Our task is to exploit this vulnerability */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int bof(char *str)
    char buffer[24];
    /* The following statement has a buffer overflow problem */
    strcpy(buffer, str);
    return 1;
 int main(int argc, char **argv)
    char str[517];
    FILE *badfile;
    badfile = fopen("badfile", "r");
    fread(str, sizeof(char), 517, badfile);
    printf("Returned Properly\n");
    return 1;

I found that in order to overwrite the return address we would have to overwrite the array starting from 36th place because we would have to jump 24 bytes (the size of the array) plus 4 bytes (for the previous frame pointer) plus 8 bytes for the some compiler data (not specified for what purpose). I calculated this with the difference of the EBP and the address of the buffer (using the debugger).

I realized that in order to jump to the malicious code we can jump to any address on the NOP sled. For a sufficiently large value the attack succeeded. I tried to calculate the minimum possible address. The logic (and the lecturer) said it was EBP + 8 because we wanted to pass both the return address and the previous frame pointer (4 bytes each). Unfortunately the attack did not succeed when I tried to run it with that value. I found through an exhaustive search that the minimum possible address is 0xBFFFF168, which is EBP + 48, and I do not understand why. I even tried to run the attack without the NOP sled and encountered problems.

Can someone please explain? Below there is a description of the stack before and after the overrun and some additional values.

Thank you very much in advance.

14        strcpy(buffer, str);
(gdb) x/20x $sp
0xbffff100:    0x0804b008    0xbffff157    0x00000205    0xb7e34374
0xbffff110:    0xb7fc4ff4    0xb7fc4ff4    0x00000000    0xb7e1f900
0xbffff120:    0xbffff368    0xb7ff26b0    0x0804b008    0xb7fc4ff4
0xbffff130:    0x00000000    0x00000000    0xbffff368    0x080484ff
0xbffff140:    0xbffff157    0x00000001    0x00000205    0x0804b008
(gdb) next
16        return 1;
(gdb) x/20x $sp
0xbffff100:    0xbffff118    0xbffff157    0x00000205    0xb7e34374
0xbffff110:    0xb7fc4ff4    0xb7fc4ff4    0x90909090    0x90909090
0xbffff120:    0x90909090    0x90909090    0x90909090    0x90909090
0xbffff130:    0x90909090    0x90909090    0x90909090    0xbffff168
0xbffff140:    0x90909090    0x90909090    0x90909090    0x90909090
(gdb) p &buffer
$1 = (char (*)[24]) 0xbffff118
(gdb) p $ebp
$2 = (void *) 0xbffff138
(gdb) p $sp
$3 = (void *) 0xbffff100
  • 2
    can I see your attack? :) whats your actual POC, might be able to help if I see some exploit code :P will make more sense to me
    – TheHidden
    Feb 27, 2018 at 10:55
  • How do you compiled your vulnerable program ? Keep in mind that, the stack organization strongly depends on your compiler and optimization it achieves. This stackoverflow question may help you.
    – binarym
    Mar 16, 2018 at 17:13

1 Answer 1


The actual size of the stack depends greatly on compiler optimizations, and be affected by the presence of the debugger. In this case, minimizing the stack to ebp+8 isn't necessary, so I wouldn't overthink it.

Keep in mind that counting on stack organization to be the same run to run isn't a realistic exploit scenario anymore. In more realistic scenarios, you will be tasked with bypassing Nxbit/dep and ASLR, so counting on your exploit code to be somewhere in particular you can jump to wont cut it anyway.

If you want a NOP-sled free version of the attack, I would instead focus on finding a way to disclose an address without crashing the program. In such a small example, that may not be possible.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .