1、背景

RASP(Runtime application self-protection)是一项运行时应用程序自我保护的安全技术,通过搜集和分析应用运行时及其他相关信息来检测和阻止针对应用本身的攻击,其典型的防护流程如图1所示。

图1 RASP典型防护流程

1.1 RASP和IAST在应用场景上有明显区别

IAST(交互式应用程序安全测试)是一种新的应用程序安全测试方案,可以通过代理或者在服务端部署Agent程序,收集、监控Web应用程序运行时函数执行、数据传输,并与扫描器端进行实时交互,高效、准确的识别安全缺陷及漏洞,IAST典型的运行流程如图2所示。当然有一类被动型IAST不会和DAST结合,只是检测污点数据是否被带入到安全敏感函数。RASP可以利用服务端集成SDK或者部署Agent程序监控运行软件内部的信息来检测和阻止计算机攻击,RASP可以和IAST使用相同的Agent技术,不同之处是RASP的使用场景更偏向防御和告警,而IAST偏向于做安全测试,进一步考虑的话,可以用RASP结合DAST达到IAST的效果。

图2 IAST典型运行流程图

1.2 RASP和网络WAF相比有差异化的优势

网络WAF无法感知应用程序上下文也无法输出漏洞攻击链,RASP无需像WAF需要考虑各种网络请求复杂编码,只需要在对应的SINK点进行插桩检测等,并且由于RASP嵌入在应用内部,可以在感知程序上下文的情况下检测和阻止攻击,因此可以利用RASP对网络WAF进行有效的补充以构建更完善的安全防护体系。

2、技术选型

由于中通内部应用开发以Java为主,所以研究Java类应用RASP成了安全团队的主要任务。目前Java类应用RASP的主要实现方式是JavaAgent和SDK,JavaAgent和SDK相比可以做到对用户代码无任何侵入,并且可以做到防护规则的热更新。实现JavaAgent代码插桩的框架主要有ASM,Javassist, Byteman等。三者对比之下,ASM在这几个框架里面插桩效率是最高的,但使用起来更复杂一些。综合考虑了开发成本和社区活跃度,我们选择了百度基于Javassist开源的OpenRasp并针对性地作了一些改进和优化,在此向百度安全团队致谢。

3、整体方案

我们的整体方案主要包括管理后台、Agent以及一些针对性的优化改进设计。

3.1 管理后台架构

管理后台架构沿用百度开源部分,相关的中间件做了集群和负载模式,具体可见https://rasp.baidu.com/doc/hacking/architect/cloud.html。

图3 OpenRasp管理后台架构

3.2 Agent设计

当RASP Agent以JVM指定代理的方式启动时,Instrumentation实例会传递到代理类的Premain方法,此外JVM还提供了一种在启动之后的某个时刻启动代理的机制,此时Instrumentation实例会传递到代理类代码的Agentmain方法。在ClassFileTransformer类中实现Transform函数,在需要插桩的类和函数插入污点传播和安全检查算法。当应用收到用户请求后,应用运行到安全敏感函数时会首先检测参数值为污点字符并被安全检查算法判断为攻击行时将攻击日志落盘并保存到Elasticsearch中,Agent的运行流程如图4所示。

图4 Agent运行流程

3.3 优化改进

3.3.1动态污点追踪

借助动态污点追踪技术,我们能判断有害变量是否出现在安全敏感函数(例如执行SQL语句处,SpEL表达式执行处 )。动态污点追踪技术是一种信息流分析方法,能够记录数据的传播过程并找出数据之间的依赖关系。动态污点追踪简化之后可以分为如下三个部分:

  • 污点源(Source),一切输入都是有害的,将用户所有可控的变量都标记为污点源。可以在容器或者网络框架获取用户参数的函数位置标记。

  • 污染传播(Propagation),记录污点传播过程,利用用字符串hashCode作为有向图的顶点,污点传播路径可以用有向图的深度或广度遍历寻找。

  • 污点下沉点(Taint Sink),在安全敏感函数插桩,在此判断敏感函数参数是否为污点并运行OpenRasp检测插件的逻辑。

借助动态污点追踪技术,我们可以更加清晰地看见攻击数据流向,方便复盘和查阅漏洞,由于动态污点追踪会涉及到图路径的搜索,所以只推荐在测试环境中作为IAST使用。

3.3.2熔断保护机制

客观上RASP会存在一些硬件资源的占用,比如CPU、内存、硬盘等。所以在线上环境部署之时一定要考虑大并发下资源消耗殆尽的情况。OpenRasp中存在CPU占用过高时关闭检测的策略,相对应的还应该补充和完善内容熔断、硬盘熔断等保护机制。

3.3.3整合Dependency检测服务

由于Java Agent只能修改JVM中的字节码而不能修改替换JAR文件,可以在不重启的情况下修改JVM进程中的字节码起到打临时热更新补丁的作用,但是在此基础上还需要对有问题的JAR文件进行升级替换,特别是对于Dependency爆发0day的情况,更合适的方法是结合Dependency检测服务。内部自研的Dependency检测服务可以快速识别某个Java应用第三方依赖的风险。在某个Dependency爆发0day时,可以通过RASP获取应用程序的JAR文件,并将其发送到Dependency检测服务。不仅可以客观地评估0day的影响范围还可以方便精准指导和推动应用升级Dependency。除此之外,Dependency检测服务还可以集成到内部DevOps平台,可以在CI/CD时及时检测风险并阻断整个发布流程,强制要求升级替换有问题的JAR文件。

4、部署实践

由于RASP是要部署在线上系统,所以对性能损耗的控制要求很高。在上线前需要进行全面压测,出一份Rasp-Agent部署前后的性能损耗对比,并针对性优化算法和减少Hook点,并根据测试和优化结果决策是否可以部署。测试数据对比样例如图5所示。

图5 测试数据对比样例

5、未来展望

由于RASP和APM的实现原理都是修改JVM类字节码,可能会存在修改字节码之后互相干扰的情况。未来会尝试和APM团队共同拟定一套字节码插桩规范以确保相关逻辑相互独立不受影响。RASP在原本的运行程序中嵌入了检测攻击逻辑,无可厚非地会占用一部分硬件资源,如何在性能损耗和漏洞检测之间平衡还需要在实践中持续优化和探索,我们仍然处于一个比较初级的阶段。目前有一个方案是在RASP前面加联动网络WAF判断,对高风险请求进行RASP防护。

另外RASP可以作为应用层的分布式WAF节点,将之打造成安全纵深防御体系的一个安全策略执行点,对外提供安全策略输入的API开放接口和相关日志的吐出通道,对接整体的安全风控策略中心和日志分析中心。

参考:

https://rasp.baidu.com/doc/hacking/architect/cloud.html

https://www.jianshu.com/p/5c62b71fd882

声明:本文来自中通安全应急响应中心,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。