目的
我登錄到生產(chǎn)服務器上面發(fā)現(xiàn)mysql無法登錄,由于是生產(chǎn)服務器所以不可能重啟或者改配置,于是我想到我可以通過tomcat部署的war包里面的配置文件來拿到mysql的登錄密碼。
1.
我通過tomcat webapp里面拿到了項目,然而 配置文件中的密碼已經(jīng)加密過了。

2.
這個時候我首先想到的是,這個一串很像base64的編碼,我嘗試用base64去破解,然而并不能破解。
3.
于是我準備"破解"這串密碼,也就是看看源碼里面是用什么東西去加密的。
首先我想看看conf包下面是否有相關讀取文件解密操作,然而木有,
然后查找utils包,也木有,
我把整個war包都翻了一次,結(jié)果有用的結(jié)果一個也沒有。
內(nèi)心是無奈的,我基本能肯定是框架做的加密(框架好像是jeesite,我給的評級,一堆別人框架的組合還好意思收費,還好意思付費看視頻,真不要臉...),看來需要我解析框架代碼了,但是這樣我又得去搭建jeesite,我內(nèi)心是抗拒的,故不考慮這種辦法。
4.
萬般無奈下我想到,既然是通訊那么肯定會把密碼發(fā)到mysql服務器,但是極有可能拿到的是一串字節(jié)序列,我可能需要知道m(xù)ysql的通訊協(xié)議,這個比較麻煩但是必須嘗試一下。
于是我使用wireshark去監(jiān)聽3306端口發(fā)出的信息。然而我意外的發(fā)現(xiàn),wireshark居然支持mysql的協(xié)議(我非常感動,這些作者真好,比起國內(nèi)東拼西湊的垃圾應用平臺jeesite的技術上強一萬倍,居然還不收費)
于是我通過wireshark看到了,但是比較蛋疼的,傳輸密碼加密了。

5.
看來必須使用終極大殺器了。
我準備反編譯代碼然后在代碼里面的某一行去打印出密碼來。
6.
首先定位大致的代碼的類,聯(lián)想到如果mysql密碼錯誤會java會彈出相關錯誤棧。我們這個錯誤的幀棧大致的找到相關類。

7.
我們一行行的推,最后發(fā)現(xiàn)在mysql-connector-java-x.x.xx.jar的 MysqlIO類的proceedHandshakeWithPluggableAuthentication這個方法確實會打印真正的password出來,沒有加密的。
(具體是我自己通過其它項目(含mysql-connector-java),一步一步debug發(fā)現(xiàn)的)
8.
我們反編譯mysql-connector-java 這個項目的MysqlIO類,然后另存為java文件。
但是當我們編譯這個java文件的時候。
我意外的發(fā)現(xiàn),反編譯出來的代碼無法正常通過編譯器語法檢查,出現(xiàn)大量bug代碼

(教訓:以后必須注意的是,反編譯出來的代碼不一定就是真的)
9.
各種辦法,各種反編譯器試了之后,我發(fā)現(xiàn)真的好無奈。
看來還是只能硬著頭皮去編譯一次。
我發(fā)現(xiàn)bug語法的數(shù)量和類的行的數(shù)量程正相關。
我刻意找了一個類行數(shù)較少,且含Password的類(NonRegisteringDriver)

10
這個類依然有1個語法bug,但是我手動改了之后,然后在用javac去編譯。
javac -cp .;mysql-connector-java-x.x.xx.jar NonRegisteringDriver.java
成功生成了兩個文件class文件(其中有個是內(nèi)部類)
11
在替換成功jar中類后,在放到tomcat中運行,我們成功的打印了password
收貨
- mysql的通訊過程中并未傳輸真正的密碼,而是傳輸一種,通過SHA1對加鹽的密碼后加密的固定長度的字符串,這種方式值得學習。
- 我們替換類的時候可以找一些行比較少的類,并且某些不是特別重要的方法如果出現(xiàn)錯誤,可以直接將方法返回null
- 編譯時候帶上這個jar本身就可以解決依賴問題。