Work in progress

Multipath ROP

Multipath-ROP tries to find multiple ROP-words that are separated by pagesize, so that with ASLR in place one or the other word is hit. The ROP-words have to be different so that the word can be used to pass information about the word itself, hence passing on information about the ASLR layout. If it is possible to construct multiple parallel ROP-execution pathes, one can increase the chance of a ROP-exploit to succeed on ASLR architectures.

The beginning of some kind of proof of concept: At first analyze a binary to find interesting locations. To keep it simple, only combination of pop %exx and add %esp, imm8 instructions before ret were considered. This simple analyzer searches the code from the ret instruction backwards without considering multivalent byte sequences, sequences that could be executed in more than one way. An an ideal algorithm, e.g. markov-chain based, could be able to capture all possible targets and hence increase the number of interesting locations. All valid target offsets are mapped to pagesize using modulo, giving a page offset. For each page offset, the number of available sequences is counted and the stack pointer modification count is stored using a bitmask. The most interesting page offset is that, where the highest number of different stack pointer modification counts is archived. The analysis against ubuntu oneiric libc-2.13.so from around 20110710, md5sum 36428553552e04090ad5b2586f1b4681, can be carried out using:

java org.halfdog.hack.rop.SimpleMultipathRopAnalyzer --File libc-2.13.so

to show that offset 0x4e is most interesting and then

java org.halfdog.hack.rop.SimpleMultipathRopAnalyzer --File libc-2.13.so --DumpResults 0x4e

to get the list of target offsets. Analysis of the target offsets shows that %ebp could be filled in different ways, depending on lib mapping offset. The 5 target sequences are:

00f9040: 450c 7fc4 8d74 2600 83c4 105b 5e5f 5dc3 E....t&....[^_]. 00000000 5D pop ebp 00000001 C3 ret 0065040: 8b55 e029 d789 fa83 c420 89d0 5b5e 5f5d .U.)..... ..[^_] 0065050: c38d b426 0000 0000 39f8 0f47 c789 c289 ...&....9..G.... 00000000 5F pop edi 00000001 5D pop ebp 00000002 C3 ret 0067040: 8527 ffff ff89 f02b 45f0 83c4 1c5b 5e5f .'.....+E....[^_ 0067050: 5dc3 8db6 0000 0000 8b4a 1431 c08b 5220 ]........J.1..R 00000000 5E pop esi 00000001 5F pop edi 00000002 5D pop ebp 00000003 C3 ret 007e040: 2408 8b45 0889 4424 04e8 1200 0000 83c4 $..E..D$........ 007e050: 105b 5dc3 9090 9090 9090 9090 9090 9090 .[]............. 00000000 83C410 add esp,byte +0x10 00000003 5B pop ebx 00000004 5D pop ebp 00000005 C3 ret 00f5040: ff89 4604 e8d7 e8ff ff89 068b 45c0 83c4 ..F.........E... 00f5050: 445b 5e5f 5dc3 6690 8d83 08fc fdff 8944 D[^_].f........D 00000000 83C444 add esp,byte +0x44 00000003 5B pop ebx 00000004 5E pop esi 00000005 5F pop edi 00000006 5D pop ebp 00000007 C3 ret

Next step is to try to find stack data, that will execute on all the different locations. Since testing with real ASLR is hard, a simple helper MultipathRopDemoLoader.c can be used to show execution with different library mappings. When using the same libc file from above on a 32bit x86 architecture, a jump to a fixed memory position even when libc mapping offset is choosen randomly, always results in an execution sequence storing the mapping offset value in %ebp register before jumping to invalid address. The invalid address could be trivially replaced by a valid address except for one offset value, but this should be fixable also. The seed values 1,2,3,7,16 can be used to replay every possible mapping, result is in register %ebp.

gdb --args ./MultipathRopDemoLoader --MapFile libc-2.13.so --StackFile StackContent --Offset 0x20000000 --Offset 0x20004000\ --Offset 0x2007b000 --Offset 0x20092000 --Offset 0x20094000 --Jump 0x200f904e --Seed 16

Last modified 20150407
Contact e-mail: me (%) halfdog.net