目的
我登錄到生產(chǎn)服務器上面發(fā)現(xiàn)mysql無法登錄啸箫,由于是生產(chǎn)服務器所以不可能重啟或者改配置匪煌,于是我想到我可以通過tomcat部署的war包里面的配置文件來拿到mysql的登錄密碼俊嗽。
1.
我通過tomcat webapp里面拿到了項目呼渣,然而 配置文件中的密碼已經(jīng)加密過了蔑祟。
2.
這個時候我首先想到的是早敬,這個一串很像base64的編碼忌傻,我嘗試用base64去破解大脉,然而并不能破解。
3.
于是我準備"破解"這串密碼水孩,也就是看看源碼里面是用什么東西去加密的镰矿。
首先我想看看conf包下面是否有相關讀取文件解密操作,然而木有俘种,
然后查找utils包秤标,也木有,
我把整個war包都翻了一次宙刘,結果有用的結果一個也沒有抛杨。
內(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本身就可以解決依賴問題脊髓。