Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

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

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

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2025-24990_POC — CVE-2025-24990(Agere Systems 驱动程序)的概念验证 | Kitploit
工具/GitHubGitHub/moiz-2x/cve-2025-24990_poc
权限提升漏洞利用框架漏洞分析漏洞利用二进制利用
GitHubmoiz-2x/cve-2025-24990_poc

CVE-2025-24990_POC

CVE-2025-24990(Agere Systems 驱动程序)的概念验证

查看仓库
59139个月前Kitploit 审核通过

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

Windows Agere Modem 驱动程序(ltmdm64.sys)。该驱动程序非常老旧,默认情况下不会在我的测试机器上加载,因此我将在 BYOVD 场景中利用它。有趣的是,根据我的研究,该驱动程序自 Windows 7 起就已存在,并且至少有一个漏洞。此处

当时,MSRC 没有采取任何行动 🤡

漏洞

该驱动程序中的某些 IOCTL 使用了 METHOD_NEITHER,但未检查调用者提供的地址缓冲区是来自用户模式还是内核模式。以下是我用 OSR 解码的一个示例 IOCTL 代码:

这意味着你可以向 DeviceIoControl API 提供内核地址,驱动程序会正常处理它。

请注意,你必须先绕过 kASLR 才能泄露内核地址,我将使用 EnumDeviceDrivers(在 Windows 24h2 上,你需要 SeDebugPriv 才能执行此操作)。

空指针解引用

问题出在 IOCTL 0x802b200f(ud_response)中。同样,此 IOCTL 分发未验证我从用户模式提供的地址,但我稍后会利用它。

ud_response 调用 ll_load_diagnostics,我将到达以下代码:

在开始时,全局变量 eeprom 未被初始化,因此它将包含 NULL。以下是一个触发此问题的简单代码。

我稍后会利用这一点。

漏洞利用入口点 0x802b2003

此 IOCTL 简单地将驱动程序版本字符串 "8.36" 转换为数字 0x836(一个 DWORD),并将其写入调用者提供的地址(得益于 METHOD_NEITHER)。从技术上讲,我可以将这四个字节(36 08 00 00)写入任意内核地址。我将利用这一点来覆盖驱动程序的全局变量并改变执行流程。

我将这个 0x802b2003 称为 IOCTL_GET_VERSION

漏洞利用

任意空 1 字节:

回到空指针解引用的情况,我使用 VirtualAlloc API 分配一个固定地址(0x083600000000)。然后我使用 IOCTL_GET_VERSION 将上述四个字节写入 *(eeprom + 4)。当驱动程序稍后解引用 eeprom 时,它将从我分配的地址读取。

修复空指针解引用后,该 IOCTL 会根据缓冲区大小将字符串写入我从用户模式提供的地址。

此代码简单地演示了我上面描述的内容:分配一个缓冲区并用 0xAA 填充,修复空指针解引用,然后调用驱动程序。请注意,我分配了 11 个字节,但只向驱动程序提供了 10 的缓冲区大小,以观察其行为。

它向我的缓冲区写入一个固定的字节序列,然后将最后一个字节(第 11 个)置空,即使我只提供了大小为 10。它将我缓冲区中的最后一个 0xAA 替换为 0x00。这表明如果我提供的大小为 0,驱动程序仍会在目标地址写入一个 0x00 字节。

任意递减

现在我有了空字节和固定的 4 字节任意写入,让我构建其他原语。

此 IOCTL 会将全局 LtMsgEvent 设置为我提供的用户缓冲区,然后检查 WDM 是否为 null,如果是则再次将其设置为零。

然后在 0x802b2207 中,它将调用 ObfReferenceObject API。

在初始状态下,WDM 为 null,但借助 IOCTL_GET_VERSION,我可以将 WDM 设置为 0x36(它的大小只有 1 字节),而 LtMsgEvent 仍然是我的缓冲区。然后我将 WDM 置空并调用 0x802b2207。最后到达 ObfReferenceObject。我将这两个 IOCTL 称为 IOCTL_SET_LtMsgEvent 和 IOCTL_DEREF_LtMsgEvent。

使用 ObfReferenceObject 的漏洞利用技术会将我们 KTHREAD 的 PreviousMode 从 UserMode 更改为 KernelMode,你可以在此处阅读相关内容。然而,Windows 已修复此漏洞,因此我们无法使用它。

但 ObfReferenceObject 中的原语仍然存在。该 API 从我们提供的地址中减去 0x30,将结果转换为 8 字节整数,然后减去 1。

root@kitploit:~
*(signed long long)(LtMsgEvent-0x30) -= 1

但问题是它会检查下一个值是否为 0,或者当前值是否 < 1(解释为 8 字节有符号整数)。如果任一条件为真,它会跳转到 KeBugCheckEx 并使系统崩溃。

任意写入

有了任意递减,我需要找到其他地方来写入字节 0xFF,然后将其递减到我想要的字节,我找到了这个 IOCTL 0x802b2243:

我们将专注于 flip 分支。pbVar5 是我从用户模式提供的地址,可以是任何我选择的目标地址。我将字节 0x0C 写入 DAT_TARGET_EX(借助 IOCTL_GET_VERSION 和任意递减原语),并且我还在目标地址处将一个字节置空。第一次调用此 IOCTL 会在目标地址设置 0xC0,然后将其递减为 0xBF。第二次调用会在目标地址设置 0xFF(0xBF | 0xC0 = 0xFF)。一旦目标包含 0xFF,我只需将其递减到所需的值。

我将一次写入一个字节,并小心 ObfReferenceObject 中的 KeBugCheckEx。

任意读取

对于读取原语,我使用此处描述的技术(@carrot_c4k3)。我只需覆盖内核中的 UNICODE_STRING 对象(ExpManufacturingInformation),然后调用 NtQuerySystemInformation。由于 ObfReferenceObject 会调用 KeBugCheckEx,我将把 ExpManufacturingInformation 相邻的 8 个字节置空。

就是这样,现在我们有了任意 R/W,我们可以使用这些原语做很多事情。该驱动程序默认情况下不会加载,因此我将在 BYOVD 场景中利用它,并设置进程的 PPL。

在 Windows 11 22H2+ 中的漏洞利用:

我上面描述的漏洞利用在所有 Windows 版本中都有效,但由于 KeBugCheckEx 而不稳定。但在 Windows 11 22h2+ 中,有一种称为 ioring 的技术。该技术简单地将 ioring->Buffer 覆盖为可控地址。具体来说,我们可以分别用 0x083600000000 和 0x836 覆盖 ioring->Buffer 及其大小(使用 IOCTL_GET_VERSION)。使用此技术,我只执行 2 次写入,然后非常稳定地使用 R/W 原语。请注意,此方法需要泄露内核地址。

漏洞利用运行

Windows 默认情况下不会加载该驱动程序。因此你需要手动加载它。文件 ltmdm64.sys 位于 C:\Windows\System32\DriverStore\...\ltmdm64.sys,以管理员身份运行此命令,然后运行漏洞利用程序:

sc create ltmdm64_srv binPath="C:\Windows\System32\DriverStore...\ltmdm64.sys" type=kernel && sc start ltmdm64_srv

漏洞利用程序将使用 ioring 技术关闭 lsass.exe 的 PPL,并使用我的纯数据技术将 PPL 设置为 notepad.exe(win 11 24h2 需要 SeDebugPriv 为 enabled)

https://github.com/user-attachments/assets/05a35b38-d26c-484f-9fb7-137f8fe8c079

CVE 作者

我将此漏洞报告给了 ZDI。但似乎它与 Fabian Mosch 和 Jordan Jay 提交给 MSRC 的内容重复,因此此 PoC 仅展示该漏洞,并感谢他们的工作。 这几乎是我的第一个 CVE 😍

下载工具