Dubbo 高危漏洞!原来都是反序列化惹得祸

前言
这周收到外部合作同事推送的一篇文章,【漏洞通告】Apache Dubbo Provider默认反序列化远程代码执行漏洞(CVE-2020-1948)通告 。
按照文章披露的漏洞影响范围,可以说是当前所有的 Dubbo 的版本都有这个问题 。

Dubbo 高危漏洞!原来都是反序列化惹得祸

文章插图
 
无独有偶,这周在 Github 自己的仓库上推送几行改动,不一会就收到 Github 安全提示,警告当前项目存在安全漏洞CVE-2018-10237 。
Dubbo 高危漏洞!原来都是反序列化惹得祸

文章插图
 
可以看到这两个漏洞都是利用反序列化进行执行恶意代码,可能很多同学跟我当初一样,看到这个一脸懵逼 。好端端的反序列化,怎么就能被恶意利用,用来执行的恶意代码?
 
这篇文章我们就来聊聊反序列化漏洞,了解一下黑客是如何利用这个漏洞进行攻击 。
先赞后看,养成习惯!微信搜索『程序通事』,关注就完事了!
反序列化漏洞在了解反序列化漏洞之前,首先我们学习一下两个基础知识 。
JAVA 运行外部命令Java 中有一个类 Runtime,我们可以使用这个类执行执行一些外部命令 。
下面例子中我们使用 Runtime 运行打开系统的计算器软件 。
// 仅适用macos Runtime.getRuntime().exec("open -a Calculator ");有了这个类,恶意代码就可以执行外部命令,比如执行一把 rm /* 。
序列化/反序列化如果经常使用 Dubbo,Java 序列化与反序列化应该不会陌生 。
一个类通过实现 Serializable接口,我们就可以将其序列化成二进制数据,进而存储在文件中,或者使用网络传输 。
其他程序可以通过网络接收,或者读取文件的方式,读取序列化的数据,然后对其进行反序列化,从而反向得到相应的类的实例 。
Dubbo 高危漏洞!原来都是反序列化惹得祸

文章插图
 
下面的例子我们将 App 的对象进行序列化,然后将数据保存到的文件中 。后续再从文件中读取序列化数据,对其进行反序列化得到 App 类的对象实例 。
public class App implements Serializable {    private String name;    private static final long serialVersionUID = 7683681352462061434L;    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {        in.defaultReadObject();        System.out.println("readObject name is "+name);        Runtime.getRuntime().exec("open -a Calculator");    }    public static void main(String[] args) throws IOException, ClassNotFoundException {        App app = new App();        app.name = "程序通事";        FileOutputStream fos = new FileOutputStream("test.payload");        ObjectOutputStream os = new ObjectOutputStream(fos);        //writeObject()方法将Unsafe对象写入object文件        os.writeObject(app);        os.close();        //从文件中反序列化obj对象        FileInputStream fis = new FileInputStream("test.payload");        ObjectInputStream ois = new ObjectInputStream(fis);        //恢复对象        App objectFromDisk = (App)ois.readObject();        System.out.println("main name is "+objectFromDisk.name);        ois.close();    }执行结果:
readObject name is 程序通事main name is 程序通事并且成功打开了计算器程序 。
当我们调用 ObjectInputStream#readObject读取反序列化的数据,如果对象内实现了 readObject方法,这个方法将会被调用 。
源码如下:
Dubbo 高危漏洞!原来都是反序列化惹得祸


推荐阅读