Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-76070 — 针对 Netis NC63 login.cgi 中预认证 Base64 解码密码栈缓冲区溢出的原创研究与 PoC | Kitploit
工具/GitHubGitHub/ozcanpng/cve-2026-76070
嵌入式系统安全物联网安全漏洞分析漏洞利用逆向工程固件分析二进制利用
GitHubozcanpng/cve-2026-76070

CVE-2026-76070

针对 Netis NC63 login.cgi 中预认证 Base64 解码密码栈缓冲区溢出的原创研究与 PoC

查看仓库
1331个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2026-76070:Netis NC63 login.cgi 中经 Base64 解码密码导致的未认证预认证栈缓冲区溢出,可致 RCE

研究员: Özcan Ersan (@ozcanpng)

披露状态

  • CVE: CVE-2026-76070
  • 厂商: Netis Systems Co., Ltd.
  • 产品: Netis NC63 Wireless AC1200 Router
  • 测试固件: NC63_V3.0.0.3327
  • 受影响组件: /bin/netis.cgi
  • 端点: POST /cgi-bin/login.cgi
  • 参数: Base64 编码的 password
  • 认证: 无;不安全的解码发生在凭据比较之前
  • 架构: MIPS32r2 小端序,o32 ABI,uClibc
  • 漏洞类别: 基于栈的缓冲区溢出,可控制保存的返回地址
  • 验证: 在隔离的 QEMU 用户态运行时中对原始哈希的生产 CGI 进行验证
  • 准备时的 CVE 记录状态: 已分配;CNA 记录详情待补充

执行摘要

Netis NC63 固件 V3.0.0.3327 中的公开登录处理程序获取攻击者控制的 password 参数,并使用自定义 Base64 例程 FUN_00402bd4 对其进行解码。 调用方提供了一个 64 字节的本地栈缓冲区,但未将其容量传递给解码器。 解码器根据编码输入推导其工作量,并在不检查目标末尾的情况下写入解码后的字节。

保存的 MIPS 返回地址位于解码缓冲区起始位置之后 136 字节处。针对原始哈希生产 CGI 的动态测试确认:

  1. 解码后的 140 字节 B 模式会在 0x42424242 处产生故障;
  2. 将保存的 ra 替换为 0x0041a2e0 会导致在登录处理程序处观察到第二次进入,证明程序计数器可控;以及
  3. 一个隔离的仅观察测试到达原始二进制文件的直接 system() 调用,并使用攻击者选择的 MIPS a0 值。替换的 /bin/sh 记录了 /bin/sh -c NC63_RCE_PROOF,且未执行任何命令。

本仓库中的公开 PoC 有意止步于崩溃模式。它不包含返回链、shellcode、命令、反向 shell 或持久化。 poc/exploit-db/ 中单独维护的 RCE 脚本是为提交至 Exploit-DB 而准备的,仅用于对受影响系统进行授权测试。

受影响工件完整性

193f6a5e2ce65972b1805bf076f8d3521379a8441c8aaeb5ad0ba174bbee0792  netis_NC63_V3.0.0.3327.bin
23faa747b7d2f067aa5431bcc227ceca97a7977cf3e7c372f715cbba57f9209b  squashfs-root/bin/boa
eb298774c27070dc595fefcabb4e8c12a46cb5f4fd08f91c3ca92282c3a289a2  squashfs-root/bin/netis.cgi

动态测试的 /bin/netis.cgi 副本与从厂商固件中提取的可执行文件具有相同的 SHA-256。

原始哈希与运行时哈希

攻击面与认证状态

厂商前端将密码以 Base64 形式发送到公开端点:

obj.password = base64encode(utf16to8(password));
request({
    url: "/cgi-bin/login.cgi",
    data: obj
});

HTML 字段使用了 maxlength="63",但这只是浏览器端的限制。直接的 HTTP 客户端可以提交更大的编码值。

前端请求与仅客户端限制

login.cgi 在认证之前必然可达。不安全的解码发生在将解码后的密码与配置的管理员密码进行比较之前。不需要有效的会话、Cookie 头、Authorization 头或正确的密码。

从源到汇的追踪

Unauthenticated HTTP client
  |
  | POST /cgi-bin/login.cgi
  | password=<attacker-controlled Base64>
  v
/bin/netis.cgi: FUN_0041a2e0
  |
  | get_request_param("password")
  v
FUN_00402bd4(decoded_stack_buffer, encoded_password)
  |
  | no destination-capacity argument
  | decoded output exceeds 64 bytes
  v
saved s8 at decoded offset 132
saved ra at decoded offset 136
  |
  v
attacker-selected MIPS PC

存在漏洞的代码

源自 Ghidra 的伪代码,为便于阅读已对名称进行规范化处理:

int login_cgi(void *request)
{
    char decoded[64];
    char stored[68];
    char *password;

    memset(decoded, 0, 64);
    memset(stored, 0, 64);
    password = get_request_param(request, "password");
    if (password != NULL)
        FUN_00402bd4(decoded, password); /* no capacity argument */

    apmib_get(0x15e, stored);
    if (strcmp(decoded, stored) == 0)
        printf("[\"SUCCESS\"]");
    else {
        system("echo 0 >/tmp/boa_auth");
        printf("[\"%d\"]", 0x15);
    }
    return 0;
}

存在漏洞的登录处理程序

位于 FUN_00402bd4 的解码器仅接收目标指针和源指针。 其循环会推进目标指针,并为每四个 Base64 符号存储最多三个解码后的字节。没有任何比较操作会检查目标指针是否超出 decoded + 64。

自定义 Base64 解码器写入循环

Base64 是输入变换方式,而非底层缺陷。根本原因在于攻击者控制的解码后长度与固定大小的目标缓冲区之间的不匹配,而后者的容量从未被强制执行。对于普通的带填充输入,四个编码字符最多表示三个解码后的字节;因此,服务器端检查必须在写入之前计算并验证解码后的大小。

栈破坏分析

FUN_0041a2e0 起始于 0x0041a2e0,并创建一个 0xa8 字节的栈帧:

0041a2e0  addiu sp,sp,-168
0041a2e4  sw    ra,164(sp)
0041a2e8  sw    s8,160(sp)
0041a2ec  move  s8,sp

解码后的目标地址从 s8+0x1c 开始;保存的 s8 和保存的 ra 分别位于 s8+0xa0 和 s8+0xa4:

decoded[64]  s8+0x1c   decoded offset 0
saved s8     s8+0xa0   decoded offset 132
saved ra     s8+0xa4   decoded offset 136

精确的返回地址距离为 0xa4 - 0x1c = 0x88,即 136 字节。

栈帧与保存的返回地址偏移

动态验证

覆盖保存的返回地址

一个 140 字节的解码 B 模式替换了四字节的保存返回地址:

--- SIGSEGV {si_signo=SIGSEGV, si_code=1, si_addr=0x42424242} ---
qemu: uncaught target signal 11 (Segmentation fault)

攻击者选定返回地址处的故障

程序计数器控制

另一组 140 字节的输入将 ra 保存为 0x0041a2e0。QEMU CPU 跟踪记录到一次普通的第一处理程序入口,随后是第二次入口,其中 s8=0x41414141 且 ra=0x0041a2e0。

受控的第二次处理程序入口

仅观察的命令边界

原始二进制在 0x0041a3cc 处包含一条直接的 jal system。在私有的隔离验证中,现有的固定基址指令将一个标记加载到 a0 并到达了该调用。一个静态观察程序被挂载到 /bin/sh 之上;它记录了命令解释器的参数,并且没有执行任何内容:

argv[0]=</bin/sh>
argv[1]=<-c>
argv[2]=<NC63_RCE_PROOF>
CONTROLLED_MARKER_REACHED
PASS: attacker-controlled a0 reached system() and /bin/sh argv.
PASS: the guard logged the request and executed no command.

这展示了隔离的生产代码路径中的一个 RCE 原语。它并不能证明在物理路由器上、在其部署的内核和栈随机化配置下具有相同的漏洞利用可靠性。

权限与二进制加固背景

原始 Boa 配置指定了 User root、Group root,以及包含 /bin 和 /web/cgi-bin 的 CGI 路径。生产可执行文件为固定基址(0x00400000),没有栈金丝雀或 RELRO,并声明了一个带有 RWX 段的可执行 GNU 栈。

生产 Boa 权限配置

二进制加固状态

安全的公开 PoC

随附脚本默认采用 dry-run 模式,仅生成一个解码后包含 140 个 B 字节的 Base64 表单主体:

python3 poc/poc.py

发送需要明确指定授权目标以及 --send:

python3 poc/poc.py --target http://192.168.1.1 --send

Exploit-DB RCE 脚本

poc/exploit-db/CVE-2026-76070.py 是为 Exploit-DB 准备的 RCE 脚本。 它针对已记录的未认证 login.cgi 漏洞,并接受 一个命令参数,用于对已授权的受影响测试目标进行测试:

python3 poc/exploit-db/CVE-2026-76070.py <target> "id"

发送该模式可能导致 CGI 进程崩溃。请仅在获得授权的、可丢弃的环境中使​​用它。该 PoC 未实现私有的 RCE 验证链。

影响

成功利用可在路由器管理上下文中执行攻击者选定的代码或命令。在原始 Boa 配置下,该上下文以 root 身份运行。潜在后果包括配置和机密泄露、DNS/防火墙/路由操纵、流量重定向、服务中断以及设备完全被攻陷。

修复

  1. 将自定义解码器替换为接受目标容量的 API。
  2. 拒绝计算出的解码长度超过 63 字节的输入,为终止符预留空间。
  3. 在解码前于服务端验证长度和 Base64 语法。
  4. 审计 FUN_00402bd4 的每一个调用方。
  5. 使用栈金丝雀、PIE、NX 和 RELRO 重新构建。
  6. 以最小权限运行 CGI 进程。

证据索引

有关截图和跟踪映射,请参见 evidence/README.md。 规范化后的 Ghidra 摘录位于 attachments/decompiled-functions/。

披露时间线

  • 2026-08-16: 完成发现和隔离的生产二进制验证。
  • 2026 年 8 月: 报告给 VulnCheck。
  • 2026-08-20: VulnCheck 分配了 CVE-2026-76070 并授权公开披露。
  • 2026-08-20: 发布公开披露包。

参考资料

  • CVE-2026-76070
  • VulnCheck
  • Netis NC63 支持页面
  • CVE-2026-73673

未对任何物理路由器进行刷机。未使用任何真实 shell 命令、反向 shell、持久化、外部连接、凭据窃取或破坏性固件操作。

下载工具