来源极客时间《安全攻防技能30讲》
以下是自己总结笔记,仅用于学习思考!
一、反序列化漏洞是如何产生的?
反序列化操作,也就是应用将字符串或者字节流变成对象。
反序列化漏洞到底是怎么产生的呢?问题就出在把数据转化成对象的过程中。在这个过程中,应用需要根据数据的内容,去调用特定的方法。而黑客正是利用这个逻辑,在数据中嵌入自定义的代码(比如执行某个系统命令)。应用对数据进行反序列化的时候,会执行这段代码,从而使得黑客能够控制整个应用及服务器。这就是反序列化漏洞攻击的过程。
简单的四个步骤:
1、黑客构造一个恶意的调用链(专业术语为 POP,Property Oriented Programming),并将其序列化成数据,然后发送给应用;
2、应用接收数据。大部分应用都有接收外部输入的地方,比如各种 HTTP 接口。而这个输入的数据就有可能是序列化数据;
3、应用进行反序列操作。收到数据后,应用尝试将数据构造成对象;
4、应用在反序列化过程中,会调用黑客构造的调用链,使得应用会执行黑客的任意命令。
在这个过程中,应用必须根据数据源去调用一些默认方法(比如构造函数和 Getter/Setter)。
二、反序列化漏洞的利用
1、通过反序列化漏洞,黑客可以调用到Runtime.exec()来进行命令执行。
2、黑客还是能够利用反序列化漏洞,来发起拒绝服务攻击。
3、黑客可以通过构建一个体积很小的数据,增加应用在反序列化过程中需要调用的方法数,以此来耗尽 CPU 资源,达到影响服务器可用性的目的。
三、如何进行反序列化漏洞防护 ?
1、认证和签名
首先,最简单的,我们可以通过认证,来避免应用接受黑客的异常输入。要知道,很多序列化和反序列化的服务并不是提供给用户的,而是提供给服务自身的。比如,存储一个对象到硬盘、发送一个对象到另外一个服务中去。对于这些点对点的服务,我们可以通过加入签名
的方式来进行防护。比如,对存储的数据进行签名,以此对调用来源进行身份校验。只要黑客获取不到**信息,它就无法向进行反序列化的服务接口发送数据,也就无从发起反序列化攻击了。
2、限制序列化和反序列化的类
我们可以通过构建黑名单的方式,来检测反序列化过程中调用链的异常。(在反序列化漏洞中,黑客需要构建调用链,而调用链是基于类的默认方法来构造的。然而,大部分类的默认方法逻辑很少,无法串联成完整调用链。)
3、RASP(实时程序自我保护) 检测
RASP 通过 hook 等方式,在这些关键函数的调用中,增加一道规则的检测。这个规则会判断应用是否执行了非应用本身的逻辑,能够在不修改代码的情况下对反序列化漏洞攻击实现拦截。简单来说,通过 RASP,我们就能够检测到应用中的非正常代码执行操作。