前言

最近在做ctf题时发现关于mysql任意文件读取漏洞的考点非常频繁,而且一直都朦胧不清,也没去学习,在不久前的DDCTF和国赛,还有最近的Nu1lCTF中都考到了这个点,利用Load data infile语法。在mysql客户端登陆mysql服务端后,客户端执行语句Load data local infile '/etc/passwd' into table proc;,从而可以导致mysql进行本地或远程读取文件。这个原漏洞被爆出在去年phpmyadmin任意文件读取漏洞。

phpMyAdmin开启远程登陆导致本地文件读取

下面我们先去分析复现下这个漏洞。

如果phpmyadmin开启了如下选项

$cfg['AllowArbitraryServer'] = true; //false改为true

则登录时就可以访问远程的服务器。当登陆一个恶意构造的Mysql服务器时,即可利用load data infile读取该服务器上的任意文件。当然前提条件是secure_file_priv参数允许的目录下,且phpmyadmin的用户对该文件有读的权限。

这里利用vulnspy上的实验环境演示分析该漏洞。
VulnSpy 已为大家提供在线 phpMyAdmin 环境地址:https://github.com/vulnspy/phpmyadmin-4.8.4-allowarbitraryserver

漏洞细节
LOAD DATA LOCAL导致的任意文件读取是个由来已久的问题,根据前人们的研究:

Read MySQL Client’s File
MySQL connect file read
我们知道下列的下列情况都存在该问题:

MySQL Client
PHP + mysql/mysqli
PHP + PDO (MYSQL_ATTR_LOCAL_INFILE)
Python + MySQLdb
Python3 + mysqlclient
Java + JDBC Driver

phpMyAdmin 属于典型的 php+mysqli 组合,当 AllowArbitraryServer 开启的情况下(默认关闭),我们可以让phpMyAdmin连接到恶意的MySQL服务器来触发任意文件读取漏洞。

漏洞利用

EXP: https://github.com/Gifts/Rogue-MySql-Server/blob/master/rogue_mysql_server.py

1. 首先是配置恶意服务器。在db服务器的命令行里修改root/exp/rogue_mysql_server.py文件,设port为3306外的其他端口,这里设为3307,然后在filelist中选择一个要读取的文件。我们这里读取/etc/passwd文件。

2. 运行python rogue_mysql_server.py,启动服务,服务会监听3307端口。

3. 打开phpMyAdmin的登录页面,地址输入db:3307、用户密码随意输,提交登录。

然后会发现生成一个mysql.log日志,查看日志

在日志中我们看到成功读取了passwd文件。

参考https://www.vulnspy.com/cn-phpmyadmin-load-data-local-file-read-local-file/

漏洞防御
关闭local_infile参数,禁止导入本地文件
开启–ssl-mode=VERIFY_IDENTITY参数,防止连接不安全的mysql服务器

参考https://www.anquanke.com/post/id/173039

ctf例题分析

下面看一下今年ddctf中mysql弱口令这道题,这题就是利用了以上原理。
http://117.51.147.155:5000/index.html#/scan
首先题目要求我们输入自己的服务器ip以及端口,并且要在服务器上运行mysql服务。

agent.py文件

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 12/1/2019 2:58 PM
# @Author  : fz
# @Site    :
# @File    : agent.py
# @Software: PyCharmimport json
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from optparse import OptionParser
from subprocess import Popen, PIPEclass RequestHandler(BaseHTTPRequestHandler):def do_GET(self):request_path = self.pathprint("\n----- Request Start ----->\n")print("request_path :", request_path)print("self.headers :", self.headers)print("<----- Request End -----\n")self.send_response(200)self.send_header("Set-Cookie", "foo=bar")self.end_headers()result = self._func()self.wfile.write(json.dumps(result))def do_POST(self):request_path = self.path# print("\n----- Request Start ----->\n")print("request_path : %s", request_path)request_headers = self.headerscontent_length = request_headers.getheaders('content-length')length = int(content_length[0]) if content_length else 0# print("length :", length)print("request_headers : %s" % request_headers)print("content : %s" % self.rfile.read(length))# print("<----- Request End -----\n")self.send_response(200)self.send_header("Set-Cookie", "foo=bar")self.end_headers()result = self._func()self.wfile.write(json.dumps(result))def _func(self):netstat = Popen(['netstat', '-tlnp'], stdout=PIPE)netstat.wait()ps_list = netstat.stdout.readlines()result = []for item in ps_list[2:]:tmp = item.split()Local_Address = tmp[3]Process_name = tmp[6]tmp_dic = {'local_address': Local_Address, 'Process_name': Process_name}result.append(tmp_dic)return resultdo_PUT = do_POSTdo_DELETE = do_GETdef main():port = 8123print('Listening on localhost:%s' % port)server = HTTPServer(('0.0.0.0', port), RequestHandler)server.serve_forever()if __name__ == "__main__":parser = OptionParser()parser.usage = ("Creates an http-server that will echo out any GET or POST parameters, and respond with dummy data\n""Run:\n\n")(options, args) = parser.parse_args()main()

这个agent.py代码不是很长,从模块名、函数名大概就能猜到它的意思——开启运行主机上的8123端口做一个http服务器,然后返回运行主机上的tcp进程信息。即代码_func方法中popen函数执行的命令netstat -tlnp,关于linux netstat命令参数的详解可见Linux netstat 命令

这里运行一下netstat -tlnp


agent.py代码的意思理解清楚后
按照提示把agent.py部署到我的阿里云主机上,记得安全组把8123端口打开,然后在自己的vps上运行agent.py以及伪造的mysql服务端https://github.com/Gifts/Rogue-MySql-Server。

然后在题目输入框输入你的vps的地址和你伪造的mysql服务端服务的端口后进行扫描。然后题目提示服务器未开启mysql。

这里就应该可以猜到,题目扫描的流程——先向目标ip的8123端口进行访问,获取目标vps上开启的tcp进程,然后进行判断mysql服务是否开启。
所以这里首先要做的是绕过这个判断,我们可以修改agent.py中的代码,从vps上的agent.py的输出结果来看,题目服务器应该使用GET型进行请求。

于是我们找到agent.py代码里的GET处理函数,修改如下图,将返回结果直接赋为result = [{'local_address':"0.0.0.0:3306","Process_name":"1234/mysqld"}]

def _func(self):netstat = Popen(['netstat', '-tlnp'], stdout=PIPE)netstat.wait()ps_list = netstat.stdout.readlines()result = [{'local_address':"0.0.0.0:3306","Process_name":"1234/mysqld"}]# for item in ps_list[2:]:#    tmp = item.split()#    Local_Address = tmp[3]#    Process_name = tmp[6]#    tmp_dic = {'local_address': Local_Address, 'Process_name': Process_name}#    result.append(tmp_dic)#return resultself.wfile.write(json.dumps(result))

改为之后,我们再在伪造mysql服务器的脚本里改要读的文件名称,这里直接给含flag目标文件吧,~/.mysql_history(root用户的mysql操作一般记录在该文件中)

1.开启agent.py,监听8123端口
2.开启rogue_mysql_server.py(监听端口3306、filelist为~/.mysql_history)
3.题目输入框输入vps ip及上述rogue_mysql_server.py(注意在自己的云主机上安全组中设置允许通过该端口),进行扫描

可以看到扫描成功,此时在rouge_mysql_server.py生成的mysql.log中应该就能看到~/.mysql_history文件内容,在里面可以找到flag。

mysql任意文件读取漏洞学习相关推荐

  1. 7天学习Go语言-尾声+一次险些翻车的任意文件读取漏洞小记

    接口 接口的定义 接口(interface )类型是对其他类型行为的概括和抽象,接口类型定义了一组方法,但是不包括这些方法的具体实现 接口本质是一种指针类型,可以实现多态功能.如果一个类型实现了某个接 ...

  2. 蓝海卓越计费管理系统漏洞学习——download.php 任意文件读取漏洞

    警告 请勿使用本文提到的内容违反法律. 本文不提供任何担保 目录 警告 一.概述 二.影响版本 三.漏洞复现 一.概述 蓝海卓越计费管理系统 download.php文件存在任意文件读取漏洞,攻击者通 ...

  3. 记一次小米路由器任意文件读取漏洞

    文章目录 前言 一.漏洞发现 二.漏洞挖掘 1.简单的爆破 2.文件读取 三.漏洞利用 总结 前言 任意文件读取漏洞,是web安全里高危的漏洞,它可以泄露源码.数据库配置文件等等,导致网站处于极度不安 ...

  4. Grafana 任意文件读取漏洞复现

    一.漏洞描述 Grafana存在任意文件读取漏洞,通过默认存在的插件,可构造特殊的请求包读取服务器任意文件 二.漏洞影响 Grafana 8.x 三.漏洞复现 可以从登陆页面看到版本信息为 v8.2. ...

  5. 【MetInfo任意文件读取】--任意文件读取漏洞

    文章目录 漏洞信息 一.漏洞产生的原因 二.漏洞利用 1.对靶机网址进行burp抓包 2.对上述请求包进行修改 三.漏洞修复与绕过--四种修复与绕过 1.置空../和./ 2.对$dir进行判断 3. ...

  6. 任意文件读取漏洞知识梳理

    文章目录 1.概述 2.开发语言触发点 2.1 PHP 2.2 Python 2.3 Java 2.4 Ruby 2.5 Node 3.中间件/服务器相关触发点 3.1 Nginx错误配置 3.2 数 ...

  7. Apache Solr任意文件读取漏洞复现

    Apache Solr任意文件读取漏洞复现 一.简介 Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口.用户可以通过http请求,向搜索引擎服务器提交一定格 ...

  8. CISCO ASA任意文件读取漏洞复现 (CVE-2020-3452)

    CISCO ASA任意文件读取漏洞复现 (CVE-2020-3452) 一.漏洞描述: Cisco Adaptive Security Appliance (ASA) 防火墙设备以及Cisco Fir ...

  9. 昆石网络 VOS3000虚拟运营支撑系统任意文件读取漏洞

    漏洞描述: 昆石网络 VOS3000虚拟运营支撑系统 通过 %c0%ae%c0%ae 等字符绕过检测,可导致任意文件读取漏洞. 漏洞利用条件: 对⽤户查看或下载的⽂件没有限制或者限制绕过,就可以查看或 ...

最新文章

  1. 【ACM】杭电OJ 2036(待更)
  2. [zz]ZeroMQ 的模式
  3. sql 以a开头的所有记录_#9#猴子聊数据分析之常见的SQL笔试题和面试题(下)
  4. Android开发者必备的42个链接
  5. nagios用NsClient自定义windows监控
  6. (转)msys2使用教程
  7. java、sqlserver复习
  8. dockerHub登录失败
  9. linux命令(44):sed,vim;去掉文件中的^M 符号,去掉行首空格和制表符
  10. OpenGL中 Canvas 性能分析
  11. 35c语言编程,35编号c语言编程题08850.pdf
  12. 基于Java的博客系统
  13. paip.gch预编译头不生效的原因以及解决:
  14. 电子电路基础——知识点(下篇)
  15. 修改app的名字和图标
  16. 如何屏蔽油管网页上的广告
  17. android 自定义开关键设置大小,Android 自定义Switch开关按钮的样式实例详解
  18. WLC5508 HA ( AP SSO)
  19. Kali网络渗透测试二——网络嗅探与身份认证
  20. 有用的win11小技巧

热门文章

  1. 计算机网络-数据链路层(超级无敌详细)
  2. 由曦:王坚在这本书里讲了他的坚持
  3. “春节回家带点啥?”一个愁人的选择题
  4. Nmap Network Scanning扫描版
  5. 场效应管(FET)知识点释义
  6. 《互联网信贷风险与大数据》读书笔记(三)
  7. Spring错误之org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named ‘bookService‘
  8. 如何用mac自带软件录屏且录制屏内屏外声音
  9. qiankun 传统项目配置_前端微服务
  10. MAC Python环境配置