Advanced Return to libc Exploits
Advanced Return to libc Exploits
Advanced Return to libc Exploits
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
This article can be roughly divided in<strong>to</strong> two parts. First, the<br />
advanced return-in<strong>to</strong>-lib(c) techniques are described. Some of the presented<br />
ideas, or rather similar ones, have already been published by others.<br />
However, the available pieces of information are dispersed, usually<br />
platform-specific, somewhat limited, and the accompanying source code is not<br />
instructive enough (or at all). Therefore I have decided <strong>to</strong> assemble the<br />
available bits and a few of my thoughts in<strong>to</strong> a single document, which should<br />
be useful as a convenient reference. Judging by the contents of many posts<br />
on security lists, the presented information is by no means the common<br />
knowledge.<br />
The second part is devoted <strong>to</strong> methods of bypassing PaX in case of<br />
stack buffer overflow (other types of vulnerabilities are discussed at the<br />
end). The recent PaX improvements, namely randomization of addresses the<br />
stack and the libraries are mmapped at, pose an untrivial challenge for an<br />
exploit coder. An original technique of calling directly the dynamic linker's<br />
symbol resolution procedure is presented. This method is very generic and the<br />
conditions required for successful exploitation are usually satisfied.<br />
Because PaX is Intel platform specific, the sample source code has been<br />
prepared for Linux i386 g<strong>libc</strong> systems. PaX is not considered sufficiently<br />
stable by most people; however, the presented techniques (described for<br />
Linux on i386 case) should be portable <strong>to</strong> other OSes/architectures and can<br />
be possibly used <strong>to</strong> evade other non-executability schemes, including ones<br />
implemented by hardware.<br />
The reader is supposed <strong>to</strong> possess the knowledge on standard exploit<br />
techniques. Articles [1] and [2] should probably be assimilated before<br />
further reading. [12] contains a practical description of ELF internals.<br />
--[ 2 - Classical return-in<strong>to</strong>-<strong>libc</strong><br />
The classical return-in<strong>to</strong>-<strong>libc</strong> technique is well described in [2], so<br />
just a short summary here. This method is most commonly used <strong>to</strong> evade<br />
protection offered by the non-executable stack. Instead of returning in<strong>to</strong><br />
code located within the stack, the vulnerable function should return in<strong>to</strong> a<br />
memory area occupied by a dynamic library. It can be achieved by<br />
overflowing a stack buffer with the following payload:<br />
<br />
------------------------------------------------------------------<br />
| buffer fill-up(*)| function_in_lib | dummy_int32 | arg_1 | arg_2 | ...<br />
------------------------------------------------------------------<br />
^<br />
|<br />
- this int32 should overwrite saved return address<br />
of a vulnerable function<br />
(*) buffer fill-up should overwrite saved %ebp placeholder as well, if the<br />
latter is used<br />
When the function containing the overflown buffer returns, the<br />
execution will resume at function_in_lib, which should be the address of a<br />
library function. From this function's point of view, dummy_int32 will be the<br />
return address, and arg_1, arg_2 and the following words - the arguments.