4

RASP | 远程Java应用的RASP调试教程 - HsinTsao

 1 year ago
source link: https://www.cnblogs.com/HsinTsao/p/16446639.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

远程Java应用的RASP调试教程

Java RASP是基于Java Agent技术实现的,而Java Agent代码无法独立启动,必须依赖于一个Java运行时程序才能运行。 如何调试一个Java Agent可以参考之前的一篇推文:如何 debug JRASP Agent代码

在RASP开发的中后期,则需要在真实的Web服务器上测试。通常这些Java应用程序都运行在远端设备上,开发者本地不具备这样的环境。所以我们需要远程调试一个真实的Java应用,来解决bug或者验证RASP的防护效果。下面将以tomcat为例,介绍如何调试一个应用于远端Java应用的RASP程序。

  1. 运行于Windows上的IDEA CE 2021.2(社区版)
  2. 运行于Linux上的apache-tomcat-9.0.0.m1

1. 设置IDEA远程调试

  1. 点击编辑运行配置
  2. 新建一个远程JVM调试模板
  3. 调试器模式设置为附加到远程JVM,传输方式选择Socket。IDEA还有ShareMemory方式的传输方式,这两者的本质都是用于传输远程调试信息。双机调试建议使用Socket模式。
  4. 设置目标Java应用所在机器的IP地址,以及一个未被使用的端口。
  5. 选择目标Java应用运行时JDK版本,将会自动生成一些启动参数。不同的JDK版本的启动参数不同,所以需要注意这点。
  6. 复制自动生成的JVM启动参数,用于后续添加到目标Java应用的启动参数中。
  7. 设置需要调试的代码
    image

2. 下断点

  1. 在刚刚设置的需要调试的代码中下断点。
  2. 断点的位置尽量高,而且最好是在逻辑简单且必经之地。因为RASP代码逻辑是由目标Java应用触发,而不是我们手动触发的。另外建议多下几个断点,以保障IDEA可以正确捕获断点。
    image

3. 在目标应用中添加调试的启动参数

  1. 将IDEA自动生成的远程JVM启动参数调加到目标应用的启动参数中.
  2. 以tomcat为例:
    1. tomcat启动脚本目录:${tomcat安装目录}/bin

      • Linux:${tomcat安装目录}/bin/catalina.sh
      • Windows:${tomcat安装目录}/bin/catalina.bat
      • e.g: /usr/web/apache-tomcat-9.0.0.M1/bin/catalina.sh
    2. 修改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=5005
        
      • e.g

        image
    3. 保存修改后的脚本

4. 启动目标Java应用

  1. 重启修改脚本后的Java应用
  2. 以tomcat为例:
    image

5. 启动IDEA远程调试

  1. 选择刚刚新建的远程JVM调试配置并启动

    image
  2. 如果显示连接成功,则表示双机调试通道已经建立。

  3. 如果显示连接失败或者连接超时,则需要排查原因:

    1. 检查双机是否可以ping通。

    2. 检查远端机器上的目标Java应用是否正确地监听在调试端口号上。可以使用如下命令:

      • lsof -i:端口号
      • e.g
        image
    3. 通常远端服务器都设置了防火墙或者安全组,此时需要放开该调试端口号

6. 对目标应用启动RASP注入

  1. 查看所有Java应用程序pid:

    jps
    

    jps.png

  2. 进入到jrasp安装目录

    cd /usr/local/jrasp/bin
    
  3. 手动注入jrasp

    ./jrasp.sh -p pid
    

    image

7. 触发断点

  1. 断点触发与否主要是基于所要测试的代码和断点位置。一般来说,如果断点设置在AgentMain入口处,则jrasp注入的时候,IDEA即可捕获断点。

  2. 如果需要调试的代码和AgentMain函数不在一个模块中,则需要针对性的触发。双机调试建立之后,可能IDEA并未捕获断点,这是因为目前调试的RASP模块还未被执行。

  3. 此时需要针对性的触发断点。举两个例子:

    1. 如果测试的是RASP监控tomcat request请求模块的代码,那么直接浏览器访问tomcat服务器即可触发断点。
    2. 如果测试的是RASP对于RCE检测与阻断能力模块的代码,那么需要使用rce相关的exp攻击tomcat服务器;或者在tomcat服务器内部内置jsp脚本模拟RCE,然后通过浏览器网络请求调用该jsp脚本。
    image

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源码,调试过程更加清晰。

本文作者:HsinTsao

本文链接:https://www.cnblogs.com/HsinTsao/p/16446639.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK