Buffer Overflows Part 2!
This is a continuation from my first Buffer Overflow Tutorial; I would highly recommend that you read that tut, before you read this one! (Even if you’ve read it before re-read it to refresh your memory!)
Ok, so in part one we looked at
How a Buffer Overflow happens and the security implications of this.
Ways to find what programs have SUID privileges using the
find / -type f –perm -04000 –ls command .
We also looked at how to change a program to give it #root privileges.
I will start this tutorial off at the point where, you have compiled a piece of code that is vulnerable to an overflow (see part 1), you have changed the ownership of the program to root and you have made it a SUID root program. We will call this program “pool”
So, we know pool can be exploited with a buffer overflow (as we programmed it) and we know it has root privileges (as we gave them to it)
Now what we need to do is generate a program with a buffer (remember a buffer is a portion of memory assigned to a program) that contains the shellcode, which will spawn a shell that can be “fed” into the pool program. We will call this program “snooker”
Our aim is to make the program pool overflow in to the buffer that the program snooker has given it and make the EIP point to where our shellcode within this buffer and then to make snooker accidentally execute this shellcode.
Obviously for this to work we need to know where our shellcode is stored in the buffer!
There two main ways of doing this: Using a NOP sled or by flooding the end of a buffer with quite a few “return addresses”.
No Operation (NOP)
As the name suggests this is an instruction that does nothing, its sole purpose is to take up a byte of memory so nothing else can occupy it.
Why is this useful to us?
For a few reasons really.
1. If our NOP is occupying a byte of memory we know that our shell code couldn’t possibly be there!
2. The processor will skip over a NOP until it gets to something that tells it to do something, i.e. our shellcode (hopefully)
3. A program wont crash if it hits a NOP as the NOP isn’t telling it to do anything, it will just move down or up to the next memory “block”
Consider this (each number represents a bock of memory in our buffer)
Pool Snooker Snooker Shellcode Snooker Snooker Snooker Snooker
For us to execute our shellcode we would have to ensure the EIP was pointing at “4” and no where else, otherwise snooker would continue to run. There would be a lot of trial and error not to mention luck in executing the shell code!
But, what about if we done this:
Pool Snooker NOP NOP NOP NOP NOP Shellcode
As long as the EIP was pointing at either 3,4,5,6,7 or 8 our shellcode would be executed, because as I said earlier the processor would just skip along them NOP’s until it got to something it could execute!
Obviously this gives us a bigger area of error for the EIP to execute the shellcode
So along as we overwrite the EIP with any address in the NOP we can be assured our shellcode will be executed