rapid7/metasploit-framework — pull request #2467 by wchen-r7 (2013-10-04 22:08:42+00:00)
Title: Dynamic ROP payload size

While crafting a ROP chain, this allows the size argument to be dynamic depending on the payload size. It can also avoid null bytes, which is a common requirement for our browser exploits.

The following demonstrates that the payload is only 100 bytes, and the size argument for VirtualProtect is automatically adjusted:

20302044 FFFFFFFF ÿÿÿÿ |hProcess = FFFFFFFF
20302048 20302074 t 0 |Address = 20302074
2030204C 00000064 d... |Size = 64 (100.)
20302050 00000040 @... |NewProtect = PAGE_EXECUTE_READWRITE
20302054 51C5BFAE ®¿ÅQ \pOldProtect = hxds.51C5BFAE

The following demonstrates that the payload is 1024 bytes, but the RopDb mixin decides to avoid using 1024, because the value to NEG for 1024 is 0xfffffc00, which has a null byte. So instead, it uses 0xfffffbff for the NEG instruction, which returns 1025 (decimal) for the size argument:

203024A4 FFFFFFFF ÿÿÿÿ |hProcess = FFFFFFFF
203024A8 203024D4 Ô$0 |Address = 203024D4
203024AC 00000401 .. |Size = 401 (1025.)
203024B0 00000040 @... |NewProtect = PAGE_EXECUTE_READWRITE
203024B4 51C5C638 8ÆÅQ \pOldProtect = hxds.51C5C638

I also wrote a rspec for the mixin:

$ rspec spec/lib/rex/exploitation/ropdb_spec.rb

Rex::Exploitation::RopDb
Class methods
.initialize
should initialize with a path of the ROP database ready
.has_rop?
should find the msvcrt ROP database
should find the java ROP database
should find the hxds ROP database
should find the flash ROP database
should return false when I supply an invalid database
.select_rop
should return msvcrt gadgets
should return msvcrt gadgets for windows server 2003
should return msvcrt gadgets with a new base
.generate_rop_payload
should generate my ROP payload
should generate my ROP payload with my stack pivot
.get_safe_size
should return 0xfffffed0 (value does not need to be modified to avoid null bytes)
should return 0xfffffeff (value is modified to avoid null bytes)
.get_unsafe_size
should return 0xfffffc00 (contains a null byte)

Finished in 0.0756 seconds
14 examples, 0 failures

And then I tested the following modules to make sure the patch isn't breaking anything (for Java & msvcrt xp ROP chains):

* msxml_get_definition_code_exec
* ie_execcommand_uaf
* ms13_059_cflatmarkuppointer
* ms12_037_same_id
* mozilla_firefox_onreadystatechange
* ie_cgenericelement_uaf
* ie_setmousecapture_uaf