the KASLR graveyard: every way i tried to leak ntoskrnl on Win11 25H2, and what killed each one
For there is nothing covered, that shall not be revealed; neither hid, that shall not be known.
Luke 12:2 (KJV)
i had a signed driver with arbitrary kernel read and write. CYREN's amp.sys,
shipped with their AV product, exposes \\.\AMP with an IOCTL
(0x226003, METHOD_NEITHER, no ProbeForRead /
ProbeForWrite) that gives unrestricted kernel memory access from any user
process. code 5 with command 26 reads any kernel address into an internal buffer; code
5 with command 2 copies that buffer out to userspace. code 1 writes a DWORD of zero to
any address. that's the read primitive, the write primitive, and the goal:
NT AUTHORITY\SYSTEM on Windows 11 25H2.
the plan was simple. leak ntoskrnl.exe's base address, walk
PsInitialSystemProcess to find System's EPROCESS, read its token, write it
into my process's EPROCESS. standard token steal, same playbook that's worked since
Windows 7. the read primitive handles everything except one thing: the kernel base
address. i don't know it, and on 25H2, nothing will tell me.
this is the catalog of everything i threw at that problem. not in hindsight, not curated to look smart. in the order i tried them, with the actual error messages and crash dumps.
the target
Windows 11 25H2, build 26200.8655. VMware Workstation VM on an AMD Ryzen 9 5900X host. 16GB
RAM. HVCI off. VBS off. Secure Boot off. UMIP off (confirmed: sidt and
sgdt both work from CPL3). the VM is joined to no domain, no Defender
tamper protection, no EDR. easy mode.
the user is noob, medium integrity, no admin, no special groups.
amp.sys loads at boot via the CYREN AV install and creates
\\.\AMP with a default DACL -- any user can open it.
what 25H2 changed
starting with 24H2, Microsoft added the KASLR Leaks Restriction.
Yarden Shafir at Windows Internals wrote the definitive deep-dive on
how it works
internally and it's required reading if you want to understand the dispatch chain
from NtQuerySystemInformation down through
ExpQuerySystemInformation to the ExIsRestrictedCaller gate.
the short version: the implementation is a function called
ExIsRestrictedCaller that gets called from inside
ExpQuerySystemInformation and every other NtQuery* dispatch
path. it checks a WIL (Windows Implementation Libraries) feature flag named
Feature_RestrictKernelAddressLeaks_private_IsEnabled. if the flag is on
(and on 25H2 it is), it calls
SeSinglePrivilegeCheck(SeDebugPrivilege, PreviousMode). if you don't hold
SeDebugPrivilege, the function returns true -- meaning "yes, this caller is
restricted" -- and the dispatch handler zeroes every kernel pointer in its output
buffer before returning it to userspace.
i confirmed this in IDA. the gate DWORD for the feature flag lives at ntoskrnl RVA
0xFC3A88. on this build it holds 0x57 (enabled + cached).
writing 0x00000000 to it via amp.sys disables the check for
the current call. i verified: after the write,
NtQuerySystemInformation(SystemHandleInformation) returns real kernel
Object pointers instead of zeros.
but here's the catch. the gate re-arms itself. WIL's feature state is not a
simple toggle -- it's a cached evaluation that the kernel re-runs periodically.
i'd write zero, confirm zero, make one NtQuerySystemInformation call, get
real pointers, and by the next call the gate was back to 0x57. or worse,
it came back as 0x00040004, a different enabled state. writing zero
doesn't stick. the feature table around the gate is full of 0x57 values
-- 39 feature states packed into a table, all evaluated by the same WIL
machinery.
so you get one call through, maybe. and then it closes. and you need the base address
before you can write to the gate, because the gate is at
base + 0xFC3A88 and you don't know base.
that's the catch-22. everything below is what i tried to get out of it.
attempt 1: NtQuerySystemInformation (the obvious one)
NtQuerySystemInformation takes a class number that tells it what info you
want. the ones that matter for KASLR leaking (the full list is in phnt's ntexapi.h):
- class 11 (
SystemModuleInformation) -- all loaded kernel modules with their base addresses. this is the one everyone used. - class 16 (
SystemHandleInformation) -- every handle in every process, with the kernelObjectpointer for each. - class 64 (
SystemExtendedHandleInformation) -- same as 16 but with extra fields, same kernel pointers. - class 5 (
SystemProcessInformation) -- per-process info, used to leakEPROCESSaddresses indirectly.
on 25H2, class 11 still succeeds (returns STATUS_SUCCESS), the buffer
fills up with 196 module entries, but every ImageBase field is zeroed.
the module names are there, the sizes are there, the addresses are gone.
i tried class 16 -- same deal. 35,000+ handles returned, every
Object pointer zeroed. class 64 -- same. class 5 -- returns process info
but no kernel addresses anywhere. i dumped the raw buffer and scanned every qword for
the 0xFFFF high 16 bits that identify kernel pointers. zero hits across
2MB of data.
ExIsRestrictedCaller got them all.
attempt 2: NtQueryInformationProcess / NtQueryInformationThread
these take their own class numbers (documented in ntdoc's PROCESSINFOCLASS table and the thread equivalent). the ones that used to leak kernel addresses:
- class 0 (
ProcessBasicInformation) -- returnedPEBaddress and kernel pointers. - class 7 (
ProcessDebugPort) -- returned the debug port kernel object pointer. also used for anti-debug. - class 49 (
ProcessConsoleHostProcess) -- returned a kernel pointer to the console host process. this was the go-to KASLR leak for years.
i tried every class from 0 to 50 on both APIs.
every class that historically returned kernel pointers now returns either
STATUS_ACCESS_DENIED (0xC0000022) or succeeds with the
kernel pointer fields zeroed. the restriction isn't just in
NtQuerySystemInformation -- it's in every
NtQuery* dispatcher that touches kernel addresses.
ExIsRestrictedCaller is called from each one individually.
attempt 3: EnumDeviceDrivers (psapi)
EnumDeviceDrivers in psapi.dll was the classic KASLR bypass.
it went through a different code path than
NtQuerySystemInformation -- or so people thought. turns out on
24H2+, psapi's EnumDeviceDrivers calls
NtQuerySystemInformation(SystemModuleInformation) internally. same
dispatch, same ExIsRestrictedCaller gate, same zeroed output.
dead end. the only non-NtQSI path i could think of was direct device I/O, which is
what amp.sys already provides.
attempt 4: sidt / sgdt (hardware registers)
the IDT and GDT live at known offsets from the kernel base. on older Windows, you'd
run sidt from CPL3, read the IDT base address, walk the interrupt handler
entries to find a function pointer into ntoskrnl, then page-walk
backward to the MZ header. clean, no APIs, no privileges needed.
UMIP was off on this box, confirmed:
sidt → IDT base = 0xFFFFF80000001000
sgdt → GDT base = 0xFFFFF8534B590000
# both valid kernel addresses. both readable from CPL3. UMIP off confirmed.
but when i tried to amp_read32 the IDT base, the VM immediately
bugchecked. PAGE_FAULT_IN_NONPAGED_AREA or
ATTEMPTED_WRITE_TO_READONLY_MEMORY, depending on which address i hit
first.
the IDT and GDT regions are not amp-readable. amp.sys uses
METHOD_NEITHER -- it dereferences the target address directly in
kernel mode with no ProbeForRead. if the page is mapped but has a
protection mismatch, or if VMware's nested paging treats certain system-structure
pages differently, the read faults. and since amp.sys has no exception
handler around the dereference, the fault goes straight to the bugcheck handler.
i tried the GDT next, same result. immediate BSOD. seven crashes in total, each from
a single amp_read32 call on a different address in the IDT/GDT region.
the VM went into a crash loop twice because the auto-restart hit the same fault before
i could SSH in.
both the IDT and GDT are always-mapped, per-CPU structures. the CPU itself dereferences
them on every interrupt and segment load. they are absolutely in memory. but
amp.sys can't touch them. probably because they're in a special page
protection region that VMware's hypervisor enforces, or because Windows marks those
pages with a protection that traps METHOD_NEITHER reads. either way:
dead.
attempt 5: the desktop heap (heap_kbase)
the user-mode desktop heap mapping in the TEB contains a self-referential kernel
pointer at offset +0x100:
heap_kva = *(uint64_t*)(hub + 0x100). this pointer holds the kernel VA
of the desktop heap. if you can read past the user-mapped portion into the kernel-only
portion, the heap objects (tagWND, THREADINFO, etc.) contain
raw kernel pointers to win32k and ntoskrnl.
i mapped the full 112KB user portion of the heap and scanned every qword. result:
exactly one kernel pointer. the self-referential one at hub + 0x100.
zero ntoskrnl pointers, zero win32k pointers.
then i used amp.sys to read the kernel-side copy at
heap_kbase = heap_kva & ~0xFFF. result: byte-for-byte identical to the
user mapping. the user mapping is a direct map of the same physical pages.
there's no hidden unsanitized data on the kernel side. the 24H2 restriction (or a
related change) already cleaned the heap objects.
the old technique of reading past the user mapping boundary (deep_heap)
also failed: the heap is exactly as large as the user mapping. reading past it hits
unmapped kernel addresses. the tagWND pti and
pEThread pointers that used to live here as raw kernel addresses are gone.
attempt 6: KUSER_SHARED_DATA
KUSER_SHARED_DATA at 0xFFFFF78000000000 (kernel alias) /
0x7FFE0000 (user alias) is always mapped and amp-readable. i confirmed
this:
amp_read32(0xFFFFF78000000000 + 0x330) = 0x75D3CAE3 # amp read works
*(uint32_t*)(0x7FFE0000 + 0x330) = 0x75D3CAE3 # user mapping matches
i scanned the full KUSD structure (0xA80 bytes) for any kernel pointer. zero hits.
the NtBuildNumber is there (0x6658 = 26200), the system root
path is there, but no kernel addresses anywhere in the struct. Microsoft cleaned this
one out long ago.
attempt 7: the gate crash-oracle (binary search via BSOD)
this was the ugly one. the gate DWORD is at
ntoskrnl_base + 0xFC3A88. i know the RVA. i don't know the base. but
ntoskrnl is large-page aligned (2MB boundaries, since the VM has
>2GB RAM). so the base is one of a finite set of candidates:
0xFFFFF800'00000000 + N * 0x200000.
the idea: read the DWORD at each candidate base + 0xFC3A88. if it's
0x57 (or has bits 0x11 set), we found the gate. if the page
is unmapped, amp.sys bugchecks. each wrong guess is one BSOD, one reboot,
one more candidate eliminated.
i wrote a script that reads an index from a file, tries the Nth candidate, and increments the index for the next run. on each boot, i run the script, it tries one address, either finds the gate or crashes, and i reboot and try again.
idx 0 (base + 0x200000): BSOD
idx 1 (base + 0x400000): BSOD
idx 2 (base + 0x600000): BSOD
# three reboots, three BSODs, crash loop. VM required manual recovery.
ntoskrnl loads somewhere in a range of about 512 possible 2MB-aligned
addresses. that's 512 potential crashes, each requiring a reboot. at 90 seconds per
crash-reboot cycle, that's 13 hours of crashing. theoretically possible. practically
insane.
attempt 8: prefetch sidechannel (EntryBleed on Windows)
hackyboiz published a writeup showing that the Linux EntryBleed prefetch sidechannel
(CVE-2022-4543)
works on Windows too, because KVA Shadow is disabled by default on modern CPUs. the
technique uses prefetchnta / prefetcht2 timing to determine
which addresses are TLB-cached, scanning the entire kernel address space for the
syscall entry point.
two problems. first, the writeup explicitly states: "reliable only on recent Intel
processors. on AMD CPUs, results are inconsistent." this box is a Ryzen 9 5900X. second,
this VM runs under VMware's nested paging (NPT/EPT), which flattens TLB timing. the
prefetch instruction hits VMware's shadow page table, not the guest's
TLB. the timing difference between cached and uncached addresses is dominated by
VMware's hypervisor overhead, making the sidechannel noise floor higher than the
signal.
i ported the prefetch-tool PoC from exploits-forsale and ran it. results: random noise. no consistent timing peaks. after 30 minutes of scanning, the tool reported zero candidates with sufficient confidence.
attempt 9: the admin oracle (SeDebugPrivilege from another account)
the restriction checks for SeDebugPrivilege. admins hold it in their token (disabled
by default, but can be enabled). there was a second account on the box
(exp, full admin) with SSH access.
the approach: SSH in as exp, enable SeDebugPrivilege, call
NtQuerySystemInformation(SystemModuleInformation), read the
ntoskrnl base, write it to a file. then switch back to noob
and proceed with the amp.sys chain using the leaked base.
# as exp (admin):
[*] NtQSI(11=ModuleInfo): st=0x0 len=58024
[*] 196 kernel modules:
[0] base=0xFFFFF805C0E50000 size=0x1450000 ntoskrnl.exe
[+] *** NTOSKRNL BASE = 0xFFFFF805C0E50000 ***
this worked. exp with SeDebugPrivilege got 196 module entries with real
addresses. ntoskrnl.exe at 0xFFFFF805C0E50000. the entire
KASLR problem, solved by a second account with admin rights.
is it a KASLR bypass from an unprivileged user? no. it's a KASLR bypass from an admin user, which was never restricted. but it got me the base address, which is what i needed.
what i learned
the KASLR Leaks Restriction on 25H2 is thorough. it's not a single check you can NOP
-- it's per-dispatcher, per-call, re-evaluated by WIL. the gate DWORD can be poked
for one call, but it re-arms. the hardware register approach (sidt /
sgdt) is dead because the driver can't read those memory regions without
faulting. the desktop heap is sanitized. KUSER_SHARED_DATA is clean. the
prefetch sidechannel is neutralized by AMD + nested paging.
the restriction's real strength is that it removed every easy leak. the remaining options all require either a second primitive (physical memory, MSR access, a known-offset structure) or a second account. on a real target with no second account, you'd need either:
- a driver with physical memory access (like
xacone's
eneio64.sysapproach: scan physical memory 0x0-0x100000 for the Low Stub, extractKiSystemStartup's RIP fromKPROCESSOR_STATE, subtract the entry point RVA) - a driver with MSR read (like CVE-2025-8061's
LnvMSRIO.sys: readIA32_LSTARto getKiSystemCall64's address) - a timing sidechannel that works on AMD (none currently published)
- the WIL gate poke for exactly one
NtQSIcall, if you can find the gate address without KASLR (circular)
or you do what i did: get the address from somewhere else and move on. the token steal
via PsInitialSystemProcess (RVA 0xFC5AF0) works perfectly
once you have the base.
PsInitialSystemProcess (0xFFFFF805C1E15AF0) = 0xFFFFBA0E416E2040 # System EPROCESS (PID 4)
System Token (EPROCESS+0x248) = 0xFFFFA808382894B9 # _EX_FAST_REF
# ActiveProcessLinks walk: 119 entries. found our EPROCESS (PID match).
# amp_write0 our token → PreviousMode flip → NtWriteVirtualMemory the real token in.
# cmd.exe spawns. whoami: nt authority\system.
once you have the base, the rest is just offsets. UniqueProcessId at
+0x1D0, ActiveProcessLinks at +0x1D8, Token at +0x248,
PreviousMode at KTHREAD+0x232. i confirmed all of these against build
26200 and they're correct. the hard part was never the token steal. it was getting
that first address.
and yeah, credit where it's due, the restriction works. i spent way longer than i
should have on this. it used to be one NtQuerySystemInformation call and
you were done. now you need either a second bug (physical memory, MSR access) or a
second account. that's annoying, which means it's doing its job.
but the driver is still there. the gate can still be poked for one call. and i had an admin account on the box. one SSH session later i had the base and was done.
a nice double tap; kernel pointers are zombie land
i disassembled ExIsRestrictedCaller in IDA and pulled the raw bytes
off the live kernel with the amp.sys read primitive. the function is more
interesting than the public writeups let on. it's not one check, it's two,
and they're independent:
// IDA decompilation of ExIsRestrictedCaller (ntoskrnl RVA 0xA105FC)
__int64 ExIsRestrictedCaller(KPROCESSOR_MODE a1, DWORD *a2)
{
// check 1: PreviousMode bypass
if (!a1) // PreviousMode == KernelMode
return 0; // not restricted, skip everything
// check 2: WIL feature flag + SeDebugPrivilege (fills *a2)
if (a2 && Feature_RestrictKernelAddressLeaks_IsEnabled())
*a2 = !SeSinglePrivilegeCheck(SeDebugPrivilege, a1);
// check 3: SeAccessCheck against SeMediumDaclSd (determines return value)
SeCaptureSubjectContext(&SubjectContext);
success = SeAccessCheck(SeMediumDaclSd, &SubjectContext, ...);
SeReleaseSubjectContext(&SubjectContext);
return !success; // TRUE if access denied
}
the first check is obvious: PreviousMode == KernelMode skips
everything. if you're calling from kernel mode, you're not restricted. this is
the PreviousMode bypass that the whole amp.sys chain was trying to exploit.
the second check is the one everyone knows about: the WIL feature flag
Feature_RestrictKernelAddressLeaks plus
SeSinglePrivilegeCheck(SeDebugPrivilege). if you don't hold
SeDebugPrivilege, *a2 gets set to 1 (restricted). but this value
only fills an output parameter that the caller reads separately. it doesn't
determine the function's return value.
the third check is the one nobody talks about:
SeAccessCheck against SeMediumDaclSd. this is what
actually gates the return value. i pulled SeMediumDaclSd off the
live kernel via amp.sys. it's a SECURITY_DESCRIPTOR with a NULL DACL (everyone
has access) but a SACL with a mandatory label. the mandatory label enforces
integrity level -- if it's set to high-IL, every medium-IL caller fails
SeAccessCheck and the function returns TRUE (restricted).
so it's a belt-and-suspenders design. the WIL flag gates one thing (whether
the output pointers get zeroed at the call site), and the SACL gates another
(whether the function returns restricted at all). you'd need to defeat both to
get raw kernel pointers back. the WIL flag re-arms itself when you poke the
gate DWORD. the SACL is hardcoded in .rdata and can't be poked
without the kernel R/W primitive, which needs the base address, which is what
you're trying to leak.
kernel pointers are zombie land. you can shoot at them from every angle and they just keep coming back zeroed.
round 2: every other lane i could think of
after writing up the first nine attempts i went back and tried harder. fired everything i could think of from the unprivileged user.
brute-force NtQuerySystemInformation (classes 0-260)
scanned every SYSTEM_INFORMATION_CLASS from 0 to 260. all 261 classes.
a few returned data. none had kernel pointers.
class 5 (ProcessInfo): 337KB, 0 kptrs
class 11 (ModuleInfo): 62KB, 0 kptrs # ImageBase fields zeroed
class 16 (HandleInfo): 3.6MB, 0 kptrs # Object fields zeroed
class 22 (PageFileInfo): 106KB, 0 kptrs
class 57 (ExtProcInfo): 479KB, 0 kptrs
class 64 (ExtHandleInfo): 6.1MB, 0 kptrs
class 66 (BigPoolInfo): 397KB, 0 kptrs # VirtualAddress fields zeroed
class 234 (FeatureConfig): 17KB, 0 kptrs
class 241 (NumaPerf): 1MB, 0 kptrs # ASN.1 blob, no pointers
also tried every class of NtQueryInformationProcess (0-100) and
NtQueryInformationThread, plus
NtQueryObject, NtQuerySection,
NtQueryTimer, NtQueryEvent,
NtQueryMutant, NtQuerySemaphore,
NtQueryInformationToken, NtQueryInformationJobObject,
NtQueryVirtualMemory, and NtSystemDebugControl.
zero kernel pointers everywhere. the restriction covers every surface.
firmware tables (SMBIOS / ACPI)
GetSystemFirmwareTable lets any user read ACPI and SMBIOS tables.
these are copied from physical memory by the kernel, so i thought maybe an address
survived in the table data. queried every ACPI table (MCFG, FACP, SRAT, WAET, APIC,
WSMT) and the full SMBIOS structure. 13KB of SMBIOS data, 768 bytes of ACPI tables.
zero kernel pointers.
RPC endpoints (381 total)
enumerated all 381 RPC endpoints on the box. 150 unique interface UUIDs. identified
the high-value ones: samr (SAM), lsarpc (LSA),
spoolss (Print Spooler), svcctl (SCM),
WinReg (Registry), EventLog, KeyIso (CNG
Key Isolation), ProcessTag, StateRepository,
AppIDSvc, LicenseManager.
335 of 381 accepted unauthenticated management queries
(RpcMgmtIsServerListening returned RPC_S_OK). that tells
you the server is alive, but it doesn't mean you can call methods. the actual method
calls enforce auth: OpenSCManager works but
EnumServicesStatusEx returns ACCESS_DENIED.
OpenEventLog returns ACCESS_DENIED outright.
WTSEnumerateProcesses worked and returned 210 processes, but only PIDs
and names. no kernel addresses.
crash dumps
the BSODs from the gate crash-oracle (attempt 7) left crash dumps on disk.
C:\Windows\memory.dmp (679MB) and five minidumps in
C:\Windows\Minidump\. i copied one with an admin account and read it.
PAGEDU64 signature confirmed
PsLoadedModuleList: 0xFFFFF801EADA52D0 # ntoskrnl module list head
PsActiveProcessHead: 0xFFFFF801EADB5B40 # process list head
KdDebuggerDataBlock: 0xFFFFF801EACB1040 # debugger data
PfnDatabase: 0xFFFFF801EAE76C78
the dump header contains four kernel addresses in the 0xFFFFF8 range.
any one of them gives you the KASLR slide. this is a real leak.
but: those addresses are from the boot that crashed. after the reboot, KASLR
re-randomized. and the dump files are ACL'd Administrators:(F) with a
high mandatory label. an unprivileged user can't read them.
so it's not a live bypass. it's proof that the data exists on disk in cleartext, and if the ACLs are ever wrong (WER sometimes leaves dumps world-readable), or if you can read the dump through a side channel before the reboot finishes, you have the kernel base. the KASLR restriction sanitizes API responses but does nothing about crash dump files.
VMware backdoor (port 0x5658)
this is a VM-specific angle. the VMware hypervisor exposes a backdoor via I/O port
0x5658. on this VM, CPL3 IN to that port doesn't trap -- it
goes straight to the hypervisor. the backdoor responds, returns a version number
(0x06), and even opens an RPC channel (cookie 0x10000).
VMwareToolboxCmd.exe stat speed and stat hosttime both
work from the unprivileged user, proving the RPC layer is functional.
but the RPC commands are handled by vmtoolsd inside the guest, and they
don't expose kernel memory layout. the info-get guestinfo.* commands
return nothing useful on Workstation (those are ESX features). the backdoor is a
channel, not a leak. it bypasses the guest OS entirely, which means it bypasses the
KASLR restriction, but it also doesn't know about ntoskrnl's load
address. the hypervisor manages guest physical memory, not guest virtual memory.
CPUID hypervisor leaves (0x40000000-0x40000010) return VMware
identification and feature bits, but no memory addresses.
PDH performance counters
tried reading \Process(System)\Virtual Bytes,
\Memory\System Code Total Bytes, and every other counter that might
embed a kernel address as a raw value. PdhCollectQueryData failed with
PDH_CANNOT_CONNECT_TO_MACHINE (0x800007D3). the PDH counter path format
was wrong or the counter provider needs the machine name.
what else
- Toolhelp32:
CreateToolhelp32Snapshoton PID 4 (System) returnsACCESS_DENIED. can't enumerate System's modules. - EnumProcessModules on PID 4:
ACCESS_DENIED. - QueryFullProcessImageName on PID 4:
ACCESS_DENIED. - 929 ETW providers: registered but querying them for trace data is complex and unlikely to leak addresses (traces are structured, not raw memory).
- VMCI device (
\\.\VMCI): opens from unprivileged user, but the IOCTL surface is for inter-VM communication, not memory inspection. - crash dump ACLs: both
memory.dmpandMinidump\*areAdministrators:(F) SYSTEM:(F)with high mandatory label. locked down.
references
- Yarden Shafir -- KASLR Leaks Restriction (Windows Internals). the authoritative breakdown of the
ExIsRestrictedCallerdispatch chain, the WIL feature gates, and what changed at the kernel level in 24H2. if you read one link here, read this one. - hackyboiz (L0ch) -- Bypassing Windows Kernel Mitigations: Part 0. covers the prefetch sidechannel approach (EntryBleed / CVE-2022-4543) adapted to Windows, and why it works on Intel but not AMD. good analysis of the
ExIsRestrictedCallerandFeature_RestrictKernelAddressLeaksinternals. - xacone (Yazid) -- Breaking KASLR on Windows 11 24H2 using an HVCI-compatible Driver with Physical Memory Access. the Low Stub physical memory scan approach: read
KPROCESSOR_STATEfrom physical 0x0-0x100000, extractKiSystemStartup's RIP, subtract the entry point RVA. works on 24H2 with a physical-memory driver likeeneio64.sys. - Quarkslab (Luis Casvella) -- Exploiting a vulnerable driver (CVE-2025-8061). MSR read approach via
LnvMSRIO.sys: readIA32_LSTARto getKiSystemCall64's address, deriventoskrnlbase. separate driver class, same goal. - Yarden Shafir -- An End to KASLR Bypasses? (Windows Internals). the follow-up post covering the telemetry/audit side: how Microsoft detects repeated failed
NtQuerySystemInformationcalls and what the restriction looks like from the defender's perspective. - exploits-forsale -- prefetch-tool. the PoC implementation of the EntryBleed prefetch timing attack, portable to Windows. works on Intel, inconsistent on AMD, dead inside a VM with nested paging.
. _SiCk · 0xdeadbeefnetwork · afflicted.sh