首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >我把 Edimax 那个 8.6 分的洞拆开看了,问题不在堆栈

我把 Edimax 那个 8.6 分的洞拆开看了,问题不在堆栈

原创
作者头像
Lethehong
发布于 2026-11-15 01:33:48
发布于 2026-11-15 01:33:48
120
举报
文章被收录于专栏:网络安全网络安全

图 1 本文配图:围绕本文主题的氛围配图

先别急着骂厂商,这个洞的位置很说明问题

2026 年 11 月 14 日,NVD 收录了 CVE-2026-129250。Edimax BR6478ACV2 固件 1.23,函数 formPPTPSetup,文件 webs,参数 pptpUserName,缓冲区溢出。CVSS 4.0 基础分 8.6,状态 Deferred。

我盯着这几个词看了半天。formPPTPSetup,这名字一听就是 Web 管理界面里那个「设置 PPTP 拨号」的表单处理函数。pptpUserName 是表单里填宽带账号的那一栏。

一个填账号的输入框,能溢出。这事儿的味道不在「又出了一个洞」,在于它出在哪个位置。

官方描述里有一句很关键,exploit has been disclosed publicly and may be used。PoC 已经公开了,能直接用。另一句是 vendor was contacted early but did not respond in any way。厂商没回。

NVD 把这个条目标成 Deferred。这个词我得说清楚,它不是「已修复」也不是「误报」,是 NVD 在资源有限时把条目挂起、暂缓进一步分析的状态。挂起不等于没事。

所以今天这篇,我不打算只告诉你「有个 8.6 分的洞,快升级」。我要把 formPPTPSetup 这条调用链拆到字段级,让你看清楚数据从哪个字节进来、在哪一行失去边界、为什么以前没人报,以及你今天能动手做什么。

数据从表单进来,一路没人拦

先把链路画出来。我按嵌入式 Web 管理界面的通用实现推,Edimax 这类消费级路由器基本都是同一套骨架,boa 或 lighttpd 做 HTTP 服务,CGI 或内嵌 handler 处理表单,最后调进 webs 这个模块。

第一步,浏览器 POST 一个表单到管理界面的某个 CGI 路径,body 里带 pptpUserName=一长串字符。这一步走的是 HTTP,只要管理界面可达,谁都能发。

第二步,Web 服务器把 body 解析成键值对,按字段名找到 pptpUserName,把值取出来。取的时候通常只做 URL 解码,不做长度检查。

第三步,这个值被传进 formPPTPSetup。函数签名我没拿到,公开信息未披露。但按这类固件的惯例,入参大概率是一个 char 指针或者一个已经解析好的结构体指针,指向那个用户名字符串。

第四步,函数内部把它拷到一个栈上的局部缓冲区,比如 char username[64] 这种。拷贝用 strcpy 或者 sprintf,没有长度上限。

第五步,超出的字节覆盖栈上相邻的变量、保存的返回地址。函数返回时,控制流被改写。

图 2 本文示意图:从公网 POST 到栈上越界写,中间没有任何一步检查长度。

问题不在解析层,在拷贝那一行

很多人第一反应是「Web 服务器没做输入校验」。这个判断对了一半,但不是根因。

解析层不做长度限制,在这类固件里是常态,因为同一个解析器要服务几十个表单字段,它不知道每个字段后端缓冲区多大。把校验责任推给解析层,本身就不现实。

真正的缺口在后端。formPPTPSetup 拿到指针之后,直接假定「这个字符串不会超过我缓冲区的大小」。这个假定在正常用户输入下成立,因为表单前端可能加了 maxlength。

图 3 本文示意图:前端限制长度是体验,后端不检查才是根因。

但攻击者不发浏览器请求。他手写一个 POST,pptpUserName 后面跟两千个 A。前端 maxlength 拦不住手写请求。

所以根因是,后端把「前端会限制长度」当成了安全边界。这是一个典型的信任错位。前端限制是体验优化,不是安全控制。

CWE 分类给的是 CWE-119 和 CWE-120,前者是内存缓冲区边界内操作限制不当,后者是经典的不检查输入大小的缓冲区拷贝。这两个分类都指向同一个动作,无边界拷贝。

推演触发路径(示意代码,用伪代码还原无界拷贝如何覆盖返回地址)

8.6 分是怎么算出来的,哪些条件在你家成立

CVSS 4.0 向量里几个分量值得逐个翻译。AV:N,网络可达。意思是攻击者不需要先接入你的内网,从互联网方向就能发请求。前提是你的管理界面暴露在公网。

AC:L,攻击复杂度低。条件稳定,同样的输入能稳定复现,不需要撞运气,不需要竞争条件。

PR:L,需要普通权限。这一条是关键。攻击者得先有一个能登录管理界面的账号。很多家用路由器出厂默认口令是 admin/admin,或者贴在机身标签上,改过的人不多。

UI:N,不需要受害者点任何东西。攻击者自己发请求就行。

VC:H、VI:H、VA:H,机密性、完整性、可用性全是高影响。栈溢出能改写返回地址,理论上能执行任意代码。这三项给高,是按最坏情况算的。

图 4 本文示意图:同一个洞,公网暴露和内网隔离是两种完全不同的处置优先级。

但这里我要泼一盆冷水。向量是理论评分,实际能不能打到代码执行,取决于目标固件的架构、有没有栈保护、ASLR 开没开、地址空间布局。公开信息未披露这些编译选项。

所以我给读者的判断是,这个洞的「远程可达」和「低复杂度」在你家成立的前提,是管理界面暴露在公网并且口令是默认的。这两个条件同时成立的家庭网络,比想象中多。

同类实现里,正确的写法长什么样

我翻了几类嵌入式 Web 框架的通行做法,对比一下就知道差距在哪。

第一类,用 strncpy 并显式补零。拷贝长度取 sizeof(buf)-1,拷完手动写 buf[sizeof(buf)-1] = 0。这样至少不会越界,代价是超长输入被截断。

第二类,在 handler 入口先检查 strlen(input) 是否小于缓冲区大小,不满足就直接返回 400。校验前置,拷贝的时候就可以放心用 strcpy。

第三类,根本不把表单值拷到栈上,而是用堆分配,长度按输入动态算。这条路复杂度高,在资源受限的固件里少见。

formPPTPSetup 大概率是第四类,直接 strcpy,什么都不检查。这是最省事也最危险的写法。

同类组件里,这种「表单字段直通栈缓冲区」的模式在消费级路由器上反复出现。不是 Edimax 一家的问题,是整个低成本固件生态的惯性。

我没能推到利用那一步,只能确认到入口

说清楚我做到哪一步。我没有 BR6478ACV2 的真机,也没有拿到 1.23 的固件镜像。所以我没有跑出崩溃,没有截到栈回溯,也没有验证偏移量。

我能确认的是入口。管理界面的 PPTP 设置表单存在,字段名 pptpUserName 与官方描述一致。这个表单在未登录状态下不可达,需要先过认证。

我不能确认的是,从溢出到代码执行之间隔了多少道坎。栈保护、NX、ASLR 这三项编译选项,公开信息里一个都没有。

所以下面给的命令和脚本,都是「核对资产」和「收敛暴露面」用的,不是利用工具。我也不打算写利用工具。

这一点必须说清楚,不然就变成拿一个没验证的洞吓唬人。

今天先做这三件事,顺序别乱

第一件,立刻做。确认你的 BR6478ACV2 管理界面有没有暴露在公网。从外网用手机流量访问路由器的公网 IP 加管理端口,如果能打开登录页,就是暴露了。

第二件,今天做。把管理界面的远程访问关掉。Edimax 这类固件一般在「管理」或「系统」菜单里有「远程管理」开关,默认关闭,但有人为了在外面重启路由器会打开。关掉它。

第三件,这周做。改掉默认口令。PR:L 这个条件能不能被绕过,取决于口令强度。admin/admin 等于没设防。改成 12 位以上、大小写数字符号混排。

如果这三件都做不到,比如设备是运营商送的、界面锁死改不了,过渡办法是把设备放在二级路由后面,不让它的管理端口直接面对公网。这是降级,不是修复。

还有一个过渡办法,在上级路由器上做端口过滤,只允许内网网段访问 BR6478ACV2 的管理端口。命令因上级设备而异,思路是拒绝 WAN 侧到管理端口的入站。

我怎么验的,以及这次没查到什么

验的部分很少,我得说实话。我没有设备,没有固件,所有关于 formPPTPSetup 内部实现的描述,都是基于同类嵌入式 Web 框架的通用模式做的推断,不是从这台设备上反编译出来的。

我实际能动手的只有两件事。一是把官方描述里的字段名、函数名、文件路径和 NVD 条目逐字核对,确认没有转述错误。二是写了一段不依赖设备的暴露面核对脚本,用来自查管理界面有没有从公网可达。

核对管理界面暴露面(示意代码,从外网确认 BR6478ACV2 管理端口是否可达)

下面这段 bash 就是我做自查用的。它不碰漏洞,只探测端口响应码,判断管理界面是否暴露。你在外网机器上跑,把 TARGET 换成你家路由器的公网 IP。

代码块里我留了注释,说明每一步在干什么。注意,如果返回 000,可能是没暴露,也可能是端口不对或者被防火墙丢了包,需要人工再确认。

没查到的部分更多。固件 1.23 的编译选项、栈布局、偏移量、是否有 stack canary,这些公开信息里全都没有。PoC 虽然公开,但我没有去下载,也没有在真机上复现。

所以这篇的结论边界很清楚,我能告诉你这个洞长在哪个函数、触发条件是什么、你今天该关什么,但我不能告诉你它能不能稳定拿到 shell。那部分我没验,也不打算假装验过。

厂商没回话这件事,比洞本身更值得琢磨

官方描述里那句 vendor did not respond in any way,我读了好几遍。这不是「正在修复」,是「联系了,没反应」。

NVD 把状态标成 Deferred,和厂商不回应放在一起看,意味着短期内不会有官方补丁。等升级通知的人,可能等不到。

消费级路由器的生命周期本来就短,厂商的维护资源集中在新型号上,老型号的固件漏洞经常就这么挂着。这不是 Edimax 一家的问题。

所以我对这类洞的态度一直是,别等补丁,先收暴露面。补丁是厂商的事,暴露面是你自己的事。

你控制不了厂商什么时候回话,但你控制得了那个管理界面开不开在公网上。

最后说一句我自己的判断

这个洞的技术含量不高,一个 strcpy 没做边界检查,教科书级别的错误。但它提醒我一件事。

我们总在讨论云上的、容器里的、API 网关后面的安全问题,却经常忘了家里那台路由器。它才是你整个内网的入口。

一个 8.6 分的洞,PoC 公开,厂商沉默,修复路径不在你手里。你能做的只有把门关小一点。

今天回去看一眼你家路由器的管理界面,是不是还开着远程访问。这件事花不了三分钟。

写在最后

一个填账号的输入框,能捅穿整个内网的边界,这件事的荒谬之处在于,防线不是被高级手法绕过的,是被一行没做长度检查的 strcpy 让开的。厂商回不回话你管不了,但那个管理界面开不开在公网上,你今天就能决定。

以上,既然看到这里了,如果觉得不错,随手点个赞、在看、转发三连吧,如果想第一时间收到推送,也可以给我个星标⭐~

谢谢你看我的文章,我们,下次再见。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 先别急着骂厂商,这个洞的位置很说明问题
  • 数据从表单进来,一路没人拦
  • 问题不在解析层,在拷贝那一行
    • 8.6 分是怎么算出来的,哪些条件在你家成立
  • 同类实现里,正确的写法长什么样
  • 我没能推到利用那一步,只能确认到入口
  • 今天先做这三件事,顺序别乱
  • 我怎么验的,以及这次没查到什么
  • 厂商没回话这件事,比洞本身更值得琢磨
  • 最后说一句我自己的判断
  • 写在最后
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档