In this week’s Defend(er) Against, we are going to look at the project called PPLBlade by tastypepperoni, where the objective is to bypass Protected Process Light (PPL) to avoid Windows Defenders processing dumping detections.
You can find the project that we are discussing right here:):
GitHub – tastypepperoni/PPLBlade: Protected Process Dumper Tool
Facts up fronts:
- Short blog with some GOLD at the end.
- Lab device configured as such – The Blue Stack Cybersecurity Blog | Properly Configure MDE for Windows
- Code Integrity makes a cameo.
- We learn a lot about Code integrity.
Timeline:
- Thursday, September 21, 2023 4:06 PM – first run, not as local admin
- Thursday, September 21, 2023 4:08 PM – second run, as local admin
Running as admin we immediately get the below message.
With this I’m starting to think about what features could be at play here. I don’t see any ASR rules in effect here (prevalence rule was in Audit mode, as I wanted to test other blocking mechanisms), certainly nothing in the MPLog to contradict that. We did lowfi on the executable itself.
So, what is it? Well, what else can block drivers? WDAC? Code integrity?
Let’s start with Code Integrity because I know I don’t have any WDAC policies deployed. If we crack open event viewer and look at Microsoft-Windows-CodeIntegrity/Operational, we can see if that’s what it was. Scrolling down to my timestamps we see the following two entries; these show us that the PPLBLADE.SYS driver was revoked and subsequently blocked by Code Integrity! Boom!
We also see the Code Integrity activity in the telemetry for this device’s timeline. This being from the M365D portal (security.microsoft.com).
So, what is code integrity? Well, let me share the wisdom Mr. Jeffrey Sutherland graciously provided me with on the matter.
“Code integrity has two sub-features: Kernel Mode Code Integrity (KMCI) which enforces what is able to run in kernel; and User Mode Code Integrity (UMCI) which enforces what runs in user mode.
KMCI has existed since Windows Vista and enforces by default a hardcoded policy defined in Windows. Beginning with Windows 10, WDAC allows customers to define additional policy that layers on top of the hardcoded policy to further restrict what runs in kernel. Additionally, Windows has added (since RS5) a vulnerable driver blocklist that is conditionally enforced that blocks known malicious/vulnerable drivers from running in the kernel. Prior to Win11 22H2, the vulnerable driver blocklist enforced only if you turn on memory integrity or S mode. With Win11 22H2, it is on by default and can be turned on/off separately from any other feature.
UMCI is off by default on Windows. It was first introduced in Win8 for Windows 8 RT. With Windows 10, WDAC allowed customers the ability to turn on UMCI and enforce a customer-defined policy to control what is allowed in user mode. S mode, and Windows 11 SE also leveraged WDAC policy to enforce UMCI rules. In Win11 22H2, UMCI is turned on in audit mode only on clean installs in support of Smart App Control (the “audit mode” is called “evaluation mode” for SAC). Eventually, SAC will turn UMCI on in enforcement for some subset of users’ devices. SAC policy allows only code that is signed by a cert chaining to CAs who are part of Microsoft’s trusted root program or code that is predicted to be safe based on cloud-driven AI.
VBS provides a secure execution environment where certain processes can run. It does not trust the normal world kernel, thus providing a true security boundary against even kernel-based attacks. However, VBS is plumbing only and doesn’t provide any inherent protection alone. But, when you turn on features that use VBS, those are now protected against tampering. Memory integrity is one such feature. When you turn on Memory integrity (aka HVCI), the KMCI process that normally just runs in the kernel is now run instead in the VBS environment’s secure kernel. As a result, all code that wants to run in the kernel must first go through KMCI checks in the secure environment. And all dynamic code is blocked in the kernel. Code flow guard is turned on for kernel code as a side effect of turning on memory integrity.
With memory integrity, kernel memory pages are never both writable and executable. When you load a driver or any other code in kernel, the memory pages are writable but not executable. They are then transferred by the hypervisor to the secure kernel where the code is validated by KMCI. Once validated, the pages are marked executable only and not writable and then transferred back to the normal world kernel where it finally is run.”
This is a great example of why taking the time to configure devices appropriately with what is provided natively within Windows is crucial. Depending on just your AV or EDR to do everything isn’t enough these days, defense in depth is truly on display here.
Really not much I can add beyond that! Hope this was valuable, it certainly was for me!
Blogs to read if you want to learn more about this:
- KB5020779—The vulnerable driver blocklist after the October 2022 preview release – Microsoft Support
- https://learn.microsoft.com/en-us/windows-hardware/design/device-experiences/oem-hvci-enablement
- https://learn.microsoft.com/en-us/windows/security/hardware-security/enable-virtualization-based-protection-of-code-integrity#how-to-turn-on-memory-integrity