杂谈RASP

简单记录一下最近几个月来的调研和学习。

RASP与IAST

RASP和IAST同样都应用了插桩技术,但是两者的侧重点不太一样。

RASP,运行时应用自我保护,我认为其是在WAF和HIDS之间的一个定位。

  • 相比于WAF是作用于流量请求的拦截,不会考虑程序内部数据流,RASP技术则是根据请求上下文进行拦截的,误报率(比如程序内部已经消毒,不存在威胁)这块应该会低一些,也不会出现像WAF被绕过(${${123:-j}${456:-n}di:rmi://127.0.0.1:1099/evil})这类的漏报。
  • 而HIDS作为安全的最后一道防线,大部分是基于进程进行监控,打个比方说检测命令执行,Agent端把所有服务器信息,文件操作行为、网络连接、执行命令等等采集交给Server端,然后Server端基于规则进行匹配,再实时预警,但是进程监控能检测到,就代表在Web上已经被攻陷,所以HIDS的侧重点并不在Web程序上。

再说说IAST(Interactive Application Security Testing)交互式应用安全测试,IAST通常是作为上线前的测试环境使用,在模拟黑客外部攻击的同时,对内部实时数据进行监视,提高测试精度,目前IAST主要分主动插桩(百度开源的openrasp-iast)和被动插桩(洞态IAST)两种模式,之前接触过洞态IAST,所以简单介绍一下被动式。

因为是适用于测试环境,所以IAST对性能损耗要求不是那么高,IAST的I指的是Interactive——>交互,所以相比于RASP,IAST需要对上下文及输入输出更加敏感一些。

洞态对IAST规则划分了HttpSourcePropagatorSink四个类别:

image-20220321173851528

  1. Http:通过劫持Http(不同框架处理Http请求可能不一样),我们可以获取到原始的Servlet请求,相当于把Servlet数据进行了克隆,需要的时候再取出来。
  2. 后部分完全可以用污点分析的角度来处理:

污点分析可以抽象成一个三元组〈sources,sinks,sanitizers〉的形式,其中,source 即污点源,代表直接引入不受信任的数据或者机密数据到系统中;sink 即污点汇聚点,代表直接产生安全敏感操作(违反数据完整性)或者泄露隐私数据到外界(违反数据保密性);sanitizer 即无害处理,代表通过数据加密或者移除危害操作等手段使数据传播不再对软件系统的信息安全产生危害.污点分析就是分析程序中由污点源引入的数据是否能够不经无害处理,而直接传播到污点汇聚点.如果不能,说明系统是信息流安全的;否则,说明系统产生了隐私数据泄露或危险数据操作等安全问题.

image-20220321180314243

实现Source埋点需要我们劫持所有用户可控的输入源,比如 getParametergetHeader等函数,并对返回的值进行跟踪,一般认为所有用户可控的值都是有害的。

对于Sink的选择,其实和RASP大同小异,找到危险操作最后的触发点进行埋点即可。

最后也是最重要的部分,就是Propagator(污点传播),按照白盒的理论,我们需要处理所有调用链中的输入和输出,判断是否可达,其中需要考虑sanitizers(消毒处理),我们认为所有经过有效消毒之后的变量是无害的。在CODEQL中,定义了source和sink之后的 Path queries才是最重要的。IAST中如果传播点选择的覆盖率越广,传播的链路也就越清晰,但随之的问题就是堆栈太大。

但RASP和IAST也不是百分之百的捕获率,每个节点的传播都是一环扣一环。拿命令执行的例子来说,对于java.lang.Runtime.getRuntime().exec(),洞态可以很好的检测到命令执行,但是更往底层一点的UNIXProcess().forkAndExec(),因为Sink点并选取,导致无法检测。

image-20220320221137381

JAVASSIST还是ASM

说到插桩,JAVA自然就离不开字节码,字节码操作框架有ASMJavassistByte-Buddy,这三者越往前越底层,越往后操作起来越简便。了解到的使用情况:

Elkeid:ASM

jrasp:ASM

洞态IAST:ASM

openrasp: javassist

这样来看ASM这种直接和字节码接轨的框架还是更加受欢迎。

语言问题如何解决

JAVA的处理方案现在相对比较成熟,看看其他语言是怎么处理的。

  • nodejs

image-20220321225543594

node 同 java,是基于原生环境所所提供的机制——>node-inspect

  • python

image-20220321225809197

python是基于进程,利用ptrace实现注入。

  • Golang

image-20220321225954324

Golang同python也是用ptrace实现进程注入。并且作者专门写了工具pangolin相对稳定的在目的进程的基础上加载新进程。

RASP的一些缺陷

对于甲方来说,如果我买一套设备,自然是要和自己的业务挂钩,而乙方应该很难去对不同业务做定制化规则,所以更多时候都是甲方自己的内部人员去基于开源项目二次开发,在openrasp和洞态的社区就有很多这样的例子。

虽然说语言上的问题暂时解决了,但不同的框架,不同的中间件,部署上又不一样。目前我测试的都是一台机器,但实际的生产环境肯定远不如如此,部署上不好推动的话,很多公司可能就直接把这个服务一刀切了,这也是为什么之前说了RASP那么多好,WAF和HIDS的推广度还是远远领先。

不过在log4j2爆发之后,还是可以看到很多直接被RASP拦截的例子,总的来说这还是Web层面应用防御的发展趋势,至于其他零零碎碎的问题,我现在也只是站在一个学生的角度去看待,看了一些文章,提出一些拙见,等真正工程化的那一天,可能就变了呢。

参考