Finally I manage to put together a computer capable of running Device Guard and I’ve had a little bit of time to play around with the code signing part. Everyone is probably already familiar with x64 driver signature enforcement (64-bit Windows systems can only load signed drivers); Well, now Microsoft has introduced a similar feature for user mode code, which is a huge deal when it comes to malware (Currently the feature is only present on Windows 10 Enterprise, but I’m fairly certain as it matures it will make it’s way to home systems).
Device Guard Code Integrity Policy
Device Guard not only adds customizable user mode code integrity checks (UMCI), but re-works a lot of the kernel mode code integrity (KMCI) allowing far more flexibility than just allowing all signed drivers. The policy can either be deployed locally by and administrator or from a domain controller, making it scalable for enterprise networks.
Something I was actually quite surprised by is the fact that the user mode code integrity is not simply limited to executable (I was expecting Device Guard to be just another throw away pseudo-security feature like UAC, but it’s clear some real thought has gone into this).
As already explained, Device Guard isn’t just a more flexible version of Kernel Mode Code Signing, it goes the whole nine yards with customizable code integrity policy for executables. Rather than using a flimsy software restriction policy, Device Guard can use an array of different settings to make sure only trusted executables are run.
|Executables violating the policy are simply blocked from running at all.
Dynamic Link Libraries
One of my favorite attacks against HIPS, firewalls, and software restriction policies is DLL hijacking. Simply put, when an application calls LoadLibrary(“somedll.dll”), the system first looks for the DLL in the KnowDlls registry key, followed by the applications working folder (where the application was run from), and finally system paths like System32. If you copied a legitimate system application to another folder, then placed an arbitrary DLL in the same folder and gave it the name of a DLL the application dynamically loads, it would load your DLL instead of the real one. Using this method you can bypass all kinds security checks by loading code inside a legitimate system application, without using code injection (which normally triggers HIPS).
Well, it seems Microsoft considered DLL hijacking this time around as all DLLs loaded by an application are checked against the code integrity policy; If a DLL violates the policy, the DLL and application will fail to load (the check is implemented in MiCreateSection, so should apply to any code loaded with NtCreateSection and SEC_IMAGE).
|Trying to hijack explorer.exe with an unsigned DLL results in STATUS_SYSTEM_INTEGRITY_POLICY_VIOLATION
Windows Script Hosts & PowerShell
Another long standing issue with antiviruses is malicious scripts; Engines like PowerShell have the ability to access the Win32 API, allowing malware to leverage scripts in order to bypass binary scanning and perform almost all malicious tasks without the need for an executable.
Device Guard introduces signing of of Windows Script Host scripts, as well as PowerShell to prevent malicious use. Unsigned PowerShell scripts are blocked and PowerShell itself is run in “constrained mode” which prevents it from executing arbitrary code via .NET scripting, COM interface, WinAPI, etc.
|PowerShell is in constrained mode and blocks unsigned script.s
Device Guard provides a multitude of mix & match ways to define which applications and drivers can be run (known as file rules), allowing administrators to fine tune policies to their needs.
Here’s a list of some file rule levels currently available:
- PCA Certificate – All files signed with a leaf certificate belong to the whitelisted PCA Certificate (Ex: Any file signed with a VeriSign Extended Validation certificate).
- Leaf Certificate – All files signed with a specific code signing certificate (the ones issued to vendors).
- Hash – Allow a single file by its SHA2 hash (Good for unsigned applications).
- FileName – Just…just don’t.
- Publisher – Like PCA, but with the ability to only allow applications from certain publishers (the “common name” of the leaf certificate Ex: Only leaf certificates issued to Microsoft).
- WHQL – Allow kernel drivers which are signed & verified by WHQL.
- WHQL Publisher – Same as Publisher but only for signed & verified WHQL drivers.
Also allowed is the ability to specify a minimum file version with most of the rules, which is great for stopping malware exploiting old signed drivers to gain kernel mode execution.
To start off, a policy can be created by scanning the current system and building a list of all all installed applications, then whitelisting them using whichever rule required (it’s also possibly to fall back to hashes or file names for unsigned files). By default policies are created with “Audit Mode” enabled, which means when the policy is installed, it won’t be enforced but will instead log all files which would have been blocked to the event log.
|Example of a CodeIntegrity event
A very handy feature is the ability to create a second policy using the event log, then merge it with a first. This would allow the administrator to set up a test system and build a list of files which would be blocked by the current policy, then review and whitelist them in a future policy.
Virtualization Based Protection of Code Integrity
This is where Device Guard really comes into its own: If the system is capable of Virtualization Based Security (VBS), Device Guard can be configured to use hypervisor technology in order to isolate parts of the kernel involved in security checks from the rest. With VBS enabled, even if malicious code does somehow manage to get into kernel mode, it would be unable to patch the code responsible for UMCI / KMCI, therefore incapable of installing any code to persist across reboot (or disable the code integrity policy altogether).
If properly implemented, Device Guard can be used to create a system which is highly resilient to common malware (assuming UMCI, KMCI, and VBPCI are enabled and well configured).
- UMCI prevents an adversary social engineering the victim into running malware (unless they can get hold of a whitelisted certificate).
- On Windows 10 Google Chrome & Internet Explorer run inside an isolated container known as AppContainer, so even if the browser was exploited, it’d be run in total isolation.
- If the code somehow escapes AppContainer, it’d need a method of persisting across reboot, bearing in mind the UMCI policy prevents unsigned code being added to start-up and it’s kind of hard to exploit applications during boot.
Although it’s still early days, Device Guard is definitely a huge leap in the right direction towards putting an end to malware. Though it’s likely going to take some time for such a feature to evolve from a complex set of configurations aimed at experienced network administrators, to an out-of-the-box security system for end users.