Modern Windows Userspace Exploitation
Modern Windows Userspace Exploitation
Saar Amar
MSRC-IL
# whoami
• @AmarSaar
• MSRC-IL
• Addicted to CTFs!
• @pastenctf team member
The reason to live: Exploit!
• Easy!
• Find an awesome 0day vulnerability
• ???
• Profit!
• Yeah…
Mitigations. Mitigations. Mitigations.
• Control-flow integrity mitigations
• DEP
• CFG
• CFI
• Supporting mitigations
• Child Process Policy
• ASLR
• SafeSEH/SEHOP
• Heap randomization && metadata protection
• Sandboxing / Containers
• LPAC Even more! See https://www.microsoft.com/en-
• WDAG us/msrc/bounty-mitigation-bypass
Exploit through the ages
• Windows 10 TH1
• Windows 10 RS5
The “Winworld” challenge
• Person’s copy c’tor used in the narrator clone function skips this initialization!
friend
old shared_ptr refcount = 3
p->friends[0] before copy ctr
friend
p->friends[1] before copy ctr
Person p
global
humans list
friend
p->friends[0] after copy ctr
new shared_ptr refcount = 4
friend
p->friends[1] after copy ctr
friend
p->friends[2] after copy ctr
Triggering the clone
• This happens when a robot reaches the center of the maze, using the move command
• In Windows 7:
• Chunks in userblocks allocated continuously
• Person->name is an std::string
• Arbitrary read:
• Corrupt the std::string pointer and size
• Person->name is an std::string
• Arbitrary write:
• Corrupt the std::string pointer and size
• We need to leak our image base / ntdll / some libraries for gadgets and functions
• Shape the LFH so an std::vector object will be allocated on a dangling Person after the
UAF
• Output is the std::vector vtable address, from the base image .rdata
• VirtualAllocEx(…, PAGE_EXECUTE, …)
• Everything works!
Windows 7 Exploit
• Jump into it
• PROFIT
WINDOWS 7 DEMO
WINDOWS 10 TH1
Shape fails
NAME WORKAROUNDS
• Avoid touching the heap metadata
Heap Randomization and Metadata
• Spray allocations against randomization
Protection
EXPLAINED BOUNTY
The integrity of heap metadata cannot be Up to $15K
subverted and the layout of heap allocations is
not predictable to an attacker
What the RANDOM!
Bypassing LFH randomization on TH1
• Pool is CRNG random, but constant for the lifetime of the process
x x x
x
0 1 1 1 x
x
0 1 0 0
0 0 1 0
0 1 0 0
Bypassing LFH randomization on TH1
x x x
x
0 1 1 1 x x
x
0 1 0 0
1 0 1 0
0 1 0 0
Bypassing LFH randomization on TH1
x x x
x x
0 1
1
1 1 x x
x
1 1 0 0
1 0 1 0
0 1 0 0
Back to our TH1 exploit
NAME WORKAROUNDS
Known bypasses, see The Evolution of CFI Attacks
Control Flow Guard
and Defenses by @JosephBialek
EXPLAINED BOUNTY
Indirect branches are checked against a whitelist of Currently out of scope
targets, and if the check fails – terminate the
process
Windows 10 TH1 Exploit
• New exploit:
• Leak stack address
• Corrupt return address with the arbitrary write primitive
• Execute same ROP chain from before
• PROFIT
WINDOWS 10 TH1 DEMO
WINDOWS 10 RS5
Again…
NAME WORKAROUNDS
• Known bypasses on older versions
Arbitrary Code Guard
• Execute code in ROP
EXPLAINED BOUNTY
• Restricts allocating and mapping of +X pages UP TO $45K
• Restricts editing existing +X pages permissions
CIG
NAME WORKAROUNDS
• Use signed DLLs
Code Integrity Guard
• Execute code in ROP
EXPLAINED BOUNTY
Restricts loading of unsigned DLLs UP TO $45K
ACG bypasses – Edge use case
CreateFileMapping()
PAGE_EXECUTE_READ PAGE_READWRITE
Load script
Compile the bytecode
Parse into bytecode
MicrosoftEdgeCP.exe MicrosoftEdgeCP.exe
(content process) (JIT server)
BlockDynamicCode=ON BlockDynamicCode=OFF
Based on a diagram from “Bypassing Mitigations by Attacking JIT Server in Microsoft Edge” by Ivan Fratric
Edge ACG Old bypasses - Duplicate Handle
• In order to send its handle to the JIT process, the calling process first needs to call
DuplicateHandle on its (pseudo)handle.
• Content process needs to keep the handle of the target process (JIT process) with the
PROCESS_DUP_HANDLE access right
Edge ACG Old bypasses - UnmapViewOfFile
• Unmap the shared memory using • When JIT process calls VirtualAllocEx(),
UnmapViewOfFile() even though the memory is already
Load script
Compile the bytecode
Parse into bytecode
MicrosoftEdgeCP.exe MicrosoftEdgeCP.exe
(content process) (JIT server)
BlockDynamicCode=ON BlockDynamicCode=OFF
Based on a diagram from “Bypassing Mitigations by Attacking JIT Server in Microsoft Edge” by Ivan Fratric
“Pure” ACG Bypass - Warbird
• Caller can load a new trap frame with an arbitrary return address in userspace
• Nothing checks the CFG bitmap against it.
Working our way around ACG && CIG
• However…
Child Process Restriction
NAME WORKAROUNDS
• Implement execve in userspace
Child Process Restriction
• Chain a kernel exploit
EXPLAINED BOUNTY
A child process cannot be created when this UP TO $15K
restriction is enabled
WINDOWS 10 RS5 DEMO
Even more mitigations
• Containers/sandboxing
• LPAC, WDAG, etc.
• https://www.microsoft.com/en-us/msrc/bounty-mitigation-bypass
Killing bugs before they’re born
• Deterministic LFH