在
本文的开篇中,我们看到了Tomcat 6.0.32中的这个认证BUG,在本篇中,我们来设置IDE环境,用于调试Tomcat。
静态分析
我们已经知道,如果在admin页面的最后加上"j_security_check",则Tomcat会跳过角色认证,直接把页面显示出来,这样对用户角色的定义等于就被bypass掉了,这是一个安全漏洞。
我在分析问题时,比较喜欢先静态分析,再动态调试的方法。于是我将之前下载好的源码包解压:
然后进到里面查找"j_security_check"字串:
包含这个字串的代码并不多。此我决定一个一个地查看这些源代码:
在MacOS下面的一大好处之一就是,终端命令和GUI图形工具结合地很好,比如我可以将搜出的文件列表通过xargs直接喂给BBEdit(我非常喜欢的编辑器)。这样我就可以很方便地一个一个文件地进行阅读:
最后我在RealmBase.java中发现了很有趣的代码:
重点在这里:
...
if (requestURI.endsWith(Constants.FORM_ACTION)) {
if (log.isDebugEnabled())
log.debug(" Allow access to username/password submission");
return (true);
}
...
当URL地址以Constants.FORM_ACTION结尾时,hasResourcePermission方法直接返回true,也就是直接跳过了权限审查。
我们看一下Constants.FORM_ACTION的定义:
嗯,基本上可以确定这块代码造成的问题,静态分析看来可以告一段落。接下来我们需要验证我们的分析是正确的。
环境设置
接下来我们要进行代码的动态分析,首先要设置环境,做好准备工作。于是我们接下来要做的是把整个Tomcat的源代码导入IDE,编译,打包,然后在IDE里面运行Tomcat。。。别害怕,我只是开个玩笑。
对于Tomcat这种规模的项目,我们这样调试太恐怖,也没必要。于是我要祭出最终级武器-JPDA了。知道Java最大的优势是什么吗?就是它的调试架构了。其它语言的DEBUG全部靠边站。如果你不明白我在说什么,参考这套文档:
深入 Java 调试体系: 第 1 部分,JPDA 体系概览
深入 Java 调试体系,第 2 部分: JVMTI 和 Agent 实现
深入 Java 调试体系,第 3 部分: JDWP 协议及实现
深入 Java 调试体系,第 4 部分: Java 调试接口(JDI)
有关JDPA的技术细节,不在本文的讨论范围,大家有兴趣自己学习,本文只是去用,使用起来非常简单。首先我们看一下Tomcat的执行脚本:
如上所示,在bin目录当中,有catalina.sh,这个是Tomcat的实际控制脚本了。我们打开它,看下这几行代码:
可以看到,Tomcat已经很贴心地为我们了设置了带JPDA的启动方式,并且设置默认的调试端口为8000。因此我们使用jpda start即可:
./catalina.sh jpda start
可以看到8000调试端口已开启。接下来我们要把Tomcat的源代码加载进IntelliJ社区版:
如上图所示,打开IntelliJ以后,选择"Import Project",然后选择导入tomcat的源代码:
点击Next,选择Create Project From Existing Sources:
接下来一路Next,最终点击Finish:
这样我们就完成了对工程的创建:
接下来我们打开待调试的代码RealmBase.java:
在第750行设置断点:
如果你的IntelliJ的编辑窗口中没有显示代码行数,可以在配置中打开这个设置:
完成对断点的设置后,我们点击Debug的Edit Configuration来进行配置:
点+号,选择Remote:
Name设置为tc6-jpda,端口号设置为8000,点OK:
这样,我们在debug一栏中就有了tc6-jpda中这个profile:
在本文中,我们完成了对BUG的静态分析,并对动态分析的进行了必要的准备工作。在下一篇文章中,我们将一起动手进行问题的动态分析。