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

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

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

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-88776 — CVE-2026-88776 的技术分析文章,该漏洞是 NetScaler nsppe 的 Oracle TNS 记录解析器中一个预认证整数下溢,会导致越界写入和包引擎崩溃。 | Kitploit
工具/GitHubGitHub/scyrix-llc/cve-2026-88776
内存取证漏洞分析漏洞利用逆向工程网络安全二进制分析论文与研究
GitHubscyrix-llc/cve-2026-88776

CVE-2026-88776

CVE-2026-88776 的技术分析文章,该漏洞是 NetScaler nsppe 的 Oracle TNS 记录解析器中一个预认证整数下溢,会导致越界写入和包引擎崩溃。

查看仓库
21127天前尚未审核

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2026-88776:NetScaler nsppe(预认证越界写入)

DataStream / Oracle TNS 记录解析器中的整数下溢

摘要

NetScaler 可以对 Oracle 数据库进行负载均衡。将一个 ORACLE 类型的 vserver 指向它,数据包引擎就会开始自己讲 Oracle TNS 协议,用内置的处理程序解析客户端流量。该处理程序为每个连接维护一个小型状态机,以便记住自己处于 TNS 记录中的哪个位置。

其中一个状态表示“我正处于一条记录的中间,还有更多字节即将到来。”当下一个分段到达时,处理程序读取其长度并减去 10,因为每个分段中有 10 个字节是头部。

从来没有人问过,如果分段短于 10 字节会发生什么。

发送一个这样的分段试试。一个 1 到 9 字节的残缺分段进入该状态,长度变为负数,而由于长度存放在一个无符号 16 位寄存器中,它并不会变成负数。它会回绕成一个巨大的值,最高可达约 64 KB。然后处理程序就愉快地将这么多数据从你的数据包中 memcpy 到 .bss 中一个固定的 0x748 字节暂存缓冲区里。该引擎不是 PIE,因此被践踏的地址永远不会移动。

你不需要登录。你甚至不需要 vserver 后面有数据库,因为设备自己就会应答 TNS 握手。整个攻击就是一次 TCP 会话。

两部分都进行了现场演示:

  • 触发回绕后的长度,数据包引擎会因 SIGSEGV 而崩溃,导致设备的数据平面宕机约一分钟。确定性、可重复、可循环触发。
  • 调整长度,你就会得到安静版本。攻击者字节落在暂存缓冲区旁边的全局变量上,而引擎继续运行。那是一个写入原语,而不仅仅是崩溃。

根本原因

状态机,以及如何操纵它

处理程序将其每连接状态存储在 [pcb+0x15a] 处。大多数状态都很无聊。这里重要的是 0x1F4,它表示“记录中间,等待继续”,而你只需使用普通的协议字节就能将连接引导到该状态:

record type 6 -> deep-parser state 6 -> byte 0x03 (TTIFUN)
  -> state 0x126 -> TTC function byte 0x5e (OALL8)
  -> jump table 0x23589e0, index 0x59 -> writer at bfe27b:
       [pcb+0x15a] = 0x1F4

该连接上的下一个数据包随后在 0x1F4 上进行分发,经由 bd49a7 进入 bd5362,并落在这里:

bd5432: memset(0x30a7e60, 0, 0x748)    ; scratch region (ends 0x30a85a8)
bd5445: mov   rcx,[rbp-0x208]          ; inbound packet buffer
bd544c: movzx eax,WORD [rcx+0xf2]      ; u16 wire length of the segment
bd5453: add   eax,0xfffffff6           ; len = len - 10   <== THE UNDERFLOW
bd5456: mov   WORD [0x30a8476],ax      ; wrapped length PERSISTED to .bss
bd545d: movzx edx,ax                   ; memcpy length (1..9 -> 0xfff7..0xffff)
bd5460: mov   rsi,[rcx+0xe8]
bd5467: add   rsi,0xa                  ; src = payload + 10
bd546b: mov   edi,0x30a8075            ; dst = FIXED .bss global
bd5470: call  1b075e0                  ; memcpy: up to ~64 KB OOB write
bd5475: mov   BYTE [0x30a8478],1

像读一句话那样读它。取该段的长度。减去 10。存储结果,交给 memcpy,完成。整个过程没有任何地方会问“长度减 10”是否还是一个合理的数字。

并不存在的防护

我们统计了该函数中对该长度字段的每一处引用。共三十处。其中恰好只有一处是检查,位于 bd4083,而它所做的只是与零进行比较。零长度的段会被拒绝。其他所有长度,包括 1 到 9,都会直接进入减法运算。

代码显然相信,当状态 0x1F4 执行时,状态机已经交付了一条足够完整的记录。状态机从未做出过这样的承诺。一个作为独立数据包到达的残缺段满足所有分发条件,并且会短五个字节出现。

真正令人恼火的是,厂商知道这一类 bug。在同一个二进制文件的其他地方,sub_119c940 执行完全相同的“长度减常量”运算,并用 cmp eax,0x3f9 / ja 对其进行门控。安全模式就在那里。只是这个位置没有使用它。

回绕时会发生什么

目标地址 0x30a8075 位于一个 0x748 字节的暂存区域中,其前方只有 0x533 字节的合法空间。回绕后的拷贝会带着你的字节越过该边界,进入相邻的 DataStream 和协商全局变量。而回绕后的长度本身会被持久化到 0x30a8476,后续代码会从那里读回它并信任它。这是第二条破坏路径,与 memcpy 相隔一步。


触发条件

设置只需一行配置,即标准的 DataStream 部署:

add lb vserver v ORACLE <ip> 1521

无需后端。该设备自行终止 TNS 并构建自己的 Accept 数据包,包括 "Netscaler" 厂商字符串等全部内容。

该对话分为四个步骤:

1. TNS Connect (version 0x13A)
     <- the appliance answers Resend(11), then Accept(2), 32 bytes, v0x139

2. one complete, benign TTC round-trip
     (some builds like to glue your runt onto the previous segment;
      this resets the segmentation so the runt lands alone)

3. the arming segment: a TNS Data packet whose declared length is
     actual + 32, carrying TTC bytes {03 5E} (TTIFUN / OALL8)
     -> the state machine latches [pcb+0x15a] = 0x1F4, mid-record

4. the runt: 1-9 bytes, sent as its own TCP segment
     -> passes the zero check, dispatches on 0x1F4
     -> length - 10 wraps
     -> memcpy(0x30a8075, payload+10, ~0xFFF6)
     -> the packet engine dies

步骤 1 到 3 是纯对话。步骤 4 是五个字节。


观察到的崩溃行为

这已在 14.1-73.30 设备上触发过两次,同一台机器、同一构建、两次独立运行。两次数据包引擎都发生了 SIGSEGV 并产生了匹配的核心转储,ns.log 在该时间窗口内记录了信号 11,数据平面停机约 60 秒进行热重启。

阴性对照在两次运行中均通过。运行完全相同的对话,但将最后一段改为连贯的 10 个字节,则什么也不会发生。引擎处理它并继续运行。短包长度是唯一重要的变量。

下载工具