GL-AXT1800路由器OTA升级漏洞:SSL验证缺失导致固件降级攻击

思科Talos发现GL-Inet GL-AXT1800旅行路由器存在严重OTA升级漏洞。攻击者可通过中间人攻击伪造升级列表,诱骗用户将设备“升级”至存在已知漏洞的旧版本固件,从而为进一步的远程代码执行攻击铺平道路。

TALOS-2025-2230 || 思科Talos情报集团 - 全面威胁情报

Talos漏洞报告

TALOS-2025-2230

GL-Inet GL-AXT1800 OTA升级固件降级漏洞

发布日期: 2025年11月24日

CVE编号: CVE-2025-44018

概述: GL-Inet GL-AXT1800 4.7.0版本的OTA升级功能存在固件降级漏洞。特制的.tar文件可导致固件降级。攻击者可通过中间人攻击触发此漏洞。

已确认受影响版本: 以下版本经过Talos测试或验证,或已由供应商确认为受影响版本:

  • GL-Inet GL-AXT1800 4.7.0

产品链接:

CVSSv3评分: 8.3 - CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H

CWE: CWE-295 - 证书验证不当

详细信息: GL-Inet Slate AX(GL-AXT1800)是一款支持千兆速度和Wi-Fi 6功能的袖珍旅行路由器。该设备预装了多种VPN和远程连接工具,是追求移动安全性的用户的极受欢迎解决方案,也是亚马逊等在线零售商中最受欢迎的旅行路由器之一。

当用户登录GL-Inet Slate AX旅行路由器的网络管理界面时,新登录的用户有时会收到升级设备的提示,这取决于是否有可用升级以及设备版本。无论如何,在检查实际的升级网页时,设备会通过向https://fw.gl-inet.com/firmware/<model_name>/release/list-sha256.txt发送HTTPS请求来检查GL-Inet是否有可用升级。

对于Slate AX设备,请求如下所示:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# https://fw.gl-inet.com/firmware/axt1800/release/list-sha256.txt 
4.6.11  openwrt-axt1800-4.6.11-1216-1734278520.tar      fc9bf38d930e7281287b89525dda4c790be093e7adaba3b44316ed2e73150b98      47063920
4.6.8   openwrt-axt1800-4.6.8-1017-1729172935.tar       eb11db2e26490e70ec3a9908a11880b104f043a28f84c9973039a85713ca7eae      46900718
4.6.4   openwrt-axt1800-4.6.4-0905-1725497901.tar       f5912ed8f1add984cc1a6226f43fd52402821216ee36536313ae61f798a6e810      47077372
4.6.2   openwrt-axt1800-4.6.2-0709-1720529672.tar       a3766797f96c0982bb0f9673be02f9cac640524d2e737019bf6c7865d7c37d9a      46965331
4.5.16  openwrt-axt1800-4.5.16-0321-1711033518.tar      96d2631ec6f271949c1ac179ff972fb5f77c0e0b2a2f910709134114d7d2fdcf      48816496
4.5.0   openwrt-axt1800-4.5.0-0123-1706015685.tar       dd59b3e6b4e8e5b5bdf56266152ea847433bb11a60dbced77c68780610b37105      47507619
4.4.6   openwrt-axt1800-4.4.6-0908-1694157838.tar       32e32e90a68003b722d23b6955cb2a678445d188f47a5de926860e3e3f080487      59404146
4.2.3   openwrt-axt1800-4.2.3-0706-1688630948.tar       4911ff9688ba170cb8f3d6d0d16d869bae857581820fbf9bcbb9c5ba02119569      59373801
4.2.1   openwrt-axt1800-4.2.1-0414-1681482936.tar       4d50428028b63b35dbc039d0069c56a57ec8747380e9ae9cc4cd57bfa874c7a4      59373123
4.1.0   openwrt-axt1800-4.1.0-1116-1668588068.tar       d152cddffee821355613ba6a0db074d9b686f128e7ef6a5d65a1952e1942b655      51961046
4.0.3   openwrt-axt1800-4.0.3-0831.tar  95371806941e6b6eecfc447db41414e741b70c217027ca129f752853ab9d4b32     49592938

假设上述列表中存在版本号大于设备版本(即第一列)的条目,则继续执行升级过程,该过程主要由/usr/lib/oui-httpd/rpc/upgrade/usr/bin/one_click_upgrade脚本处理。仍在/usr/lib/oui-httpd/rpc/upgrade Lua脚本中,会对上述字段进行各种清理以防止命令注入,并验证升级大小。然后路由器获取https://fw.gl-inet.com/firmware/<model>/release/metadata_<version> URL以收集显示给用户的元数据,以便用户决定是否实际升级。URL和响应的示例如下:

1
2
3
4
5
6
7
8
https://fw.gl-inet.com/firmware/axt1800/release/metadata_4.6.11   

{  "metadata_version": "1.1", "compat_version": "1.0",   "supported_devices":["glinet,axt1800"],
 "version": { "release": "4.6.11", "date": "20241215232632", "dist": "OpenWrt", "version": "21.02-SNAPSHOT", 
"firmware_type": "release2", "revision": "r16399+173-c67509efd7", "target": "ipq807x/ipq60xx", "board": "glinet_axt1800" }, 
"upgrade_control":"", "release_note":"# V4.6.11\r\n\r\n## Overview\r\nThis version mainly fixes some known bugs.\r\n\r\n## 

Fixed the problem of abnormal display of channel list in some cases.\r", "release_note_cn":"" }

收集元数据后,升级Lua脚本会调用/usr/bin/one_click_upgrade,如下所示:

1
local cmd = (string.format)("/usr/bin/one_click_upgrade \'%s\' \'%s\' \'%s\' \'%s\' \'%s\' \'%s\' \'%d\' &", firmware_url, sha256, keep_config and "1" or "0", keep_package and "1" or "0", use_mirror_dl and "1" or "0", id or "", cloud_size or Unknown_Type_Error)

值得注意的是,firmware_url字段是通过将固件URL与从list-sha256.txt信息中选择的升级文件名拼接而成的,因此下载的固件文件名示例类似于https://fw.gl-inet.com/firmware/a1300/release/openwrt-a1300-4.4.6-0908-1694153586.tar。继续深入one_click_upgrade脚本,我们可以看到设备实际下载固件的位置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
if [ "$use_mirror_dl" = 1 ]; then
    /usr/bin/mirror_downloader $firmware_path
    while [ "$firmware_sha256sum" != "$(sha256sum /tmp/firmware.img |awk '{print $1}')"  ]; do
        /usr/bin/mirror_downloader $firmware_path
        sleep 5
    done
else
    firmware_name=$(basename "$firmware_path")
    curl -C - -Ls --connect-timeout 5 $firmware_path -o /tmp/firmware.img >> /dev/null // [1]
fi

如[1]处所示,这并没有什么特别之处。我们展示这一行是为了与/usr/lib/oui-httpd/rpc/upgrade Lua脚本通过fetch_firmware_info函数获取list-sha256.txtmetadata_<version>文件的方式进行对比:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
local fetch_firmware_info = function(url)
  -- function num : 0_4 , upvalues : http
  local httpc = (http.new)()
  httpc:set_timeout(Unknown_Type_Error)
  local res, err = httpc:request_uri(url, {ssl_verify = false}) // [2]
  if not res then
    return nil, err
  end
  httpc:close()
  if res.status ~= Unknown_Type_Error then
    return nil, "status: " .. res.status
  end
  local body = res.body
  if not body then
    return nil, "no response data"
  end
  local name, sha256, size = body:match("^%S+%s+(%S+)%s+(%x+)%s+(%S+)")
  if not name or not sha256 or not size then
    return nil, "invalid response"
  end
  return name, sha256, size
end

尽管这些请求正确地向https://*站点发送以防止中间人攻击,但我们在[2]处清楚地看到,ssl_verify选项因某种原因被关闭,这引入了不必要的攻击面。奇怪的是,在GL-Inet代码的最早版本中,此功能由正确使用curl并开启SSL验证的shell脚本处理,但在切换到Lua时,引入了回归问题。无论如何,我们面临的情况是:固件升级信息可以被拦截和修改,但实际下载的固件必须是有效的。由于先前版本中其他研究人员发现的漏洞,固件信息有各种输入检查和验证,我们无法立即通过某种命令注入获得RCE。

然而,我们仍有利用选项,因为我们可以简单地诱骗用户将设备降级到易受攻击的版本。如果我们修改sha256-list.txt响应,使其看起来像这样:

1
2
3
4
5
6
7
5.1.1  openwrt-axt1800-4.4.6-0908-1694157838.tar       32e32e90a68003b722d23b6955cb2a678445d188f47a5de926860e3e3f080487      59404146 // [3]
4.6.11  openwrt-axt1800-4.6.11-1216-1734278520.tar      fc9bf38d930e7281287b89525dda4c790be093e7adaba3b44316ed2e73150b98      47063920
4.6.8   openwrt-axt1800-4.6.8-1017-1729172935.tar       eb11db2e26490e70ec3a9908a11880b104f043a28f84c9973039a85713ca7eae      46900718
4.6.4   openwrt-axt1800-4.6.4-0905-1725497901.tar       f5912ed8f1add984cc1a6226f43fd52402821216ee36536313ae61f798a6e810      47077372
4.6.2   openwrt-axt1800-4.6.2-0709-1720529672.tar       a3766797f96c0982bb0f9673be02f9cac640524d2e737019bf6c7865d7c37d9a      46965331
4.5.16  openwrt-axt1800-4.5.16-0321-1711033518.tar      96d2631ec6f271949c1ac179ff972fb5f77c0e0b2a2f910709134114d7d2fdcf      48816496
4.5.0   openwrt-axt1800-4.5.0-0123-1706015685.tar       dd59b3e6b4e8e5b5bdf56266152ea847433bb11a60dbced77c68780610b37105      47507619

我们可以在列表中添加一个旧版本的固件,但在第一列中使用更高的版本号[5],这样设备就会选择易受攻击的固件版本(openwrt-axt1800-4.4.6-0908-1694157838.tar)进行升级。我们还可以利用对元数据文件的可用MitM攻击(在本例中为https://fw.gl-inet.com/firmware/axt1800/release/metadata_5.1.1),使升级弹出窗口显示完全错误的信息,例如更新的版本、发布日期、补丁说明等。在升级过程中的任何时候,用户都无法看到他们实际“升级”到的固件版本实际上是更旧的,至少在用户升级后登录之前是如此,但到那时已经为时已晚。例如,攻击者可以强制设备降级到4.4.6版本,并在下一次升级时,利用WAN侧的CVE-2023-50445在路由器中执行任意代码。

时间线:

  • 2025年8月11日 - 首次联系供应商
  • 2025年8月11日 - 向供应商披露
  • 2025年9月4日 - 供应商发布补丁
  • 2025年11月24日 - 公开发布

致谢: 由思科Talos的Lilith >_>发现。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计