目的
我登录到生产服务器上面发现mysql无法登录,由于是生产服务器所以不可能重启或者改配置,于是我想到我可以通过tomcat部署的war包里面的配置文件来拿到mysql的登录密码。
1.
我通过tomcat webapp里面拿到了项目,然而 配置文件中的密码已经加密过了。
2.
这个时候我首先想到的是,这个一串很像base64的编码,我尝试用base64去破解,然而并不能破解。
3.
于是我准备"破解"这串密码,也就是看看源码里面是用什么东西去加密的。
首先我想看看conf包下面是否有相关读取文件解密操作,然而木有,
然后查找utils包,也木有,
我把整个war包都翻了一次,结果有用的结果一个也没有。
内心是无奈的,我基本能肯定是框架做的加密(框架好像是jeesite,我给的评级,一堆别人框架的组合还好意思收费,还好意思付费看视频,真不要脸...),看来需要我解析框架代码了,但是这样我又得去搭建jeesite,我内心是抗拒的,故不考虑这种办法。
4.
万般无奈下我想到,既然是通讯那么肯定会把密码发到mysql服务器,但是极有可能拿到的是一串字节序列,我可能需要知道mysql的通讯协议,这个比较麻烦但是必须尝试一下。
于是我使用wireshark去监听3306端口发出的信息。然而我意外的发现,wireshark居然支持mysql的协议(我非常感动,这些作者真好,比起国内东拼西凑的垃圾应用平台jeesite的技术上强一万倍,居然还不收费)
于是我通过wireshark看到了,但是比较蛋疼的,传输密码加密了。
5.
看来必须使用终极大杀器了。
我准备反编译代码然后在代码里面的某一行去打印出密码来。
6.
首先定位大致的代码的类,联想到如果mysql密码错误会java会弹出相关错误栈。我们这个错误的帧栈大致的找到相关类。
7.
我们一行行的推,最后发现在mysql-connector-java-x.x.xx.jar
的 MysqlIO
类的proceedHandshakeWithPluggableAuthentication
这个方法确实会打印真正的password出来,没有加密的。
(具体是我自己通过其它项目(含mysql-connector-java),一步一步debug发现的)
8.
我们反编译mysql-connector-java 这个项目的MysqlIO类,然后另存为java文件。
但是当我们编译这个java文件的时候。
我意外的发现,反编译出来的代码无法正常通过编译器语法检查,出现大量bug代码
(教训:以后必须注意的是,反编译出来的代码不一定就是真的)
9.
各种办法,各种反编译器试了之后,我发现真的好无奈。
看来还是只能硬着头皮去编译一次。
我发现bug语法的数量和类的行的数量程正相关。
我刻意找了一个类行数较少,且含Password的类(NonRegisteringDriver
)
10
这个类依然有1个语法bug,但是我手动改了之后,然后在用javac去编译。
javac -cp .;mysql-connector-java-x.x.xx.jar NonRegisteringDriver.java
成功生成了两个文件class文件(其中有个是内部类)
11
在替换成功jar中类后,在放到tomcat中运行,我们成功的打印了password
收货
- mysql的通讯过程中并未传输真正的密码,而是传输一种,通过SHA1对加盐的密码后加密的固定长度的字符串,这种方式值得学习。
- 我们替换类的时候可以找一些行比较少的类,并且某些不是特别重要的方法如果出现错误,可以直接将方法返回null
- 编译时候带上这个jar本身就可以解决依赖问题。
网友评论