提权 --Mysql提权方式总结
文章目录
一、适用场景
- 拿到的Web服务器权限较低;
- 对Web服务器攻击无进展;
- 目标服务器有mysqld服务,且拥有Mysql的system权限
二、UDF提权
2.1 UDF介绍
2.1.1 含义
UDF(User Defined Functions,用户自定义函数)Mysql的一个扩展接口,用户可以添加新函数对MYSQL的功能进行补充。C++函数编写,文件后缀为 .dll。
2.1.2 UDF使用
这里通过下面使用的提权过程的lib_mysqludf.dll文件来阐述UDF能干啥?
lib_mysqludf.dll(sqlmap工具自带)文件中提供了如下函数,可动态加载执行任意系统命令:
函数 | 作用 |
---|---|
sys_eval () | 执行任意系统命令,并将输出返回 |
sys_exec () | 执行任意系统命令,并将退出码返回 |
sys_get () | 获取一个环境变量 |
sys_get () | 创建或修改一个环境变量 |
如果没有UDF库文件(.dll)或没有在\plugin目录下的话,执行会报错:(不能打开共享库)
因此,如果想使用自定义函数功能,必须将UDF库文件放入到指定的位置下才可以,这个也是UDF提权的核心所在!
2.1.3 注意点
官网对UDF安全项说明:为了防止滥用用户定义的函数:
- 要创建 / 删除自定义函数必须拥有数据库的insert或delete权限(添加和删除行)
- Mysql版本<5.1之前,UDF库文件需导入到系统目录:C:\Windows / C:\Windows\system32下;
- Mysql版本>=5.1之后,UDF库文件必须放入服务器的插件目录中(~/lib/plugin目录下,该目录由plugin系统变量的值给出,默认不存在,如提权需设法创建)。
Tips 1:Mysql5.1版本前和版本后的plugin_dir目录?
- Mysql<5.1版本,查看plugin_dir目录:
- Mysql>=5.1版本,查看plugin_dir目录:
Tips2. 关于udf官方解释,官网传送门
2.2 UDF提权操作
2.2.1 核心操作
mysql<5.0,将udf库文件导出的路径随意;
5.0 <= mysql <= 5.1 ,将udf库文件传入到系统目录下;
mysql>5.1,将udf库文件传入到/lib/plugin目录下(默认不存在,难点之一)
2.2.2 提权限制
限制1
- mysql开启了远程连接(可以远程连接执行mysql命令)
限制2
- secure_file_priv值为空(mysql允许将数据导出到本地文件,远程传入UDF库文件到目标服务器本地指定目录)
限制3
- 创建/plugin目录(高版本的mysql数据库默认没有此目录需要远程创建)
限制4
- 免杀(传入的UDF库文件未被杀软杀掉)
2.2.3 操作过程
A. 环境展示
Windows10(攻击机,ip:192.168.3.4)
Windows 2008 R2(虚拟机,ip:192.168.7.131)
Mysql 5.5.3(PHPStudy 2018)
B. 准备DLL文件
自动化注入工具sqlmap已集成lib_mysqludf_sys库文件:(具有和操作系统进行交互功能的UDF库,官网说明传送门)
其位置于:
需要针对对方Mysql版本使用对应的dll文件才能生效
这里的dll文件需要经过解码才能使用,接下来对dll文件进行解码:
Tips: sqlmap自带的shell或一些二进制文件,为了防止被误杀都经过异或方式编码,不能直接使用,可以利用自带的解码工具cloak.py进行解码(目录:\sqlmap\extra\cloak\cloak.py)
》》进入到cloak目录下执行如下命令即可解码,生成UDF库文件
cloak.py -d -i <要解码的文件>
C. 判别能否外联
目的:判断mysql是否允许远程连接:
》》Nmap探测目的端口是否开放了mysql服务(已开放)
》》测试是否开启远程连接,这里提供三种方法
方法一: 启动mysql服务本地尝试(返回如下不允许连接):
方法二: 使用客户端管理软件连接尝试(返回如下则不允许远程连接,推荐):
方法三: Hydra 远程**,显示如下则不允许远程连接
Tips:这里为了演示,已满足提权限制1 :先允许数据库远程连接,操作请参考:Mysql开启远程连接
D. 远程传入文件
a. 创建plugin目录
网上传说的ntfs数据流创建方法未成功,这里我手动创建的:
Tips:这里为了演示,已满足提权限制2(secure_file_priv值为空,这样才能导入到文件到本地!),查看修改变量值secure_file_priv值方法可参考:Mysql导出数据之全局变量secure_file_priv
(附:未设置其值为空导出文件操作会报如下错误:)
(附:创建plugin目录会报如下错误:)
b. 上传dll文件
目的: 将UDF库文件传入到对方plugin目录下(mysql版本大于5.1)
思路: 通过攻击者本地将dll文件通过mysql的hex函数生成16进制文件,通过创建数据库表将16进制复制插入到表中然后再通过查询表中的内容建立到受害者本地文件中生成dll文件
》》查看对方mysql的位数(为了对比使用sqlmap的32位还是64位,这里是32位)
》》查看对方plugin目录位置(导入文件位置)
》》攻击者本地将sqlmap的dll文件转换成16进制文本文件格式到本地文件中(方便后续传输)
》》在mysql数据库中创建一个udfdmp表:
use mysql;
create table udftmp(c blob);
》》在udftmp表中写入已转换的16进制的dll文本内容
*insert into udftmp values(unhex('复制udf文件中的16进制文本'));*
其原理如下:
》》将udftmp 中的数据通过查询传入新建的udf.dll文件中
select c from udftmp into dumpfile '~/plugin/udf.dll';
》》成功远程将sqlmap的lib_mysqludf_sys_32.dll文件通过建表16进制插入并查询方式导入到受害者本地的plugin文件下:
》》删除对Mysql的入侵痕迹(删除刚建立的udfdmp表)
问:hex()函数和unhex()函数作用?
举例1:对字符进行16进制加 / 解码
hex():将字符以16进制进行编码(“123” 16进制编码为“313233”)
unhex():将16进制字符进行解码(“313233” 16进制解码为 “123”)
举例2:对文件进行16进制加 / 解码
(将123进行16进制加码到本地不存在的test.txt文本文件)
问:为何要用16进制进行传输?
答:load_file(’’) 函数指定路径要用单引号,如果不想用单引号可以使用16进制进行替代。
举例:将本地文件进行16进制加密到本地另一个文件中(默认情况下普通用户不能创建删除本地文件,这个也是mysql可越权的原因!)
E. 从UDF库中引入自定义函数并执行
》》执行操作系统命令(提权成功!)