反序列化漏洞

序列化就是把一个对象变成可以传输的字符串,目的就是为了方便传输。 反序列化和序列化是两个正好相反的过程。

反序列化漏洞的原理:

序列化和反序列化本身并不存在问题。但当反序列化的数据可被用户控制,那么攻击者即可通过构造恶意输入,让反序列化产生非预期的对象,在此过程中执行构造的任意代码。 php比较少,Java中出现的很多,因为php中还需要满足后台不正当的使用了PHP中的魔法函数的条件

  • PHP反序列化函数: serialize(),unserialize()
  • Java反序列化函数: ObjectOutputStream的writeObject()和ObjectInputStream的readObject()。

php常见的几个魔法函数:

#魔法函数前边都会有__
__construct()当一个对象创建时被调用
__destruct()当一个对象销毁时被调用
__toString()当一个对象被当作一个字符串使用
__sleep() 在对象在被序列化之前运行
__wakeup将在序列化之后立即被调用

PHP反序列化漏洞实战

在线反序列化工具:***.com

# 已序列化数据
O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";} 
# 反序列化后的结果
Array{
  [__PHP_Incomplete_Class_Name]=>S
  [test]=><script>alert('xss')</script>
}

怎么构造payload呢 通过更改序列化之后的变量值,之后将payload写入一个接受序列化数据的API中就可以了

小结 回看整个过程就是 对象通过序列化变为字符串,我们对字符串做手脚,再交给有漏洞的地方进行反序列化

反序列化漏洞防御:

类的白名单校验机制:

对所有传入的反序列化对象,在反序列化过程开始前,对类型名称做一个检查,不符合白名单的类不进行反序列化操作。很显然,这个白名单肯定是不存在Runtime的。

禁止JVM执行外部命令Runtime.exec

这个措施可以通过扩展 SecurityManager 可以实现。

PHP防御

  1. 安全配置好php相关参数:禁止某些php函数, 服务器便是用这个来禁止php的执行命令函数。 # 禁止用这些函数来执行系统命令。 disable_functions =system,passthru,shell_exec,exec,popen
  2. 升级中间件
  3. 严格控制传入变量,严谨使用魔法函数

weblogic防御

  1. 过滤T3协议,限定可连接的IP
  2. 设置Nginx反向代理,实现t3协议和http协议隔离
  3. JEP290(JDK8u121,7u131,6u141),这个机制主要是在每层反序列化过程中都加了一层黑名单处理

原生反序列化防御

  1. 不要反序列化不可信的数据
  2. 给反序列数据加密签名,并确保解密在反序列之前
  3. 给反序列化接口添加认证授权
  4. 反序列化服务只允许监听在本地或者开启相应防火墙
  5. 升级第三方库
  6. 升级JDK,JEP290