使用JPDA调试Tomcat(二)

本文的开篇中,我们看到了Tomcat 6.0.32中的这个认证BUG,在本篇中,我们来设置IDE环境,用于调试Tomcat。

静态分析

我们已经知道,如果在admin页面的最后加上"j_security_check",则Tomcat会跳过角色认证,直接把页面显示出来,这样对用户角色的定义等于就被bypass掉了,这是一个安全漏洞。

我在分析问题时,比较喜欢先静态分析,再动态调试的方法。于是我将之前下载好的源码包解压:

使用JPDA调试Tomcat(二)_第1张图片

然后进到里面查找"j_security_check"字串:

使用JPDA调试Tomcat(二)_第2张图片

包含这个字串的代码并不多。此我决定一个一个地查看这些源代码:

使用JPDA调试Tomcat(二)_第3张图片

在MacOS下面的一大好处之一就是,终端命令和GUI图形工具结合地很好,比如我可以将搜出的文件列表通过xargs直接喂给BBEdit(我非常喜欢的编辑器)。这样我就可以很方便地一个一个文件地进行阅读:

使用JPDA调试Tomcat(二)_第4张图片

最后我在RealmBase.java中发现了很有趣的代码:

使用JPDA调试Tomcat(二)_第5张图片

重点在这里:

...
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的定义:

使用JPDA调试Tomcat(二)_第6张图片

嗯,基本上可以确定这块代码造成的问题,静态分析看来可以告一段落。接下来我们需要验证我们的分析是正确的。

环境设置

接下来我们要进行代码的动态分析,首先要设置环境,做好准备工作。于是我们接下来要做的是把整个Tomcat的源代码导入IDE,编译,打包,然后在IDE里面运行Tomcat。。。别害怕,我只是开个玩笑。

对于Tomcat这种规模的项目,我们这样调试太恐怖,也没必要。于是我要祭出最终级武器-JPDA了。知道Java最大的优势是什么吗?就是它的调试架构了。其它语言的DEBUG全部靠边站。如果你不明白我在说什么,参考这套文档:

深入 Java 调试体系: 第 1 部分,JPDA 体系概览
深入 Java 调试体系,第 2 部分: JVMTI 和 Agent 实现
深入 Java 调试体系,第 3 部分: JDWP 协议及实现
深入 Java 调试体系,第 4 部分: Java 调试接口(JDI)

有关JDPA的技术细节,不在本文的讨论范围,大家有兴趣自己学习,本文只是去用,使用起来非常简单。首先我们看一下Tomcat的执行脚本:

使用JPDA调试Tomcat(二)_第7张图片

如上所示,在bin目录当中,有catalina.sh,这个是Tomcat的实际控制脚本了。我们打开它,看下这几行代码:

使用JPDA调试Tomcat(二)_第8张图片

使用JPDA调试Tomcat(二)_第9张图片

可以看到,Tomcat已经很贴心地为我们了设置了带JPDA的启动方式,并且设置默认的调试端口为8000。因此我们使用jpda start即可:

./catalina.sh jpda start


使用JPDA调试Tomcat(二)_第10张图片

可以看到8000调试端口已开启。接下来我们要把Tomcat的源代码加载进IntelliJ社区版:

使用JPDA调试Tomcat(二)_第11张图片

如上图所示,打开IntelliJ以后,选择"Import Project",然后选择导入tomcat的源代码:

使用JPDA调试Tomcat(二)_第12张图片

点击Next,选择Create Project From Existing Sources:

使用JPDA调试Tomcat(二)_第13张图片

接下来一路Next,最终点击Finish:

使用JPDA调试Tomcat(二)_第14张图片

使用JPDA调试Tomcat(二)_第15张图片

使用JPDA调试Tomcat(二)_第16张图片

使用JPDA调试Tomcat(二)_第17张图片

使用JPDA调试Tomcat(二)_第18张图片

使用JPDA调试Tomcat(二)_第19张图片

这样我们就完成了对工程的创建:

使用JPDA调试Tomcat(二)_第20张图片

接下来我们打开待调试的代码RealmBase.java:

使用JPDA调试Tomcat(二)_第21张图片

在第750行设置断点:

使用JPDA调试Tomcat(二)_第22张图片

如果你的IntelliJ的编辑窗口中没有显示代码行数,可以在配置中打开这个设置:

使用JPDA调试Tomcat(二)_第23张图片

完成对断点的设置后,我们点击Debug的Edit Configuration来进行配置:

使用JPDA调试Tomcat(二)_第24张图片

点+号,选择Remote:

使用JPDA调试Tomcat(二)_第25张图片

Name设置为tc6-jpda,端口号设置为8000,点OK:

使用JPDA调试Tomcat(二)_第26张图片

这样,我们在debug一栏中就有了tc6-jpda中这个profile:



在本文中,我们完成了对BUG的静态分析,并对动态分析的进行了必要的准备工作。在下一篇文章中,我们将一起动手进行问题的动态分析。

你可能感兴趣的:(intellij,jpda)