Reversing : The Hacker's Guide to Reverse Engineering

(ff) #1

Now that you understand the dynamics of the stack in this function, it
becomes easy to see that only two unique stack addresses are being referenced
in this function. The parameter is accessed in the first line (and it looks like the
function only takes one parameter), and the beginning of the local variable area
in the other three accesses.
The function starts by copying a string whose pointer was passed as the first
parameter to a local variable (whose size we know is 100 bytes). This is exactly
where the potential stack overflow lies. strcpyhas no idea how big a buffer
has been reserved for the copied string and will keep on copying until it
encounters the null terminator in the source string or until the program
crashes. If a string longer than 100 bytes is fed to this function, strcpywill
essentially overwrite whatever follows the local string variable in the stack. In
this particular function, this would be the function’s return address. Overwrit-
ing the return address is a sure way of gaining control of the system.
The classic exploit for this kind of overflow bug is to feed this function with
a string that essentially contains code and to carefully place the pointer to that
code in the position where strcpyis going to be overwriting the return
address. One thing that makes this process slightly more complicated than it
initially seems is that the entire buffer being fed to the function can’t contain
any zero bytes (except for one at the end), because that would cause strcpy
to stop copying.
There are several simple patterns to look for when searching for a stack over-
flow vulnerability in a program. The first thing is probably to look at a function’s
stack size. Functions that take large buffers such as strings or other data and put
it on the stack are easily identified because they tend to have huge local variable
regions in their stack frames. This can be identified by looking for a SUB ESP
instruction at the very beginning of the function. Functions that store large
buffers on the stack will usually subtract ESPby a fairly large number.
Of course, in itself a large stack size doesn’t represent a problem. Once you’ve
located a function that has a conspicuously large stack space, the next step is to
look for places where a pointer to the beginning of that space is used. This would
typically be a LEAinstruction that uses an operand such as [EBP – 0x200], or
[ESP – 0x200], with that constant being near or equal to the specific size of
the stack space allocated. The trick at this point is to make sure the code that’s
accessing this block is properly aware of its size. It’s not easy, but it’s not impos-
sible either.


Intrinsic Implementations

The C runtime library string-manipulation routines have historically been the
reason for quite a few vulnerabilities. Most programmers nowadays know bet-
ter than to leave such doors wide open, but it’s still worthwhile to learn to
identify calls to these functions while reversing. The problem is that some


Auditing Program Binaries 249
Free download pdf