Class: Rex::Exploitation::RopDb
- Inherits:
-
Object
- Object
- Rex::Exploitation::RopDb
- Defined in:
- lib/rex/exploitation/ropdb.rb
Overview
This class provides methods to access the ROP database, in order to generate a ROP-compatible payload on the fly.
Instance Method Summary collapse
-
#generate_rop_payload(rop, payload, opts = {}) ⇒ Object
Returns a payload with the user-supplied stack-pivot, a ROP chain, and then shellcode.
-
#has_rop?(rop_name) ⇒ Boolean
Returns true if a ROP chain is available, otherwise false.
-
#initialize ⇒ RopDb
constructor
A new instance of RopDb.
-
#select_rop(rop, opts = {}) ⇒ Object
Returns an array of ROP gadgets.
Constructor Details
#initialize ⇒ RopDb
Returns a new instance of RopDb.
16 17 18 |
# File 'lib/rex/exploitation/ropdb.rb', line 16 def initialize @base_path = File.join(File.dirname(__FILE__), '../../../data/ropdb/') end |
Instance Method Details
#generate_rop_payload(rop, payload, opts = {}) ⇒ Object
Returns a payload with the user-supplied stack-pivot, a ROP chain, and then shellcode. Arguments: rop - Name of the ROP chain payload - Payload in binary opts - A hash of optional arguments:
'nop' - Used to generate nops with generate_sled()
'badchars' - Used in a junk gadget
'pivot' - Stack pivot in binary
'target' - A regex string search against the compatibility list.
'base' - Specify a different base for the ROP gadgets.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/rex/exploitation/ropdb.rb', line 78 def generate_rop_payload(rop, payload, opts={}) nop = opts['nop'] || nil badchars = opts['badchars'] || '' pivot = opts['pivot'] || '' target = opts['target'] || '' base = opts['base'] || nil rop = select_rop(rop, {'target'=>target, 'base'=>base}) # Replace the reserved words with actual gadgets rop = rop.map {|e| if e == :nop sled = (nop) ? nop.generate_sled(4, badchars).unpack("V*")[0] : 0x90909090 elsif e == :junk Rex::Text.rand_text(4, badchars).unpack("V")[0].to_i elsif e == :size payload.length elsif e == :unsafe_negate_size get_unsafe_size(payload.length) elsif e == :safe_negate_size get_safe_size(payload.length) else e end }.pack("V*") raise RuntimeError, "No ROP chain generated successfully" if rop.empty? return pivot + rop + payload end |
#has_rop?(rop_name) ⇒ Boolean
Returns true if a ROP chain is available, otherwise false
26 27 28 |
# File 'lib/rex/exploitation/ropdb.rb', line 26 def has_rop?(rop_name) File.exists?(File.join(@base_path, "#{rop_name}.xml")) end |
#select_rop(rop, opts = {}) ⇒ Object
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, :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. opts - A hash of optional arguments:
'target' - A regex string search against the compatibility list.
'base' - Specify a different base for the ROP gadgets.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/rex/exploitation/ropdb.rb', line 41 def select_rop(rop, opts={}) 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| name = e.attributes['name'] next if not has_target?(e, target) if not base default = e.elements['gadgets'].attributes['base'].scan(/^0x([0-9a-f]+)$/i).flatten[0] base = default.to_i(16) end gadgets << parse_gadgets(e, base) } return gadgets.flatten end |