返回

文章详情

摩托罗拉 MR2600 路由器中的未认证 RCE

Hacker News2026年7月12日 11:52

我目前正在寻找每个路由器厂商至少一个远程代码执行漏洞。这是我如何在摩托罗拉的 MR2600 路由器中发现未认证 RCE 的故事。我首先要解决的问题是获取固件。对于他们的大多数路由器,摩托罗拉不会公开分发固件;相反,它只会通过无线更新进行分发。我能找到的第一个例外是摩托罗拉 MR2600。这是一款 Wi-Fi 5 路由器,最后一次固件更新(v1.0.22)是在 2024 年中期发布的。https://help.motorolanetwork.com/kb/mr2600/mr2600-software-updates 下载固件后,我提取了文件系统,并开始查看路由器的 CGI 脚本和 SOAP 处理程序,以了解合法的手动更新是如何工作的。结果发现这是一个两步过程:上传镜像,然后触发验证和闪存例程。正如我随后发现的那样,这两个步骤本应需要身份验证,但实际上并不需要。上传恶意固件 在路由器固件中,可以找到对 fwupload 端点的引用:POST /WEBCGI1/prog.fcgi?method=/cgi-bin/fwupload.cgi 特别是,UpdateFirmware_Moto.html 固件更新页面包含:<form id="fwupload" action="/WEBCGI1/prog.fcgi?method=/cgi-bin/fwupload.cgi" method="post" enctype="multipart/form-data"> 这允许管理员手动升级摩托罗拉固件。一个内部处理程序通过检查文件的前四个字节是否为 0x27 0x05 0x19 0x56 来验证上传的文件是否是有效的 SEAMA 图像。不幸的是,开发人员在解析来自多部分表单的 SEAMA 图像时犯了一个关键错误。他们试图验证原始多部分数据是否带有魔数,而不是先从表单中提取相关字段。 ------WebKitFormBoundaryXXXXXXXX Content-Disposition: form-data; name="file"; filename="firmware.img" Content-Type: application/octet-stream [实际 SEAMA 字节从这里开始] ------WebKitFormBoundaryXXXXXXXX-- 这导致 API 的任何合法使用都失败,因为前四个字符将始终是 “ ---- ”,这不等于 0x27 0x05 0x19 0x56。作为攻击者,我们可以通过声称我们正在发送多部分表单来绕过此要求,但实际上发送原始固件图像,而没有任何多部分边界。开发人员可能预计这个 API 端点如果被局域网上的未经认证的攻击者调用就会被滥用,因此他们添加了一个检查,以拒绝未认证用户的请求。然而,身份验证检查只会在固件被上传并写入路由器的 /tmp/firmware.img 后触发,而且如果检查失败并不会删除该文件。 刷写固件 要刷写固件,我们需要发出以下网络请求:POST /WEBCGI1/ HTTP/1.1 Content-Type: text/xml; charset=utf-8 SOAPAction: "http://purenetworks.com/WEBCGI1/LoadFirmwareValidation" <?xml version="1.0"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <LoadFirmwareValidation xmlns="http://purenetworks.com/WEBCGI1/" /> </soap:Body> </soap:Envelope> 通俗来讲,这只是触发路由器内的一个名为 LoadFirmwareValidation 的内部函数。它试图验证 /tmp/firmware.img 中的文件是否是有效的 SEAMA 图像,并检查 CRC32 校验和以确保文件没有损坏的风险。任何人都可以生成有效的固件图像,因为这样做不需要任何加密签名来证明它是由摩托罗拉创建的。一旦固件被验证,内部函数会调用一个名为 mtd_write 的命令:mtd_write -r -w write /tmp/firmware.img Kernel & 这将刷写新的固件,然后重启路由器(由 -r 标志表示)。这个 API 端点也需要身份验证;然而,它同样也可以被绕过。检查给定端点是否需要身份验证的代码实现不正确。它首先检查 URI 是否包含任何允许列表或拒绝列表路径。在下面显示的字典中,只有最后一个值 /WEBCGI1/ 被视为拒绝列表。一旦找到匹配,函数会明确检查 URI 是否与 /WEBCGI1/ 完全相等。只要 URI 不完全匹配 /WEBCGI1/,系统就假定请求的端点是允许的,并允许流量通过。核心漏洞源于应用程序使用了不一致的比较运算符。它使用基本的子字符串匹配检查允许列出的端点,但通过检查整个 URI 的精确匹配来检查拒绝列表的端点(/WEBCGI1/)。由于这个缺陷,攻击者可以调用 API,并简单地将一个允许列表字符串作为 HTTP 参数附加,欺骗系统完全绕过身份验证。比如,POST /WEBCGI1/?Login.html /WEBCGI1/?Login.html 包含 "Login.html" --> 是(允许列表检查通过)

赞助内容

NordVPN Next-gen Antivirus

本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。

请我喝杯咖啡