This document discusses a presentation on practical Windows kernel exploitation. It covers the basics of kernel exploitation, common vulnerability classes like write-what-where and use-after-free, techniques for executing code, mitigation technologies, writing Windows kernel exploits for Metasploit, and improving reliability. The speaker works at SecureState researching and developing kernel exploits and is an open source contributor to projects like Metasploit.
1. Practical Windows Kernel Exploitation
Spencer (@zeroSteiner) McIntyre DerbyCon 5.0 Friday September 25th, 2015
2. Agenda
• Agenda
• Kernel Exploitation Overview & Basics
• Common Vulnerability Classes
• Executing Code
• Mitigation Technologies
• Kernel Exploits in MSF
• Writing Windows Kernel exploits for MSF
• Common Techniques Employed By MSF Modules
• Improving Reliability
3. About Me
• Spencer McIntyre
• Work at SecureState
• Research, Development, “Special” Projects
• BSOD-inducer
• Avid open source contributor
• Metasploit among others
• Python enthusiast
4. BSOD Warning
• BSODs are imminent
• None of the solutions here are fit-all
• Just aggregated from personal experience
Bug check from MS14-040 due to corrupted structures
6. Overview
• Why Kernel Exploitation?
• Downward trend of RCE over last couple years
• Last “Great” RCE MS08-067
• New RCE are generally in 3rd party software / libraries
• The kernel is always there
• Upward trend of client side exploitation as a foothold
• Social engineering
• Some great vulnerabilities coming from Pwn2Own and the wild
7. Recent Windows Kernel Vulnerabilities
Name Advisory / Details Released Public Exploit Code?
MS14-058 / CVE-2014-4113 October 14th, 2014 Yes
MS14-070 / CVE-2014-4076 November 11th, 2014 Yes
MS15-010 February 10th, 2015 Yes
MS15-034 / CVE-2015-1635 April 14th, 2015 Yes (DoS)
MS15-051 / CVE-2015-1701 April 18th, 2015 Yes
MS15-078 / CVE-2015-2426 July 29th, 2015 Yes
MS15-097 / CVE-2015-2510 September 8th, 2015 Yes (DoS)
• Incomplete list of recent “notable” vulnerabilities as of September 24th, 2015
• Notable because additional details were published outside the MSB / CVE
boilerplate verbiage
8. Common Vulnerability Classes
• Write-What-Where
• NULL Pointer Dereference
• Use After Free (UAF)
• Honorable Mention: Stack Buffer Overflow
• Exist, but not particularly common in Kernel land
9. Write-What-Where
• (Sometimes) Controlled data can be written to an attacker-controlled
location
• nt!HalDispatchTable is a popular target
• Controlling the Where is generally more important as it needs to be
more precise
• Exploitation is often stable
• Commonly exploited with IOCTL routines using NtDeviceIoControlFile
• Also more common than other classes in third party drivers
• Example exploits:
• MS11-080
• MS14-070
10. NULL Pointer Dereference
• Occurs when a NULL pointer is referred to as an object
• Exploitation is often stable
• NULL page can not always be mapped, mitigations exist
• Sometimes negative numbers from error statuses are used as pointers
• MS14-058 / CVE-2014-4113 for example
• Can be beneficial on 64-bit systems if truncated to a 32-bit number (resulting in
0x00000000ffffffff being used)
• Example Exploits:
• MS13-081
• MS14-058
11. Use After Free
• Pointer to an object is used after it has been freed
• Successful exploitation often requires re-allocating the freed object
• Not always reliable, depends on successful reallocation
• Failure to reallocate causes corruption of other structures
• More on this later
• Examples:
• MS15-010
12. Vulnerability To Code Execution
• Techniques dependent on class
• Write-What-Where
• Well documented, overwrite nt!HalDispatchTable+0x4
• HalDispatchTable can be resolved from the ntkrnlpa.exe
• Triggered on demand with NtQueryIntervalProfile
• NULL Pointer Dereference & UAF
• Similar in the sense that they are object-dependent
• UAF is more difficult to set up the object (not in user-land address space)
13. NULL Pointer Dereference / UAF
• An object is corrupted
• For UAF a replacement object is created
• No easy way to determine a suitable object
• Object size, layout and destination heap all must be considered
• Object needs to provide a primitive
• Generally Write-What-Where or Call
14. Useful Object: tagWND (Window)
• win32k!tagWND
• Pretty common object (CVE-2014-4113)
• Set two values for kernel code execution
• bServerSideWindowProc (Bit flag)
• lpfnWndProc (Pointer)
• Callback function can be triggered on demand
15. Mitigation Technologies
• Commonly encountered on modern systems
• The days of jmp esp died with XP
• Address Space Layout Randomization (ASLR)
• Only a semi-issue due to already having code execution
• Only need to worry about kernel addresses
• Driver bases can be determined
• Memory leaks or read primitives can disclose additional kernel addresses
• LoadLibrary & GetProcAddress are your friends
• Data Execution Prevention (DEP)
• NtAllocateVirtualMemory, VirtualProtect
• SMEP can be an issue (more on this later)
16. Mitigation Technologies
• NULL Page Mapping
• One of the oldest protections in EMET
• Pre-Allocate and squat on the page, mark with PAGE_NOACCESS
• Get around it by avoiding it (migrate into an unprotected process if
possible)
• Supervisor Mode Execution Protection (SMEP)
• Prevents user-land addresses from being executed from the Kernel
context
• Originally developed by Intel
• Support added to Windows 8
18. Disabling SMEP
• Some well-documented techniques
• See the “Further Reading & Resources” slide
• Use a ROP gadget in nt!KiConfigureDynamicProcessor to clear the
SMEP bit in the CR4 register
• Resolve the kernel address of the ROP gadget
• A few drawbacks to this approach
• Can’t be resolved with GetProcAddress like nt!HalDispatchTable
• Its in the PAGELK section on Windows 8.1
• Requires running in the native architecture, i.e. not WOW64
• If the kernel can’t be loaded (WOW64 or sandbox) a read primitive
needs to be available for resolution
20. Metasploit Windows Kernel Modules
• Divided into two categories based on implementation
• Ruby (relying heavily on RailGun)
• C (implemented as a Reflectively-loadable DLL)
• Don’t have to be local privilege escalation but almost all are
• Almost all directly steal / duplicate the token
• An alternative approach is to “clear” the ACL of a SYSTEM process to
inject into (e.g. ms13_053_schlamperei)
• Msf::Exploit::Local::WindowsKernel mixin for convenience
methods
21. Ruby Implementations
• Might be eventually deprecated in favor of RDLL1
• Well suited for simple NtDeviceIoControlFile-centric exploits
• e.g. MS11-080, MS14-002, MS14-070
• Benefits are that the exploit is a self-contained ruby file
• Failed attempts result in a lost session due to self-corruption
1 Details in issue #4715 https://github.com/rapid7/metasploit-framework/issues/4715
22. C Implementations
• Much more flexible
• Threads can be used
• Can be faster to write if extensive Windows API calls are necessary
• PoC exploits can be developed as standalone executables
• Primary benefit is the exploit can be injected into a dummy
process
• Results in stability if the exploit fails without a BSOD
23. Writing a Kernel Exploit for Metasploit
• C / Reflective DLL style is preferred
• General Steps:
1. Environment detection
• Is the session a meterpreter or running as SYSTEM?
2. Vulnerability check
• Often implemented in the “check” function, result is verified
• Checks are often for the file version and running services
3. Start a dummy process to host the malicious DLL
• If in a sandbox, load the DLL in the session process
4. The RDLL will (hopefully) exploit the vulnerability successfully and open
a new session
24. Shellcode
• Options are traditional raw bytecode or C,
but only for RDLLs
• C implementation is preferable and more
reliable
• Different version of Windows have
different token offsets
• Generic implementation uses
PsLookupProcessByProcessId then find
and replace
• Works across Windows versions
26. Sources of Instability
• Corrupted structures
• Token reference count
• Returning control after elevation
27. Corrupted Structures
• Certain objects are in a shared region between user & kernel lands1
• Handle table information without a system call for efficiency
• user32!gSharedInfo is available since Windows 7
• Region is read-only
• Back it up
• Read-only so restore from within the shellcode
• If structures are corrupted and code execution does not occur a BSOD
is imminent without a reliable write primitive
• nt!HalDispatchTable
1https://media.blackhat.com/bh-us-11/Mandt/BH_US_11_Mandt_win32k_WP.pdf
28. Token Reference Count
• “Stealing” the token can cause issues
• Token object has a reference count
• Possible workarounds
• Clear an ACL from a process
• Process still might die and cause instability
• Duplicate the token
• Not practical from raw shellcode
• Backup original token, Steal the token, Spawn a new shell, Restore the token
• Is practical from raw shellcode
• Exploit must be reliably triggered twice
29. Returning Control
• What to do if process dies after elevation?
• Find a suitable location to return control to
• Unwind the stack via assembly
• Microsoft uses a standard calling convention
• Not applicable in every situation, depends on the call
• Trivial to differentiate a user-land address vs kernel-land
30. Returning Control
• Last call in user-land ntdll!KiFastSystemCallRet
• First call in kernel-land nt!KiSystemServicePostCall
• KiSystemServicePostCall performs cleanup
operations and restores the user-mode context
• Can not directly return to user-land
• System call will probably fail but the status can be
set
• Be careful about allowing it to succeed
31. Returning Control
• Resulting shellcode is 29-bytes
• Not that size matters when
dealing with a local
Source:
https://gist.github.com/zeroSteiner/08802a798aeee05cb80a
32. 64-bit Exploitation
• Starting to pick up
• Exploits being written in C to support both architectures
• x64 uses one calling convention, only one
• WOW64 complicates things
• For Metasploit, migrate into or spawn a native process
• Check for pointer truncation
• Might help, might not
33. Closing Thoughts
• Kernel exploitation is flexible
• Code execution ahead of time can be leveraged
• Size matters not
• Hypothesis: Kernel exploitation is going to stick around for a while
• Practice and learn with a vulnerable driver
• https://github.com/hacksysteam/HackSysExtremeVulnerableDriver
34. Windows 10
• SMEP ROP gadget still in nt!KiConfigureDynamicProcessor
• Same instructions, different offset
• win32k.sys now split into 3 modules
• win32k.sys, win32kbase.sys and win32kfull.sys
36. Further Reading & Resources
• Kernel Attacks Through User-Mode Callbacks
• Tarjei Mandt, Black Hat USA 2011
• https://media.blackhat.com/bh-us-11/Mandt/BH_US_11_Mandt_win32k_WP.pdf
• SMEP: What is it, and how to beat it on Windows
• Mateusz ‘j00ru’ Jurczyk & Gynvael Coldwind
• http://j00ru.vexillium.org/?p=783
• Windows Kernel Exploitation Basics - Part 2 : Arbitrary Memory Overwrite
exploitation using HalDispatchTable
• dimanche , July 17th, 2011
• http://poppopret.blogspot.com/2011/07/windows-kernel-exploitation-basics-part.html
• Polishing Chrome for Fun and Profit
• Nils & Jon, August 29th, 2013
• https://labs.mwrinfosecurity.com/system/assets/538/original/mwri_polishing-chrome-
slides-nsc_2013-09-06.pdf
37. Further Reading & Resources
• Pwn2Own 2014: AFD.sys Dangling Pointer Vulnerability
• Sebastian Apelt, July 11th, 2014
• http://www.siberas.de/papers/Pwn2Own_2014_AFD.sys_privilege_escalation
.pdf
• One-Bit To Rule Them All: Bypassing Windows’ 10 Protections using a
Single Bit
• Udi Yavo, Februrary 10th, 2015
• http://breakingmalware.com/vulnerabilities/one-bit-rule-bypassing-windows-
10-protections-using-single-bit/