You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 lines
12 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 22 | RASP写规则写得烦了尝试一下更底层的IDS
你好,我是何为舟。
在前面的课程中我们已经介绍了防火墙、WAF和入侵检测。这些产品都有一个共同的特性就是基于网络请求或者系统行为对攻击的特征进行检测然后再采取相应的防控手段。这些安全产品基本都和应用本身解耦。也就是说基本上我们不需要对应用做任何开发和改动就能够部署这些安全产品。
尽管解耦在部署上能够节省很大的成本,但解耦同样意味着,安全产品和应用本身是通过接口、请求等形式来进行数据交换的。换一句话说,安全产品只能够看到应用输入和输出的数据,并不知道数据在应用内的流动情况。因此,这种工作模式不可避免会产生一定的误判和漏报。
我们来看一个关于WAF检测SQL注入的例子。下面是请求代码
```
http://server.com/login?username=test&password=" or ""="
```
WAF可能会检测到password参数中的SQL注入痕迹进行拦截。如果应用采用的是安全的PreparedStatement方法那这个SQL注入就不会生效也就不需要拦截。但是WAF和应用解耦让WAF不知道应用的逻辑从而产生了误报。
所以对于任何安全产品来说能获取到的数据和信息越多检测的能力就越强误判和漏报的概率也就越低。因此2012年Gartner提出了RASPRuntime Application Self Protection的概念就是希望将安全产品部署在应用的底层完全站在应用的视角去发现攻击行为从而实现更加完善的安全防护。
## RASP的原理
想要利用RASP实现更完善的安全防护首先我们要知道什么是RASP以及如何实现RASP
RASP的设计思路是通过监控应用的底层来从根本上发现攻击行为的产生。
以Java为例Java应用运行在JVM之上。因此JVM就是一个底层它能够看到所有的应用信息。我们可以通过[JavaAgent](https://www.jianshu.com/p/63c328ca208d)的形式将RASP运行在JVM上然后借助[Instrumentation](https://www.ibm.com/developerworks/cn/java/j-lo-jse61/index.html)技术Hook关键的类和方法。关键类和方法具体有哪些你可以参照OpenRASP的[Hook列表](https://rasp.baidu.com/doc/hacking/architect/hook.html)。这样一来RASP就能关注到应用安全相关的信息和调用了。
![](https://static001.geekbang.org/resource/image/b5/b7/b5634e94b5607221dee2ed3680c0efb7.jpg)
同样的原理在PHP中我们可以通过PHP扩展库来实现RASP在.Net中我们可以通过HostingStartup来实现RASP。
如果你想要研究RASP产品那我推荐你使用百度的[OpenRASP](https://rasp.baidu.com/#section-intro)。因为OpenRASP在开源市场中认可度比较高也是目前各个公司用来研究RASP产品的一个主要对象。
## RASP的优势和劣势
我们经常会将RASP和WAF拿来做比较因为它们主要关注的都是应用相关的Web安全问题。那么对比WAFRASP有哪些优势和劣势呢
首先我们来看优势。在开头我们就提到了RASP对比于WAF最大的优势在于RASP运行在应用的底层从而能够知道应用运行时的上下文比如用户、代码逻辑、SQL语句等。在Web安全中我们针对Web安全的攻击原理进行过总结SQL注入、反序列化等漏洞其实都是通过输入数据篡改应用的正常逻辑实现的攻击。
对于WAF来说它只能够判断出输入的数据“可能”会篡改应用的正常逻辑因此WAF的拦截决策都来源于这个可能性。而对于RASP来说它知道应用的正常逻辑是什么也知道应用接收输入后实际的逻辑是什么如果实际逻辑和正常逻辑不一致就必然发生了攻击。基于这种检测方式RASP基本不会产生误报或者漏报。
我们以OpenRASP防止SQL注入的[检测逻辑](https://github.com/baidu/openrasp/blob/master/plugins/official/plugin.js)为例来看一下RASP是如何进行检测的。算法描述如下
![](https://static001.geekbang.org/resource/image/a2/19/a2230de2106ad352ef33bb838b0cf719.jpg)
第1步和第2步很好理解都是SQL注入的基本特征。那第3步中的“导致SQL语句逻辑发生变化”OpenRASP要如何去识别呢假设用户的输入是万能密码"or""="那么应用实际执行的SQL语句就是
SELECT \* FROM Users WHERE Username = “” AND Password = ““or””=""
在这个SQL语句中最后的几个字符都是用户的输入。为了检测语句逻辑的变化OpenRASP将这个SQL语句进行了Token化。所谓“Token化”就是对SQL语句中的关键词进行拆解拆解后分别是SELECT、 \*、FROM、Users、WHER、Username、=、""、AND、Password、=、""、or、""、=、""。我们能够清楚地看到,用户的输入“"“or “”=”"”占据了5个Token。而正常情况下用户的输入应该只占据1个Token。因此只要用户的输入大于1个Token就说明SQL语句逻辑存在变化我们就可以断定存在SQL注入了。
其次RASP能够防范未知的攻击。对于SQL注入来说它的注入点可以是某个GET参数、某个POST的Body、某个Header字段等具体的攻击方式也多种多样盲注、基于Insert的注入等。
WAF的检测规则是一个一个去覆盖这些攻击点和攻击方式。如果黑客发现了某个新的攻击点或者使用了新的攻击方式WAF根本无法检测出来。
对于RASP来说它实际上不关注具体的攻击点和攻击方式是什么因为SQL注入攻击最终都会使SQL语句Token化后的长度发生改变。因此RASP只需要判断执行的SQL语句Token化后的长度即可。所以我才说RASP能够有效地防御未知的攻击。
最后我认为RASP还有一个比较特别的好处就是基本不用维护规则。我前面讲过的各类安全产品防火墙、WAF和入侵检测它们的本质都是检测攻击行为。而这些安全产品的检测方式不论是签名匹配、正则匹配还是行为分析都包含了大量的规则和算法。这些规则和算法带来的最大问题就是针对每一家公司我们都需要制定一套单独的规则和算法。因为每家公司的应用和网络环境都不一样面临的攻击也不一样。
随着公司的发展以及黑客的对抗升级我们还需要不停地更新和维护这套规则和算法这就带来了极大的运营成本。而对于RASP来说它当然也需要规则和算法来支持但是它的规则和算法相对统一。
比如在Java中不论你是使用的哪种开发框架最终执行SQL语句的都是底层的JDBC插件在这个层次上攻击的特征都是一致的。因此RASP基本只需要维护一套统一的规则和策略就能够适用于所有的公司和应用了。所以百度在OpenRASP[覆盖面说明](https://rasp.baidu.com/doc/usage/web.html)中敢说“若发现不能拦截的攻击或者误报的情况请联系我们”就是这个原因。开源的WAF只会提供一个维护规则的入口而不会帮助你进行维护。
尽管RASP存在许多明显的优势但是目前来看国内对于RASP的实际落地普遍还在试验阶段我很少见到RASP在公司范围内大规模推广落地案例。这是为什么呢要搞清楚这个问题就不得不提到RASP的劣势了。RASP的劣势主要有三方面下面我们一一来看。
我认为最大的劣势在于推广难度上。尽管我们一直在提安全但是事实上大部分的开发人员并不认可安全他们也不接受任何可能对应用产生影响的安全产品。这是因为这些安全产品增加了检测的逻辑就必然会影响应用的正常运行。而且WAF等拦截性安全产品产生的误报会让正常的业务请求受到影响。
但是防火墙、WAF和入侵检测实际上都已经在各个公司很好地落地了。我认为这都归功于安全人员或者运维人员的“强推”。
在部署一款WAF的过程中实际上是不需要开发人员参与的运维人员在网关上直接部署就可以了。而RASP不一样RASP和应用强耦合它需要由开发人员去部署。比如Java中需要通过命令java -javaagent:rasp.jar -jar app.jar来启动RASP其中的参数javaagent只能由开发人员进行配置。因此RASP的推广实际上是安全意识的推广所以难度也比较高。
其次RASP的解决方案并不通用。从语言支持上来看目前RASP只在Java、PHP和.Net语言中具备成熟的产品。其他高级语言如Python等可能是因为没有很好的Hook方案所以目前仍然局限于研究阶段。这也是RASP强耦合所带来的弊端每一种开发语言甚至是语言下不同的开发框架都可能会需要一套独立的RASP产品。而WAF等安全产品因为网络和系统都比较统一则不受此限制。
最后RASP在性能问题上也备受争议。尽管目前成熟的RASP产品宣称它的性能影响已经低于5%甚至更低了但在实际落地的过程中确实会出现因为系统和应用的差异而导致性能恶化比较严重的情况。这也是RASP在兼容性不足上所表现出来的缺陷。
## RASP的其他功能
除了针对应用的攻击行为进行检测和拦截和WAF一样RASP也能够提供很多额外的安全防护功能。
毫不夸张地说WAF能实现的功能RASP都能够实现。因此WAF中的数据保护、虚拟补丁等功能RASP也都能够提供原理也是一致的都是通过拦截并修改HTTP请求和响应在HTTP内容中加入额外的安全特性比如Cookie加密。
除此之外因为RASP部署于应用的底层知道应用的全部信息所以它本身可以对应用的安全性进行评估。最简单的评估问题如下
* 是否使用ROOT权限运行了应用
* 在连接数据库的时候,是否使用了弱密码;
* 使用了哪些插件,插件是否包含漏洞。
RASP可以在应用运行的过程中对这些高危的进程操作进行检测从而提醒你采取更安全的实现方式。
## 总结
好了,今天的内容差不多了,我们一起来总结一下,你需要掌握的重点内容。
RASP的功能确实能给应用的安全性带来一个质的提升。对比低耦合的WAF等安全产品RASP的准确率、覆盖度都有较大优势。但是正因为耦合度过高RASP部署起来比较麻烦实际推广落地的时候经常出现开发人员不配合的情况。总的来说推广的难度属于管理上的问题需要你想办法说服开发人员。单纯从安全角度上来说我认为RASP是一款提升应用安全性的最佳安全产品。
另外我认为在实际工作中我们也可以将RASP和其他安全产品进行适当 组合以达到取长补短的目的。比如说RASP推广比较难我们可以只做局部的部署。这些局部的部署可以当作WAF的样本数据来源只要RASP在底层发现了攻击行为就将相应的表层特征输出到WAF。这样一来我们就可以将RASP在局部上的防御能力拓展到整体的WAF上从而实现全面的安全防护提升。
![](https://static001.geekbang.org/resource/image/7f/06/7fb30045c6ee01b1b281187e92d4dc06.jpg)
## 思考题
最后,给你留一道思考题。
在这一讲中我们只是以SQL注入为例讲述了RASP是如何进行攻击检测的。你可以思考一下对于其他的攻击方式如反序列化漏洞、命令执行和SSRF等RASP又该如何防护呢你可以先学习一下OpenRASP的说明文档之后再来思考这个问题。
欢迎留言和我分享你的思考和疑惑,也欢迎你把文章分享给你的朋友。我们下一讲再见!