前言
在网上看到的,cc链之前都是用map等类来触发transform,n1ght师傅发现了新思路,通过list同样可以导致命令执行。可惜并没有越过3.2.2版本的限制,作为一道绕过黑名单的CTF题目感觉是一个不错的思路。
学习这条链子也学到了一些新的知识点,来看一下吧QAQ
Java Agent
Java 代理 (agent) 是在你的main方法前的一个拦截器 (interceptor),也就是在main方法执行之前,执行agent的代码。
agent 的代码与你的main方法在同一个JVM中运行,并被同一个system classloader装载,被同一的安全策略 (security policy) 和上下文 (context) 所管理。
其实Java Agent一点都不神秘,也是一个Jar包,只是启动方式和普通Jar包有所不同,对于普通的Jar包,通过指定类的main函数进行启动,但是Java Agent并不能单独启动,必须依附在一个Java应用程序运行,有点像寄生虫的感觉。
在本条利用链里面,CertPath重写了writeReplace导致序列化异常,使用agent直接把这个方法移除掉。
需要打一个jar包
Agent类
1 | package org.example; |
RemoveReplaceTransformer类(使用了javassist,需要导入依赖)
1 | package org.example; |
在resources目录下新建目录META-INF,然后新建文件MANIFEST.MF文件写入一下内容,然后就是打jar包
1 | Manifest-Version: 1.0 |
在运行poc设置
并且填入(-javaagent:后接jar包路径就可以)
1 | -javaagent:D:\ctf\学习笔记\java安全\反序列化\agrnt\out\artifacts\CCTestAgent\CCTestAgent.jar |
Unsafe
Java语言先比较与C和C++有一个非常大的不同点在于Java语言无法直接操作内存,实际开发中,默认都是由JVM来进行内存分配和垃圾回收,而JVM在进行垃圾回收的时候,绝大多数垃圾回收器都需要STW(stop the world)这个问题往往会导致服务短暂或者较长时间的暂停。因此Unsafe提供了通过Java直接操作内存的API,尽管Unsafe是JavaNIO和并发的核心类,但是其如其名,这是一个官方不推荐开发者使用的及其不安全的类!
EXP
1 | package exp; |
调用链
注意,禁用这个,不然调试自动调用toString方法会出问题
1 | exec:347, Runtime (java.lang) |
调试了好久,还是不能按部就班得调,人都调昏了,先在Runtime得exec方法打上断点,然后获得上面的调用栈,然后根据调用栈直接运行到相应方法上面,一针见血。
先打到readObject上面,然后步入add方法里面
接着直接运行到java.security.CodeSigner#toString
方法
步入进get(0)方法
然后再步入到set方法,看到我们熟悉的transform方法了
后记
拿张图看看吧
参考:
java反序列化漏洞commons-collections3.2.1TransformedList触发transform - 先知社区 (aliyun.com)
Java之Unsafe-越迷人的越危险 - 掘金 (juejin.cn)
Java中的Unsafe在安全领域的一些应用总结和复现 - bitterz - 博客园 (cnblogs.com)
Java Agent (JVM Instrumentation 机制) 极简教程-腾讯云开发者社区-腾讯云 (tencent.com)