深入源码对OpenRASP进行原理和设计思想的剖析
字数 2173 2025-08-10 21:22:35

OpenRASP 原理与设计思想深入剖析

一、OpenRASP 概述

OpenRASP(Runtime Application Self-Protection)是百度开源的一款运行时应用自我保护产品,通过在应用程序运行时动态注入安全检测逻辑,实现对攻击行为的实时防护。

二、OpenRASP 启动阶段

1. 核心启动流程

  1. 入口点rasp.jarMANIFEST.MF 文件配置了关键属性:

    • Premain-Class / Agent-Class / Main-Class
    • Can-Redefine-Classes / Can-Retransform-Classes
  2. Agent初始化

    • 首先加载 Agent#premain 方法
    • rasp.jar 加入 BootStrapClassLoader 下(解决双亲委派机制问题)
  3. 服务器适配

    • 针对 JBoss 等服务器进行特殊配置

2. 引擎加载

  1. 核心引擎

    • ENGINE_JARrasp-engine.jar
    • 通过 MANIFEST.MF 中的 Rasp-Module-Class 获取主类名
    • rasp-engine.jar 加入 classpath
    • 实例化主类并调用 start 方法
  2. V8引擎

    • 用于实现跨平台支持和热部署功能
    • 支持 JavaScript 规则编写

3. 插件系统

  1. 初始化配置

    • 使用 JSON 格式保存栈信息
    • 设置信息保存的 key 值
  2. 插件更新机制

    • 获取插件绝对路径
    • 加载 official.js 等官方插件
    • 使用 V8 引擎提取信息
    • InitFileWatcher 实现配置文件实时监听

4. 检测类型加载

通过 CheckerManager.init 方法加载:

  • JavaScript 插件检测
  • Java 本地检测
  • 安全基线检测

5. 字节码转换器初始化

  1. 插桩配置

    • 调用 initTransformer(inst) 方法
    • 通过 addAnnotationHook 进行插桩
  2. Hook点发现

    • 扫描 com.baidu.openrasp.hook 包下所有类
    • 提取使用 @HookAnnotation 注解的类
    • 实例化并调用 addHook 进行插桩
  3. 类转换

    • 调用 retransform 方法
    • 通过 isClassMatched 判断是否为需要 Hook 的类

三、检测阶段原理

1. 检测机制概述

  • 在初始化阶段对危险类的危险方法进行 Hook
  • 使用 javassist(ASM框架)在危险方法中动态注入检测逻辑
  • 根据检测结果决定拦截或放行

2. XXE 检测示例

  1. Hook点筛选

    • XXEHook#isClassMatched 方法筛选 XXE 漏洞 sink 点
    • 主要关注三类:
      • org/apache/xerces/impl/XMLEntityManager
      • javax/xml/stream/XMLInputFactory
      • javax/xml/transform/TransformerFactory
  2. 字节码重写

    • CustomClassTransformer#transform 实现字节码重写
    • AbstractClassHook#transformClass 添加检测代码
    • XXEHook#hookMethod 具体实现:
      • 使用 getInvokeStaticSrc 获取 checkXXE 方法字节码
      • 注入到 expandSystemIdsetDescription 等方法前
  3. 检测流程

    • 调用栈示例:
      checkXXE:102, XXEHook
      invoke:-1, GeneratedMethodAccessor9
      expandSystemId:-1, XMLEntityManager
      ...
      parse:-1, DocumentBuilderImpl
      
    • 安全检查存在业务让步机制
    • 核心检测逻辑在 doRealCheckWithoutRequest 方法中
  4. 检测类型

    • 使用 V8AttackChecker
    • 通过 checkParam 检测 payload
    • 检测规则在 official.js 中定义

3. XXE 检测规则

  1. 禁用外部实体

    // 检测是否禁用外部实体
    if (!feature.disable_external_entity) {
        // 检测逻辑
    }
    
  2. 禁用特殊协议

    // 检测危险协议
    if (entity_expanded.indexOf("http://") === 0 ||
        entity_expanded.indexOf("https://") === 0 ||
        entity_expanded.indexOf("ftp://") === 0 ||
        entity_expanded.indexOf("jar://") === 0) {
        return "block";
    }
    
  3. file协议检测

    • 提取 file:///xxx 路径内容
    • 检查跨目录访问
    • 检查 URL 锚点使用
    • 检查内部文件读取
    • 不满足则返回 clean

四、OpenRASP 优劣分析

优势

  1. 高精准性

    • 误报率低
    • 直接作用于应用内部
  2. 0Day防御

    • 可防御部分未知漏洞
    • 可用作蜜罐
  3. 加密流量处理

    • 相比 WAF 能处理加密流量

劣势

  1. 资源消耗

    • 可能造成资源浪费
  2. 维护成本

    • 需要维护多个 sink 点
    • 容易出现检测不全问题
  3. 绕过风险

    • 如 webshell 检测中,随机类名可能绕过
    • XXE sink 点更新不及时可能导致绕过
  4. 通用性问题

    • 解决方案通用性挑战

五、总结

OpenRASP 通过运行时字节码注入技术实现了精准的应用自我保护,其核心设计包括:

  1. 基于 Java Agent 的启动机制
  2. V8 引擎支持的跨平台规则执行
  3. 动态字节码修改实现的安全检测点注入
  4. 灵活的 JavaScript 规则配置

尽管存在一些局限性,但 OpenRASP 为运行时应用安全防护提供了一种有效的解决方案,特别适合需要精准防护和高自定义需求的场景。

OpenRASP 原理与设计思想深入剖析 一、OpenRASP 概述 OpenRASP(Runtime Application Self-Protection)是百度开源的一款运行时应用自我保护产品,通过在应用程序运行时动态注入安全检测逻辑,实现对攻击行为的实时防护。 二、OpenRASP 启动阶段 1. 核心启动流程 入口点 : rasp.jar 的 MANIFEST.MF 文件配置了关键属性: Premain-Class / Agent-Class / Main-Class Can-Redefine-Classes / Can-Retransform-Classes Agent初始化 : 首先加载 Agent#premain 方法 将 rasp.jar 加入 BootStrapClassLoader 下(解决双亲委派机制问题) 服务器适配 : 针对 JBoss 等服务器进行特殊配置 2. 引擎加载 核心引擎 : ENGINE_JAR 为 rasp-engine.jar 通过 MANIFEST.MF 中的 Rasp-Module-Class 获取主类名 将 rasp-engine.jar 加入 classpath 实例化主类并调用 start 方法 V8引擎 : 用于实现跨平台支持和热部署功能 支持 JavaScript 规则编写 3. 插件系统 初始化配置 : 使用 JSON 格式保存栈信息 设置信息保存的 key 值 插件更新机制 : 获取插件绝对路径 加载 official.js 等官方插件 使用 V8 引擎提取信息 InitFileWatcher 实现配置文件实时监听 4. 检测类型加载 通过 CheckerManager.init 方法加载: JavaScript 插件检测 Java 本地检测 安全基线检测 5. 字节码转换器初始化 插桩配置 : 调用 initTransformer(inst) 方法 通过 addAnnotationHook 进行插桩 Hook点发现 : 扫描 com.baidu.openrasp.hook 包下所有类 提取使用 @HookAnnotation 注解的类 实例化并调用 addHook 进行插桩 类转换 : 调用 retransform 方法 通过 isClassMatched 判断是否为需要 Hook 的类 三、检测阶段原理 1. 检测机制概述 在初始化阶段对危险类的危险方法进行 Hook 使用 javassist(ASM框架)在危险方法中动态注入检测逻辑 根据检测结果决定拦截或放行 2. XXE 检测示例 Hook点筛选 : XXEHook#isClassMatched 方法筛选 XXE 漏洞 sink 点 主要关注三类: org/apache/xerces/impl/XMLEntityManager javax/xml/stream/XMLInputFactory javax/xml/transform/TransformerFactory 字节码重写 : CustomClassTransformer#transform 实现字节码重写 AbstractClassHook#transformClass 添加检测代码 XXEHook#hookMethod 具体实现: 使用 getInvokeStaticSrc 获取 checkXXE 方法字节码 注入到 expandSystemId 和 setDescription 等方法前 检测流程 : 调用栈示例: 安全检查存在业务让步机制 核心检测逻辑在 doRealCheckWithoutRequest 方法中 检测类型 : 使用 V8AttackChecker 类 通过 checkParam 检测 payload 检测规则在 official.js 中定义 3. XXE 检测规则 禁用外部实体 : 禁用特殊协议 : file协议检测 : 提取 file:///xxx 路径内容 检查跨目录访问 检查 URL 锚点使用 检查内部文件读取 不满足则返回 clean 四、OpenRASP 优劣分析 优势 高精准性 : 误报率低 直接作用于应用内部 0Day防御 : 可防御部分未知漏洞 可用作蜜罐 加密流量处理 : 相比 WAF 能处理加密流量 劣势 资源消耗 : 可能造成资源浪费 维护成本 : 需要维护多个 sink 点 容易出现检测不全问题 绕过风险 : 如 webshell 检测中,随机类名可能绕过 XXE sink 点更新不及时可能导致绕过 通用性问题 : 解决方案通用性挑战 五、总结 OpenRASP 通过运行时字节码注入技术实现了精准的应用自我保护,其核心设计包括: 基于 Java Agent 的启动机制 V8 引擎支持的跨平台规则执行 动态字节码修改实现的安全检测点注入 灵活的 JavaScript 规则配置 尽管存在一些局限性,但 OpenRASP 为运行时应用安全防护提供了一种有效的解决方案,特别适合需要精准防护和高自定义需求的场景。