2018-12-14号获得class文件中变量的信息

目的

我登录到生产服务器上面发现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.jarMysqlIO类的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

收货

  1. mysql的通讯过程中并未传输真正的密码,而是传输一种,通过SHA1对加盐的密码后加密的固定长度的字符串,这种方式值得学习。
  2. 我们替换类的时候可以找一些行比较少的类,并且某些不是特别重要的方法如果出现错误,可以直接将方法返回null
  3. 编译时候带上这个jar本身就可以解决依赖问题。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容