<< [[2022-06-13]] | [[2022-06-15]] >>
工具的道与术: 道,是指这个工具内在的哲学,如果你觉得哲学这个词太大了,也可以叫它逻辑。一个工具的优雅之处就体现在「道」上,「道」虽然貌似虚无缥缈,它却是最容易区分同类型工具之间不同之处的东西。 术,就是技术层面,这个工具怎么操作,怎么用起来。
RASP-JRASP¶
0x01简介¶
Java Runtime Application Self-Protection 意思是Java应用自我保护系统,简称 JRASP
0x02架构图¶
0x03核心能力¶
优越的性能¶
代码插桩性能高¶
实现 JavaAgent 代码插桩的框架主要有 ASM、Javassist 和 Byteman 等。三者对比之下,ASM 在这几个框架里插桩效率是最高的,我们使用 ASM 来对字节码进行修改,最大限度的提升性能;
检测引擎低延时¶
抛弃了第三方规则引擎,使用Java原生语言实现检测。基于对各种规则引擎做了充分的性能测试,包括 Google V8 引擎、groovy脚本引擎、jdk自带的rhino引擎等, 测试发现一条规则的性能优化到极限耗时也有0.5ms,达不到我们的高负载下的延时要求;而实现相同规则,java原生代码耗时仅0.1ms,如果检测逻辑经过充分预热,耗时会更低。基于对第三方规则引擎和原生检测逻辑的性能对比,我们采用了java原生代码来实现规则检测 。尽管业内大多采用了Google V8引擎,在不同语言环境实现了检测规则的通用性,从大规模实践来看,规则引擎的通用性并不是痛点,RASP部署的最大痛点之一是检测逻辑的性能损耗。
降低注入对服务的影响¶
为了尽可能的降低 agent注入对服务的性能影响,我们创造性的实现了一系列功能,包括注入前的系统负载检查,并实现了自动寻找低峰期开启注入,注入过程无需人为干预; 注入后系统负载高的无损降级与自熔断的功能,最大程度的减少 RASP 对系统性能的影响。
强大的灵活性¶
插件可定制¶
虽然我们对常用开源中间件如tomcat、jetty、springboot等做了支持,一般企业内部会有自研、对各种开源组件包装加壳等操作来适应企业自身的基础设施, 只需要简单的遵循插件开发规范,就可以开发贴合企业架构的插件。
安全插件jar热插拔¶
安全插件按照中间件和功能分类,每个插件都能实现热加载和热卸载;(称之为插件版本升级)
检测参数实时更新¶
每个安全插件都支持参数更新(如黑白名单等);(称之为参数更新)

同时支持2种部署方式¶
java agent的部署方式有2种:premain方式和agentmain方式,2种方式各有利弊,JRASP同时支持。
为大规模部署而生¶
传统的RASP通过修改 Tomcat、Jetty 和 Springboot 等的启动脚本,给JVM增加 javaagent 参数来让JVM加载一个Java Agent。一般这样启动一个Java Agent:
java -javaagent:/path/to/your/agent.jar -jar XXX.jar
这种部署方式首先要知道 web 容器的安装路径,然后还要修改JVM参数配置文件,最后重启 web 容器,RASP 部署才算生效。小规模机器上能够使用,如果是几十万台甚至上百万台主机上,这将是一场运维灾难 (opens new window);
我们自研的 RASP 具有自动发现Java进程和依赖的中间件jar包,并根据中间件类型和版本自动下载和加载对应插件jar包,全过程 Java 服务无需要修改参数,也无需重启, 真正实现了对业务的零打扰;
实现原理:RASP 守护进程发现了 Java 进程之后,对Java进程依赖的jar包进行分析,从对象存储服务下载对应 jar 包的插件到目标主机上,然后 attach 到目标 JVM 上,目标 JVM 在初始化一个 轻量级的 Agent (仅一个类),最后动态加载核心插件 jar 包。
一键部署与跨平台¶
RASP 在 macos、linux 和 windows 环境下分别提供了一键部署的安装包,仅需一个命令即可以开启 RASP 防护。
支持native方法hook¶
例如:一般的rasp命令执行的hook点是java.lang.UNIXProcess.<init> 或者 java.lang.ProcessImpl.start,存在绕过的风险,jrasp支持最底层的native方法forkAndExec,在java层面难以绕过
专注于入侵检测¶
我们自研的 RASP 抛弃了之前开源和商业 RASP 产品大而全的方案,专注解决掉入侵相关的风险,同时也做得更底层,在 Java 运行时环境做了比较多的适配。
自身安全性¶
"打铁还需自身硬",JRASP在防护业务安全的同时,也十分重视自身安全性建设。JRASP的防护策略(包括hook类、参数检测逻辑等)仍然一定程度上于依赖信息不对称, 如何保障策略在传输过程、运行时不被恶意窃取分析是一个重要问题。 JRASP对整个通信链路进行了加密,包括:
- 管理端下发给守护进程的的安全策略加密;
- 守护进程与agent通信的http接口鉴权,防止插件被控制;
- 插件jar包传输全过程加密,在类加载时解密,最大程度防止jar包被反编译;
0x04对比¶
| 产品特性 | 阿里JAM* | 百度OpenRASP | 字节 AgentSmith | JRASP |
|---|---|---|---|---|
| 性能影响 | rt<0.5ms, cpu<1%, mem<100m | cpu<3%,rt<5ms | - | rt<0.5ms, cpu<2%, mem<100m |
| hook入口 | http、rpc | http、rpc | http、rpc | http、rpc |
| hook行为 | rce、file、net | rce、file、net、classloader | ... | rce、file、net、xxe |
| 部署方式 | premain | premain | agentmain | 都支持 |
| 多语言 | java(主要)、nodejs、python | java、php | go、java、python | java |
| 自身安全 | 全链路加密 | jar包、策略明文 | jar包混淆 | 全链路加密 |
0x05Quickstart¶
- 下载安装
# 最新版本`v1.0.5` 2022-06-06日更新
wget https://jrasp-daemon-1254321150.cos.ap-shanghai.myqcloud.com/2022-06-06/v1.0.5/jrasp-1.0.5.tar.gz
# 解压
tar -zxvf jrasp-1.0.5.tar.gz
- 启动与注入
cd jrasp/bin
# 查看Java进程pid
jps -l
# 选择进程号进行注入
./jrasp.sh -p {pid}
- 查看日志
- jrasp/logs/jrasp-agent.log 是 agent 自身日志
- jrasp/logs/jrasp-module.log 是模块调用日志 (攻击日志)
- jrasp/logs/jrasp-daemon.log 是守护进程日志
0x06测试用例¶
- 下载测试用例
wget https://jrasp-1254321150.cos.ap-shanghai.myqcloud.com/jrasp-vulns.war
- 运行
将
jrasp-vulns.war复制 tomcat 或者 jetty 的 webapps 下 启动web容器,打开链接 http://localhost:8080/jrasp-vulns/
- 加载RASP
jrasp-agent 有
启动时和运行时两种启动方式,两种方式各有利弊,JVM启动时加载对业务性能影响小,而JVM运行时加载使用更加灵活。
运行时加载¶
./jrasp.sh -p {pid}
# 返回信息
{"code":200,"data":{"mode":"ATTACH","raspHome":"/Users/xxxx/Desktop/jrasp/bin/..","version":"1.0","username":"admin"}}
运行时加载只需要知道Java进程的pid即可,不受限于JVM启动时机,非常灵活方便,但是在JVM运行时如果负载较高,加载时造成系统CPU短暂升高,可能会影响业务正常运行。
启动时加载¶
Spring boot¶
# springboot 带上 jrasp-launcher.jar
java -javaagent:/path/to/jrasp-launcher.jar -jar application.jar
Tomcat¶
以apache-tomcat-9.0.34 为例子来说明
打开 bin/catalina.sh, 找到如下内容(catalina.sh的第423行):
elif [ "$1" = "start" ] ; then
if [ ! -z "$CATALINA_PID" ]; then
修改为如下(增加 -javaagent 项)
elif [ "$1" = "start" ] ; then
JAVA_OPTS="-javaagent:/path/to/your/jrasp-agent/lib/jrasp-launcher.jar ${JAVA_OPTS}"
if [ ! -z "$CATALINA_PID" ]; then
Jetty¶
修改 java 启动参数,增加 -javaagent 参数(注意将 -jar 放在命令最末尾):
java -javaagent:/path/to/your/jrasp-agent/lib/jrasp-launcher.jar -jar start.jar
上述修改启动脚本的方式不是很灵活,需要业务高度配合,可以联合公司内部的发布系统,统一修改 Java 进程的环境变量来做
export JAVA_TOOL_OPTIONS=-javaagent:/path/to/your/jrasp-agent/lib/jrasp-launcher.jar