More than a year ago, I joined Google Security after 7 years at Microsoft. It is fascinating to have the ability to compare how security is done on two different platforms and in different companies. A few weeks ago, I started playing again with Windows mitigations. I thought it would be fun on my free time. Microsoft Edge was the perfect candidate because it enables all the mitigations.
This post describes my approach in searching for mitigation bypasses. The next one explains how I extend the base primitive to control calls. The last one goes over all mitigations bypasses with proof-of-concept code.
Microsoft has a mitigation bypass bounty for the latest version of Windows. The bounty is open for mitigations bypasses (CFG, RFG, ASLR or others) and/or suggestions for new defence mechanisms. I made multiple submissions to the bounty and most of them were rejected. The reasons went from “by design” to “already known”.
A bounty for mitigation bypasses is an original idea but it’s a hard one to do. What a mitigation is supposed to protect can be perceived differently. The ability to fix an issue weight in considering a bypass legitimate. As an external contributor, you don’t know what was reported before and Microsoft rejects known bypasses. If you spend time on mitigation bypass research, you have no guarantee it will be accepted or even fixed. Microsoft updated the bounty page recently adding additional details on scopes.
In the next post, I describe how you can transform a read-write anywhere primitive into calling valid CFG functions and controlling all arguments:
Mitigation bounty — From read-write anywhere to controllable calls
This post describes how a read-write anywhere primitive can be used to call valid CFG functions repeatedly while…
The third post discloses 4 techniques to bypass mitigations that were not fixed:
Mitigation bounty — 4 techniques to bypass mitigations
This post discloses 4 techniques to bypass mitigations that were rejected by Microsoft as “by design” or “already known…
A mitigation bypass can start with a vulnerability. You find the right bug and sit on it until you found a mitigation bypass to submit. You assume this bug won’t be found by somebody else. I don’t like the idea to sit on bugs that could be actively used. I decided to simulate a vulnerability instead of using a real one.
I assume an attacker can find a bug leading to a similar primitive. This type of bugs is used in multiple exploit write-up or techniques. Using this primitive, my goal was executing custom code bypassing CFG or RFG.
You can find the detail implementation on these files:
- basic_examples.html— Usage examples for read-write anywhere and on calling anything (described in the next post).
- scripts/windbg_attach.ps1 — Script to attach to Edge instances automatically and setup the breakpoint to simulate the vulnerability.
Existing CFG & RFG research
Plenty of people did research on bypassing CFG. If you are interested, you can look at the following:
- Sam Thomas - Object Oriented Exploitation: New techniques in Windows mitigation bypass
- Tencent — Use Chakra Engine to bypass CFG
- Tencent — Bypass DEP and CFG using JIT compiler in Chakra engine
- Zhang Yunhai — Bypass Control Flow Guard comprehensively
- Trend Micro — Exploring CFG on Windows 10
- Francisco Falcón — Bypassing CFG on Windows 8.1 Update 3
- Yang Yu — Write Once, Pwn Anywhere (also discovered by James Forshaw)
- Alex Ionescu — CFG impact on Windows 8.1
RFG has been added few weeks ago on the fast and slow ring:
- Tencent — Return Flow Guard
Please send me a message on twitter if you would like to add a link to the previous lists.