Common Mistakes in Basic Stack Buffer Overflow
This is a Blog to learn about common mistakes newbies make while learning buffer overflow. I have included a section for the anatomy of the stack as well.
Anatomy of stack
I have seen many blogs making mistakes when finding the perfect offset value for overwriting EBP and reaching EIP. People approach this in a brute force manner to get the value. This method does work. But it takes away the actual fun when solving the challenges. It is easy to find the perfect offset value with a bit of calculation and using GDB.
When we execute a binary, there is memory space given for storing the variables and other details. If you have a buffer, this is also created in the stack. Then we have the EBP and EIP. But we missed out on 2 important things here. ESP which is above the variable space and padding between EBP and Buffer or variable space.
Assume buffer size was 64 bytes. EBP and ESP are 4 bytes. So what about padding? That’s when people start to brute force by adding 4 bytes repeatedly to get a segmentation fault error. What people miss out on is the poor EBP and padding. How do we find them?
Let’s see a challenge now. I used a random challenge from the ROP emporium to demonstrate this. Here, I will tell you a direct way to find your offset value without doing the calculation. Use this when you are having a CTF challenge. Saves a lot of time :)
We see “AFAA” in the EIP region. So we try to find this particular pattern in the given input.
There we go, we found the offset value. But what was our buffer size? Here it was a 32 bytes buffer. EBP is 4 bytes. Doing a quick calculation
44(Total) = 32(Buffer) + 4(EBP) + ?(Padding) → Padding = 8 bytes.
So now you know why it takes so much space after the buffer, remember there is always an 8 bytes padding in a 32-bit binary and 16 bytes padding in a 64-bit binary minimum along with local variables. Similarly, EBP is 4 bytes in 32 bit binary and 8 bytes in the 64-bit binary fixed.
BUT WAIT ?? Is this a complete stack ???
NO! We do have many more things in a stack like the local variable, global variable, arguments, etc. Where is it located? I will give an example for arguments.
We do have arguments after the return address that we could specify, We need to give a gap of 4 bytes after return address in 32 bit binary and 8 bytes in the 64-bit binary.
Below Arguments, we have the old stack frame. Also remember, if there are many local variables it gets placed in the stack as well in the order of declaration.
Reference Points
We have seen [ebp-0xc] or [esp+0x10] or could be with any register while disassembling functions. These are nothing but references. ESP and EBP don’t change the value if we set a breakpoint in between functions. Thus they can be used as a reference point while pointing to some variable. Again to calculate this make sure you the value of ESP or EBP. Then do some calculations by converting hex to an integer. This way you’ll know where the variables are. Drawing a stack diagram could make this calculation easier.
Memory Protection and Stack
Memory protection does change the address and structure while executing a binary file. So do check the memory protection before starting with any challenge.
I use “checksec ./binary” which is a part of the pwntools module in python. This lists out all the memory protection in the given binary.
That’s it for this blog. Hope you don’t make these simple mistake while solving a challenge. Don’t brute force to get an answer.
Do leave some claps if you reached here and check out my other blogs too! Follow for more blogs on PWN.
Goodbye :)