Java调试总结
本文章已投稿seebug:https://paper.seebug.org/1316/ 【有点尴尬的是排版乱的】
0x00 前言
最近一直在Java相关漏洞进行分析学习,调试环境就是第一步需要准备的,所以总结一下,也是为跟我一样想要接触漏洞调试分析的萌新提供一些参考吧。
文笔粗糙,如有不当,请大佬批评指正。
0x01 调试基本方法
调试环境
- Intelli IDEA 2019.2.4
- Windows10
关于IDEA的安装破解这里就不说了,网上大把文章可以参考。
IDEA的调试基本用法
如上图,我们挨个简单介绍下这些按钮和区域,如果想要更多详细信息,建议看下官网IntelliJ IDEA Debug code
调用栈:主要是在调试过程中的一些方法调用栈的显示
变量区:调试程序中的变量显示,可以查看和更改变量值
调试按钮:
方框内从左到右按钮分别是:
:Step Over (F8),步过,一步一步往下,有方法不会进入内部
:Step Into (F7),步入,有方法可以进入方法内部,一般用于进入自定义方法内,不会进入官方类库的方法
: Force Step Into (Alt+Shift+F7),强制步入,能进入任何方法,包括官方类库的方法
: Step Out (Shift+F8),步出,退出当前方法到方法调用处
:Drop Frame,回退断点,回退frame
:Run to Cursor (Alt+F9):运行到光标处,可以运行到光标的那行,到那时中途有断点会停在断点。
其实除了上面的按钮,还有Force Run to Cursor(Ctrl+Alt+F9)、Improve stepping speed、Step out of code block等可以在Run菜单栏找到。
运行工具按钮:可以在这里重新运行、结束、查看所有断点等
:Rerun,重新运行
:Resume Program (F9):恢复程序,运行程序,遇到断点再停止
:Stop,停止运行
:View Breakpoints,查看所有断点
:View Breakpoints,使所有断点失效
计算表达式:Evaluate Expression (Alt+F8),在我看来是一个非常好用的计算器,可以计算表达式、方法return值等
除了上面的基本用法,官方还为我们准备了一些实用的技巧。
:Drop Frame,回退断点,上面提到了这个。我们在debug分析的过程中经常会有Step多了,错过了关键地方或者想回去重看下,就可以用这个。
Use breakpoint expressions,断点表达式:可以设置断点的条件,当满足条件才暂停,这个可以在循环或者某个确认
0x02 远程调试
我在分析漏洞的时候,会用到远程调试,多是docker+IDEA,所以这里想总结下便于以后远程分析各种java相关漏洞。
Java远程调试基础知识
Java远程调试的原理是两个VM之间通过debug协议JDWP(Java Debug Wire Protocol)进行通信,确保本地的Java的源代码与目标应用程序一致就可以成功调试,在这里我们通常会认为远程JVM是debug服务器,本地JVM是debug客户端。
知道这个我们就抓住了重点。IDEA为我们提供了连接远程调试服务,只要像下图配置远程JVM就可以去连接,而且IDEA会帮我们自动生成命令行,可以为远程JVM提供参考。
Debugger mode:指的是本地的debug模式,这里有两种选择Attach和Listen,Attach代表主动去连接远程JVM,那么远程JVM就处于监听状态,Listen代表本地监听远程JVM,我目前接触的比较多的是Attach模式,所以下面介绍的也都是这种模式。
不同的JDK版本,JVM命令行参数可能不同,这里仅介绍下JDK 5-8的命令行参数:
1 | -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=1234 |
远程调试实例
在分析漏洞时,经常会在vulhub、vulfocus等拉取docker镜像来进行复现,但是如果这时候想要进行代码深入分析的时候,就需要用到远程调试。以下用两个例子进行说明。
场景一:Apache Dubbo漏洞docker远程分析调试,内含jar包。
直接在后台从vulfocus进行拉取镜像或者vulfocus页面拉取:
1 | docker pull vulfocus/dubbo-cve_2020_1948 |
在页面启动dubbo-cve_2020_1948容器
查看容器相关信息,如图,能看到环境变量和启动命令”java -jar /demo/demo.jar”
1 | docker inspect 524 |
现在我们需要将容器环境变量和启动命令做修改,这里我使用docker-compose来启动服务。docker-compose.yml文件如下,添加环境调试变量JAVA_OPT、命令添加”-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=18888”,端口注意对于添加18888。
1 | version: "3" |
开启docker-compose up -d
到此docker环境配置完成,接下来配置本地IDEA环境
首先用docker cp将上面执行的demo.jar包拷贝出来,然后传输到本地
1 | docker cp 524:/demo/demo.jar . |
创建一个新项目,将demo.jar作为libraries加进来
在项目下创建一个lib目录,然后打开demo.jar里面的lib下的所有jar拷贝到新建的lib下,并将新建的lib添加到libraries
然后配置远程调试JVM信息准备连接
配置完成后,打上断点发送包就可以正常拦截分析了
这种场景适用于直接执行jar包,根据实际情况修改相关信息即可。当我们的复现docker环境是用包含了war包在tomcat下部署的,那我们可以采用两种方法,一种即将war拷贝到本地部署然后调试,另一种就是修改容器的tomcat相关远程调试参数然后拷贝ROOT下的src到项目然后分析,这里说明下如何tomcat远程调试参数:可以直接进入容器修改catalina.sh,也可以像上面方式写一个docker-compose.yml添加上环境变量。所以类似情况根据实际情况变通即可
1 | # tomcat远程调试 |
场景二:weblogic漏洞调试分析,直接用docker镜像进行分析,将用到的jar拷贝到本地
这里不在本文详细说明,参考IDEA+docker,进行远程漏洞调试(weblogic)即可,我们需要知道的是遇到这种大型中间件等思路都是类似的:
- 找到开启他们远程调试的方法,一般是在启动脚本中某个debug参数进行修改
- 保证外部开启这个容器的对应端口和对应环境
- 本地IDEA:在一个项目中将容器内的相关jar包都拷贝出来作为libraries
- IDEA配置远程调试IVM信息,打上断点连接remote JVM
参考链接:
Java远程调试(Remote Debugging)的那些事