Vulnerability Development mailing list archives

RE: problem in off by one overflow


From: "Steven Alexander" <alexander.s () mccd edu>
Date: Mon, 7 Feb 2005 10:10:10 -0800

Off-by-one exploits do not work by pointing ebp at shellcode like a
straightforward exploit does with eip.  ebp points to the local stack
frame.  The ebp stored on the stack points to the previous local stack
frame.  You need to modify the saved ebp value to manipulate the stack
frames in such a way that an eip of your choosing is later removed from
the stack.  
 
In a function call, the arguments to the function are pushed on to the
stack.  A call instruction is executed that pushes the current eip on to
the stack and jumps to the address of the function to continue
executiong.
 
At the beginning of each function, the current ebp is pushed on to the
stack and the current esp is copied over ebp.  Then, esp is decremented
to make room for local variables.  
 
At the end of each function, ebp is copied over esp.  The previous ebp
is popped from the stack.  The function returns by popping eip from the
stack and resuming execution at that address (with a ret instruction).
 
Say that you have a program where func1 calls func2.  In func2, you
modify the saved ebp value with an overflow.  At the end of func2, the
value of ebp (the current one, not the one you modified) is restored
into esp.  Your modified ebp is popped into ebp.  Func2 returns
(correctly) into func1.  At the end of func1, the now current ebp (the
one you did modify) is copied over esp.  The previous ebp is popped off
the stack (which means that esp, which holds your modified ebp, is
increased by 4) and func1 returns.  
 
In order to construct an exploit, you need to 
 
1) put your shellcode on the stack
2) store the address of (read: a pointer to) your shellcode on the stack
(if it's not exact, you can NOP-pad your shellcode).
3) modify the saved ebp in func2 to point four bytes lower than the
address of your shellcode
 
Then, 
 
* The value you supply will be increased by four due to a 'pop ebp'
instruction and will then point at the address of your shellcode
 
* func1 will pop what it thinks is the saved eip off the stack (but is
actually the address of your shellcode)
 
* The program will resume execution at your shellcode.
 
There are possible complications.  If you modify the saved ebp in func2
and func1 uses ebp to reference local variables after func2 returns, the
program may crash.
 
You should read or re-read the Phrack article on the subject:
http://www.phrack.org/phrack/55/P55-08
 
I hope this helps and that I haven't made any errors myself,
 
Steven


Current thread: