Java RASP是基于Java Agent技术实现的,而Java Agent代码无法独立启动,必须依赖于一个Java运行时程序才能运行。 如何调试一个Java Agent可以参考之前的一篇推文:如何 debug JRASP Agent代码
在RASP开发的中后期,则需要在真实的Web服务器上测试。通常这些Java应用程序都运行在远端设备上,开发者本地不具备这样的环境。所以我们需要远程调试一个真实的Java应用,来解决bug或者验证RASP的防护效果。下面将以tomcat为例,介绍如何调试一个应用于远端Java应用的RASP程序。


tomcat启动脚本目录:${tomcat安装目录}/bin
${tomcat安装目录}/bin/catalina.sh${tomcat安装目录}/bin/catalina.bat/usr/web/apache-tomcat-9.0.0.M1/bin/catalina.sh修改tomcat启动脚本,添加启动参数。将刚刚复制的JVM启动参数以如下的方式添加至catalina.sh的最前面:
Linux:
export JAVA_OPTS='-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005'windows
set JAVA_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005e.g
保存修改后的脚本

选择刚刚新建的远程JVM调试配置并启动
如果显示连接成功,则表示双机调试通道已经建立。
如果显示连接失败或者连接超时,则需要排查原因:
检查双机是否可以ping通。
检查远端机器上的目标Java应用是否正确地监听在调试端口号上。可以使用如下命令:
lsof -i:端口号
通常远端服务器都设置了防火墙或者安全组,此时需要放开该调试端口号。
查看所有Java应用程序pid:
jps
进入到jrasp安装目录
cd /usr/local/jrasp/bin手动注入jrasp
./jrasp.sh -p pid
断点触发与否主要是基于所要测试的代码和断点位置。一般来说,如果断点设置在AgentMain入口处,则jrasp注入的时候,IDEA即可捕获断点。
如果需要调试的代码和AgentMain函数不在一个模块中,则需要针对性的触发。双机调试建立之后,可能IDEA并未捕获断点,这是因为目前调试的RASP模块还未被执行。
此时需要针对性的触发断点。举两个例子:

RASP是依赖目标Java进程的,所以RASP的远程调试也是基于Java应用的远程调试。比如说调试Tomcat上的RASP,要先在Tomcat的JVM启动参数中添加远程调试的设置,RASP注入后,RASP的代码将作为Tomcat的一部分被JVM运行,可远程调试Tomcat即可远程调试RASP。补充一点,调试时无需Tomcat源码,在RASP的代码中设置断点,IDEA将自动捕获。但是,RASP大多时候需要hook Tomcat的API,如果无法精准地知道API及其函数描述,可以利用maven中添加对应的tomcat版本的依赖包,上述的远程调试技巧也可以定位到相关的tomcat源码中,这样子在调试堆栈中,既可以看RASP的代码,也可以看JDK源码和tomcat源码,调试过程更加清晰。