恶意软件
ClingSTUN:路由器后门的两条连接
ClingSTUN 利用旧漏洞控制联网设备,借公共 STUN 查询公网地址,再从另一条 TCP 连接接收命令。公共服务器仍可正常提供服务,排查要追到发起连接的进程和设备上的驻留程序。

文章导航
路由器连向一台视频通话也会使用的公共服务器,这条出站记录该不该追?ClingSTUN 恰好利用了这类服务:它先向公共 STUN 服务器询问自己的公网地址与端口,再等待后续控制流量。那台回答地址的服务器可以照常提供合法服务,发起请求的设备却已经装上了后门。
Fortinet 旗下 FortiGuard Labs 在 10 月 5 日公开的分析描述了这个 Linux 后门。攻击者从联网设备的已知漏洞进入,程序随后修改启动文件、干扰其他进程,并建立远程执行通道。研究团队按恶意程序下载源的变化,把观察记录分成三个时期,详细分析的是第二、第三时期的 x86-64 样本。
公共 STUN 返回地址,控制包到达后,设备再连接另一个 TCP 对端接收命令。这两条连接需要沿设备上的进程关联起来。封禁公共 STUN 可能先打断正常语音或 WebRTC 功能,留下的启动项和执行权限仍在。调查应从发起请求的进程追到后来的执行动作。
1 后门进来之前,旧入口还开着
FortiGuard 最先记录的入口是 Hytec Inter HWL-2511-SS 工业路由器的 CVE-2022-36553。CVE 记录把受影响范围写为 v1.05 及以下,位置是 /www/cgi-bin/popen.cgi,问题类型为命令注入。请求中的输入进入系统命令执行,给了攻击者下载并启动程序的机会。公开记录没有提供该固件完整源码及修复差异,无法据此给出一个经过核对的内部函数名或首修提交。
这个型号已有可核对的厂商处置入口。Hytec 的 2023 年 10 月 26 日公告确认过入侵与恶意程序感染,要求更新固件并收紧远程管理。截至本次核查,产品页仍提供 Ver. 111 固件,同时标注销售结束。该公告没有把每项修复逐一对应到 CVE,安装前应让支持方确认手中硬件、当前版本及这个包的适用性,不能用一个更大的版本号代替确认。
对尚未发现入侵的同型号设备,先撤下公网管理入口,再按厂商确认的固件升级。管理仍有需要时,限制到受控管理网络或明确授权的来源。更换端口只能改变服务出现的位置,命令注入代码仍会处理到达的请求。升级需要重启,应为设备承担的数据采集或转发准备替代路径,失败时保持隔离,不退回已知受影响固件继续对外服务。恢复后核对实际运行版本,并从受控的管理网络确认访问限制与正常转发均已生效。
后续记录里的入口扩大到 EnGenius、D-Link、Realtek、TP-Link 等设备的旧漏洞,第三时期还继续增加目标。一个产品的固件更新只能关闭它自己的入口。设备若已出现 .cling 文件、启动项改动或下文的进程伪装,处置还要覆盖已写入的程序和配置,升级结束与入侵清除分别验收。
2 STUN 告诉设备,外面看见的地址是什么
私网设备发出的数据包经过 NAT 时,路由器会把来源地址与端口改成对外使用的值。设备知道自己绑定的本地端口,却未必知道外面的服务器实际看见什么。STUN 的 Binding 交换解决的就是这个问题:服务器把收到请求时看见的来源地址写进响应,设备再读回来。RFC 8489 的工作过程解释了这条往返,语音和 WebRTC 等应用也依赖这种信息建立连接。
可以把一个文档示例端点 192.0.2.1:50000 放进响应,看看设备怎样取回它。STUN 先有 20 字节头,里面包含消息类型、后续内容长度、固定值 0x2112A442 和 12 字节事务标识。事务标识把响应与之前的请求配对。成功响应中的 XOR-MAPPED-ADDRESS 再携带外部端点,IPv4 地址与固定值异或,端口与它的高 16 位异或,客户端做同样运算便还原出原值。
文档示例:192.0.2.1:50000
地址:0xc0000201 XOR 0x2112a442 = 0xe112a643
端口:0xc350 XOR 0x2112 = 0xe242
属性:0020 0008 0001 e242 e112a643
还原:192.0.2.1:50000
上面的数值来自一个只处理内存字节的离线模型,没有发送数据包。异或使用公开固定值,服务端和客户端都能直接计算,它承担字段编码的工作。读出这个端点,只回答了“这台 STUN 服务器看见什么”。另一台主机能否往这里发包、包能否穿过设备前面的 NAT 和过滤规则,还需要实际连接条件。
ClingSTUN 在随机本地端口上建立 UDP 套接字,向一组公共端点发送 Binding 请求。第二时期的样本使用 24 个端点,至少一半交换成功后继续,第三时期缩到 13 个并要求全部成功。它还周期性地向这些端点发送组标识和映射端口列表。
3 命令从后来建立的 TCP 连接进入
控制包能否到达,受 NAT 的映射、过滤方式和当时仍存活的连接状态影响。公开分析没有找到独立协调服务器的注册过程,操作者如何获得外部映射、又如何把控制流量送过 NAT,仍未核实。公共 STUN 在后续协调中是否参与了其他工作,也缺少已确认的执行记录。
报告能继续追到的是控制包到达以后的执行。程序保留的 UDP 套接字收到一类 20 字节控制报文,其中的命令 1 触发另一条出站 TCP 连接。连接目标来自控制报文,程序从该 TCP 对端接收命令并执行。这样,公共 STUN 回答地址查询,后来的 TCP 对端承担命令传递,两者在执行链上的工作不同。标准 STUN 头与这类控制报文都出现“20 字节”,长度相同并不能说明格式或作用相同。
这个区别直接影响网络调查。报告列出的三个恶意程序下载源,可以用于追查设备是否取过程序。公共 STUN 地址则应结合发起进程和业务用途调查。后续陌生 TCP 连接需要再与该进程的 UDP 接收时间、子进程启动及执行痕迹关联。只有一个目的 IP 命中,无法把下载、地址查询和命令执行三种动作全部补出来。
样本还内置了针对七个漏洞的传播代码。这个数量说明它具备哪些攻击功能,公开报告没有逐项给出这七条路径在每台受害设备上的成功记录。对已经确认感染的设备,应检查其向外发出的连接和相邻设备的记录,确定它在本地承担过哪些动作,再决定需要扩大到哪些资产。
4 进程列表也被它动了手脚
沿发起连接的进程回查,会遇到 ClingSTUN 的另一层处理。程序先把自己复制到 /root/.cling 与 /usr/local/bin/.cling,赋予执行权限,再向 /etc/inittab、/etc/init.d/rcS 和 /etc/rc.d/rc.boot 追加启动内容。设备实际采用哪个初始化系统、哪些文件会被读取,决定这些改动能否在下一次开机生效。恢复时要把实际生效的启动配置与可信基线比较,并检查设备重启后的启动结果。
随后,它清空原始命令行参数,让 ps 等工具显示的命令行变空。Linux 对 cmdline 的说明提醒,进程可以改写这片参数内存。一个空命令行需要结合可执行文件、启动来源和连接继续核对,不能据此把进程当成系统任务,也不能把所有空命令行都判为感染。
在 UID 为 0(root 身份)的分支里,样本还从 /proc/1/ 复制部分进程信息到 /tmp,再把 /tmp 绑定挂载到自己的 /proc/<pid> 上。PID 1 是编号为 1 的初始进程。proc 文件系统原本提供内核中的进程信息,绑定挂载则让另一棵目录出现在同一个访问位置。调查工具沿这个路径读取时,可能读到拷贝的 PID 1 元数据。正在运行的恶意进程没有因此取得 PID 1 的真实身份,变动发生在工具看到的目录内容。
这也解释了为什么只换一个依赖 /proc 的查看工具,可能继续看到相同伪装。应保存当前挂载关系与进程、网络记录,再从可信的采集或恢复环境检查。第三时期的下载器还会检查 /proc/mounts,卸载挂在进程目录上的非 proc 文件系统并终止相关进程,也会清理在 /tmp 运行的程序。
其他动作会影响设备稳定性。样本尝试通过 /dev/watchdog 和 /dev/misc/watchdog 的 ioctl 停止看门狗,也按临时目录、命令行与可执行文件名等条件终止进程,并跳过自己的进程组。看门狗通常用于处理设备失去响应的情况,进程清理还可能碰到维护任务。恢复检查应按设备的官方方法验证看门狗和维护功能,不能停在“网络又通了”。
5 沿设备上的证据决定怎样恢复
如果唯一线索是一次公共 STUN 访问,先核对设备是否运行语音、视频或其他需要 NAT 协调的功能,以及哪个进程产生了请求。若同时找到 .cling、不明启动项和进程目录上的异常挂载,就应隔离设备,保存这些文件、挂载关系及边界网络记录。重启会改变运行态证据,还可能让已经写好的启动项再次工作,不能把重启当成第一项清理动作。
确认后门以高权限运行后,恢复要回到可信固件和经过检查的配置。关闭被利用的公网入口,按具体型号处理漏洞,再核对远程管理账号、设备可接触的凭据及相邻网络中的异常连接。恢复出厂设置是否覆盖被改文件、固件重刷保留哪些配置,应由对应型号的官方恢复说明确认。无法获得可用修补和可信恢复路径的设备,继续隔离并安排替换。
出站策略可以按设备用途收紧。没有语音、WebRTC 或同类功能的工业网关,一般没有理由长期向一大组公共 STUN 端点查询映射,允许的业务目的地可以先从现有配置与正常记录确定。确有相关业务时,保留所需服务并把流量关联到具体应用,测试正常功能,观察同一进程是否又接上陌生 TCP 端点。