0% found this document useful (0 votes)
2 views

Bypass AM PPL

The document discusses advanced techniques for bypassing Antimalware Protected Process Light (AM-PPL) and disabling Endpoint Detection and Response (EDR) systems, focusing on the evolution of endpoint security and various EDR/AV bypass methods. It covers the architecture of EDRs, including userland hooking and direct system calls access, as well as specific tools and techniques like SysWhispers and D/Invoke for evasion. The authors, members of the Avast Red Team, provide insights into the implications of these techniques for security professionals and suggest defensive measures.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Bypass AM PPL

The document discusses advanced techniques for bypassing Antimalware Protected Process Light (AM-PPL) and disabling Endpoint Detection and Response (EDR) systems, focusing on the evolution of endpoint security and various EDR/AV bypass methods. It covers the architecture of EDRs, including userland hooking and direct system calls access, as well as specific tools and techniques like SysWhispers and D/Invoke for evasion. The authors, members of the Avast Red Team, provide insights into the implications of these techniques for security professionals and suggest defensive measures.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 46

Nullcon Berlin

2022
How to bypass AM-PPL (Antimalware Protected Process
Light) and disable EDRs - a Red Teamer's story

Juan Sacco
Stephen Kho
Avast Confidential
Agenda
1. Who we are?
2. Endpoint security evolution (so far)
3. How EDR/AVs work?
4. 2022 EDR/AV bypass techniques
5. AM-PPL bypass research
6. Bypassing AM-PPL
7. Chain of attack and timeline
8. What can you do about it?
9. Q&A

Avast Confidential
Who we are
• $ whoami : Stephen Kho <[email protected]> – Team Lead Avast Red Team
• $ whoami : Juan Sacco <[email protected]> – Co Team Lead Avast Red Team

Avast Red Team - Offensive security team for defensive purposes


• Red Teaming Scope:
• Pentesting • Internal / external network infrastructure
• Purple Teaming • Avast products and applications
• Research • 3rd party products and applications
$il> – Team Lead Avast Red Team n

Avast Confidential
Endpoint security evolution (so far)
Heuristic AV EDR (Endpoint Detection and Response)
• 1987 McAfee, Inc. released VirusScan • 2013 Term coined by Anton Chuvakin from Gartner
• First heuristic AV released - FlushShot Plus and Anti4us • Real-time continuous monitoring and collection of endpoint data
• 1988 Avira release AntiVir (Luke Filewalker) • Machine learning and behavior analysis to evaluate system
• 1988 Avast was founded and released Avast Antivirus and events and identify anomalies
SecureLine VPN ○ VMware Carbon Black
○ Crowdstrike Falcon
○ Microsoft Defender for Endpoint

1971 1980s 1990-2000s 2010s 2020s

Signature based AV AV + Cloud (Behavioural analysis) XDR (Extended Detection


• 1971 Reaper was written to remove • 1991 Dr. Solomon’s Anti-Virus Toolkit and Norton and Response)
Creeper virus which infected DEC PDP-11 AntiVirus • Alert Integration, Normalization,
• 1987 German computer security expert • 1992 AVG AVG AntiVirus released Correlation (SIEM-like)
Bernd Fix created program to get rid of • 1996 Bitdefender, Kaspersky Anti-Virus • Automated Investigation and
Vienna, a virus that infected .com files on • 2005 F-Secure developed an anti-rootkit tool BlackLight Remediation (SOAR-like)
DOS-based systems • 2008 McAfee Artemis, cloud-based anti-malware
● Trend Micro Vision One
● Palo Alto Networks Cortex
• 2011 AVG Protective Cloud Technology.
● Cynet 360
How EDR/AVs work? – Architecture overview in 60 sec
• MS DOS (1980)
• Programs directly accessed device drivers / hardware

• No security separation and can easily lead to system instability


• Windows
• Windows 1-3.x (1985) - protected mode kernel that could multitask several
DOS applications but apps still ran in a shared virtual DOS machine.

• Windows NT 3.1 (1993) first to feature user mode and kernel mode

• User mode applications processes runs with a private virtual address


space and a private handle table - one application cannot alter data that
belongs to another application and if an application crashes, the crash is
limited to that one application.

• The kernel provides the foundation for the executive and the subsystems.
All code that runs in kernel mode shares a single virtual address space but
only drivers that have been sent to Microsoft for signing will load into the
Windows kernel.
• Less BSODs! Avast Confidential
• Userland
• processthreadsapi.h
1. Call function in NTDLL • Win32 API
CreateRemoteThread

How EDR/AVs work? – Windows API


2. Make syscall
• Userland
• The Windows API (Application Programming Interface) - • NTDLL.dll
NtCreateThreadEx
access and manipulate system resources • Unexported

• User applications (User Mode) access system resources


(Kernel Mode) via the mapped functions in NTDLL.DLL
• SYSCALL instructions are OS operations such as file IO,
and networking • Kernel mode
SYSCALL instruction
• Example:
• Logged in user executes cmd.exe
• CreateRemoteThread function does sanity checks
and then calls
• NtCreateThreadEx function in NTDLL.dll
• Setup required registers with params to then
make the SYSCALL instruction
• Once complete, returns to Userland Avast Confidential
How EDR/AVs work? – Windows API hooking/Userland hooking

● Technique used by EDRs and other programs such as anti-cheat


engines to redirect the flow of program execution when a certain
function is called
● An EDR will hook by loading a library into all newly created
processes
● Windows API functions that are commonly hooked are functions
related to process and thread creation and manipulation, memory
mapping, etc.
● Common functions include NtCreateThreadEx,
NtMapViewOfSection, NtAllocateVirtualMemory.
● Most common hooking techniques involves replacing the first
instruction of the unexported function in the system DLL with a
JMP instruction that jumps to a routine in the EDR’s loaded
library.

Avast Confidential
How EDR/AVs work? – Windows API hooking/Userland hooking

2. JMP instruction to EDR 4. Make syscall if no EDR


code detection

SYSCALL
NtCreateThreadEx functions
• Userland
• Userland
• NTDLL.dll • Check • Kernel
• processthreadsapi.h
parameters mode

CreateRemote EDR/AV
Thread functions

1. Call function in NTDLL 3. Return to call or EDR


detection made

Avast Confidential
2022 EDR/AV bypass techniques

Why? Some techniques being used out there


• Evade EDR/AV detection • Direct system calls access
• Red Teaming exercises • Unhooking the hookers
○ Test Blue Team overall detect • Direct Entrypoint patching
& response capabilities
○ Attack chain • .NET Core evasion techniques

• Test EDR/AV products • Patching the patch

• Purple Teaming • SysWhispers


• Signature detection & Sandboxing
• Active protection & Event tracing
• Userland hooking
• P/Invoke & D/Invoke
2022 EDR/AV bypass techniques

Why? Some techniques being used out there


• Evade EDR/AV detection • Direct system calls access
• Red Teaming exercises • Unhooking the hookers
○ Test Blue Team overall detect • Direct Entrypoint patching
& response capabilities
○ Attack chain • .NET Core evasion techniques

• Test EDR/AV products • Patching the patch

• Purple Teaming • SysWhispers


• Signature detection & Sandboxing
• Active protection & Event tracing
• Userland hooking
• P/Invoke & D/Invoke Avast Confidential
2022 EDR/AV bypass techniques

Direct system calls access


The main goal of this technique is to bypass Userland-Hooking by not loading any function
from ntdll.dll during runtime. But instead calling directly the corresponding assembler code (
obtained previously from a dissasembly of the ntdll.dll ) in-line from your program itself.

SysWhispers ( Direct Access but Next-Gen ):


In a nutshell, it helps with evasion by generating custom headers/ASM file implants to make
the usage of direct system calls easier. So, with a tool, not more manual disassembly. And
yes, works on Visual Studio ;-)

Avast Confidential
First line of defense: Signature detection

It’s the process of analyzing the signatures of files for known malware
previously identified. Tipically implemented at kernel level using file system
filters. Files get scanned at opening phase, and if a signature is triggered the
filter driver blocks the access.

But as you may know.. in most cases a partial


recompilation may suffice.

Second line of defense: Sandboxing

Prior to allow an executable from running a potentially malicious program will


get executed inside a virtual machine, and no, it’s not a vmware/virtualbox but
a sandbox designated to analyse program flow, tipically doing CFG of all paths
of the program.
Sanboxing and the hot-potato:

While most of the sandboxes uses CFG analysis, meaning the recompilation of
binaries or other small changes will still produce the same CFG regardless of
the executable having a partial or complete different signature.

Computing power have a cost. Analysing samples will produce an overhead of


resources if not measured correctly, and this finite amount of time assigned to
each sample means that.. It can be abused. How? When there is enough
complexity in the program being virtualized inside the Sandbox, eventually it
will give up if it hasn’t during the CFG found the binary to be malicious. And
quickly it will jump into the next sample.

Breaking up the analysis!


A commonly used method to skip the Sandbox
is to break the control flow to prevent further
analysis of the sample. The Sandbox is essentially
a VM, but specific OS API calls cannot really be
virtualized. When this occur the sandbox cannot
carry on the analysis and tipically gives up.
Active protection:

Typically an EDR/AV will become part of the execution, generally


implemented by forcing a DLL into the process and doing API function hooks
to analyse during runtime the process against potentiall suspicious behavior.

Windows Event Tracing:


In a nutshell, parsing: Sysmon. When all other measures fail event tracing will
be the last resource to fallback into. This will cover event behavioral analysis
and custom rules set by the administrators that will ended-up triggering alerts
if a detection of the user-behavior or executable actions matches one of the
said rules or events.
Windows architecture.
Win32API consists of several DLLs located in system32, for example
kernel32.dll and User32.dll.

User applications: User-Mode


Drivers and Kernel: Kernel-Mode

All of these are mapped into


functions from the native API.
NDTLL.DLL

API -> Function -> NTDLL


Userland hooking
NTDLL.dll functions are the last intance that can be monitored by EDR/AVs,
and these tipically inject custom DLLs into every new process.

As shown below “aswhook.dll” coming from the AV, will be most likely
monitoring Windows API Calls. If a program loads a function from
kernel32.dll a copy of this dll is placed into memory. Then the AV can
manipulate the in memory copy at will, hooking into it, using a trampolin
function to control the flow of the hooked API native call. This technique is
called Userland-Hooking.
Patching the patch
When the in-memory copy of Kernel32.dll or NTDLL.dll is loaded into memory
tipically EDR/AVs will patch some of the functions using trampolin hooks placing
a JMP or similar at the beginning of the code to redirect the Windows API
function to some inspecting code controlled by the EDR/AV itself.

If the analysis outcome is positive (or bad in our case) the execution continues, if
not the execution is flagged and the API call gets blocked.

Unhooking
To be able to unhook, or restore the hooked functions we need to know how it
looked like before it got modified. This can be achieved by comparing the
function definitions in the DLL on the disk with their definitions on memory.
Direct system calls access:
The main goal of this technique is to bypass Userland-Hooking by not loading
any function from ntdll.dll during runtime. But instead calling directly the
corresponding assembler code ( obtained previously from a dissasembly of
the ntdll.dll ) in-line from your program itself.

As for example: WriteVirtualMemory

ZwWriteVirtualMemory80 proc
mov r10, rcx
mov eax, 38h
syscall
ret
ZwWriteVirtualMemory80 endp

NtWriteVirtualMemory ( undocumented ) is similar to WINAPI WriteProcessMemory. Writes data to an area of memory in a


specified process. The entire area to be written to must be accessible or the operation fails.

Using this technique will bypass Userland-Hooking and the EDR/Avs will not
see any Windows API function at all. No imports and no patches or hooks.
SysWhispers ( Direct Access but Next-Gen ):
In a nutshell, it helps with evasion by generating custom headers/ASM file
implants to make the usage of direct system calls easier. So, with a tool, not
more manual disassembly. And yes, works on Visual Studio ;-)
P/Invoke & D/Invoke
Platform Invoke allows .NET applications to access data and APIs in
unmanaged DLLS. By using P/Invoke you may make calls to the standard
Windows APIs allowing a malicious program to perform post-exploitation
on-memory without droping files to disk. In a nutshell you can access structs,
callbacks and functions in unmanaged libraries from your managed code.

But all references get an entry in the .NET assembly Import Table. This static
reference, from the perspective of your program, will get you caught. Tipically
EDR/Avs will inspect the IAT of the running programs to learn about their
behavior. And so is born.. D/Invoke

In a nutshell, if we first learn the offset and call directly the function we can
make those references at runtime using a pointer to its location.
// NtWriteVirtualMemory
stub = Generic.GetSyscallStub("NtWriteVirtualMemory");
NtWriteVirtualMemory ntWriteVirtualMemory = (NtWriteVirtualMemory)
Marshal.GetDelegateForFunctionPointer(stub, typeof(NtWriteVirtualMemory));

var buffer = Marshal.AllocHGlobal(_shellcode.Length);


Marshal.Copy(_shellcode, 0, buffer, _shellcode.Length);

uint bytesWritten = 0;

result = ntWriteVirtualMemory(
hProcess,
baseAddress,
buffer,
(uint)_shellcode.Length,
ref bytesWritten);
Unhooking the Hookers
It’s possible to completly unhook a hooked DLL loaded in memory by reading
the .text section and overwriting the .text section mapped into memory.

Mapping a copy of, on this example, NTDLL.DLL from disk into memory, then
get the NTDLL.DLL base address, find the offset to the .text section Vadress.

Then simply copy the .text section into the hooked DLL and apply the original
memory protections set to NTDLL by the EDR/AV.
Direct Entry Point Patching
Using Windows Debug API to listen for LOAD_DLL_DEBUG_EVENTS it’s
possible to patch the EntryPoint of the injected DLL attempt and return only
TRUE instead of actually attaching the DLL into the process, avoiding
User-Land Hooks all together.

BEFORE

AFTER
What is PPL?
The Protected Process Light (PPL) is a technology that has been
implemented since Windows 8.1>, and it’s used to protect specific
critical processes. These processes should have an internal or external
signature to meet the Windows requirements.

The following actions are available to PPL processes ( depending on


access levels ) and restricted from others.

● Process termination
● Access to virtual memory
● Debugging
● Copying of descriptors
● Access to memory
● Thread interaction
● Token impersonation
ACCESS DENIED. Trying to interact with an
unprotected process even as NT/System.
PPL Processes - The basics
PPL effectively prevents an unprotected process from accessing
protected processes with extended access rights.

What we cannot do.


● PPL prevents memory write/read access
● PPL prevents unsigned DLLs loading!
● PPL prevents token impersonation
● PPL prevents access from non-protected processes

What are the access like from other PP/PPL process?


● A PP process can open a PP or a PPL with full access if its signer
type is greater or equal.
● A PPL can open a PPL with full access if its signer type is greater
or equal.
● A PPL cannot open a PP with full access, regardless of its signer
type.
Source: https://docs.microsoft.com/en-us/windows/win32/procthread/zwqueryinformationprocess
Access levels of PP/PPL processes
The highest PPL access level is WINTCB-L
The exploit.

In 2018, James Forshaw from Project Zero discovered a vulnerability that


originally intended for privilege escalation, could also be abused to inject
arbitrary code into a PPL process as an administrator.

“Object Manager directories are unrelated to normal file directories. The directories are created
and manipulated using a separate set of system calls such as NtCreateDirectoryObject rather
than NtCreateFile. Even though they’re not file directories they’re vulnerable to many of the
same classes of issues as you’d find on a file system including privileged creation and symbolic
link planting attacks.”

Source: https://googleprojectzero.blogspot.com/2018/08/windows-exploitation-tricks-exploiting.html
Proof of concept: https://bugs.chromium.org/p/project-zero/issues/detail?id=1550#c5
How the exploit works:
DLLs are only verified when the file is mapped. When a Section is created. This means that, if
you are able to add an arbitrary entry to the \KnownDlls directory, you can then inject an
arbitrary DLL and execute unsigned code into a PPL protected process.

Restriction: Only protected processes that have a level higher than or equal to WinTcb can
request write access to this directory.

Call DefineDosDevice with the value

We needed to use GLOBALROOT\KnownDlls\FOO.dll as the device name. The target path of this
device is the location of the DLL. The service creates the symbolic link \KnownDlls\FOO.dll with a
target path we control.
The target must be a Section Object, rather than the DLL file path
Phantom DLL hollowing:
Once we have the symbolic link pointing to our DLL from the KnownDLL
objects, if a program loads a DLL named FOO.dll and the Section object
\KnownDlls\FOO.dll exists, then the loader will use this image rather than
mapping the file again.

An implementation of a DLL hollowing attack implies an injection of a mapped


view generated from a real DLL file on disk. Such DLL files should have a .text
section with a IMAGE_SECTION_HEADER.Misc.VirtualSize greater than or equal
to the size of the shellcode being implanted, and should not yet be loaded into
the target process as this implies their modification could result in a crash.

The essence of phantom DLL hollowing is that an attacker can open a TxF
handle to a Microsoft signed DLL file on disk, infect its .text section with his
shellcode, and then generate a phantom section from this malware-implanted
image and map a view of it to the address space of a process of his choice.
The file object underlying the mapping will still point back to the legitimate
Microsoft signed DLL on disk (which has not changed) however the view in
memory will contain his shellcode hidden in its .text section with +RX
permissions.
Source: https://www.forrest-orr.net/post/malicious-memory-artifacts-part-i-dll-hollowing
Exploit #2 .NETProfiler
We have “debug” and “impersonate” privileges, so we can list the current processes, find one
that runs as LOCAL SERVICE, duplicate the primary token and temporarily impersonate this
user. But we needed Administrator rights to begin with.

.NET can be coerced into loading a profiling DLL into any .NET assembly when launched. This is
done when a handful of environment variables and registry keys are set.

COR_ENABLE_PROFILING=1
COR_PROFILER={GUID}
COR_PROFILER_PATH=C:\path\to\some.dll

And in order to make it work you can hook your custom DLL:
REG ADD "HKCU\Software\Classes\CLSID\{FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF}\InprocServer32" /ve /t REG_EXPAND_SZ
/d "C:\Temp\test.dll" /f
REG ADD "HKCU\Environment" /v "COR_PROFILER" /t REG_SZ /d "{FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF}" /f
REG ADD "HKCU\Environment" /v "COR_ENABLE_PROFILING" /t REG_SZ /d "1" /f
REG ADD "HKCU\Environment" /v "COR_PROFILER_PATH" /t REG_SZ /d "C:\Temp\test.dll" /f

COR_PROFILER can be used to also get persistence


since it loads a DLL in the context of all .NET processes
every time the CLR is invoked.

Task scheduler -> DLL Injected using the Profiller


Exploit #3 ( Optional ) Abusing .NET Core – Garbage Collector
The .NET's GC, like for any GC from other programming languages, is
responsible for the allocation and release of the memory used by an
application during runtime. .NET Core allows the use of custom GC via the
COMPlus_GCName environment variable. A custom GC takes the form of an
unmanaged C++ Dynamic-Link Library (DLL.
Escalate to NT/System
● Locate winlogon.exe process using CreateToolhelp32Snapshot, Process32First, and
Process32Next
● SeDebugPrivilege enabled for the current process via a call to AdjustTokenPrivileges,
● The handle of winlogon.exe token is retrieved by OpenProcessToken
● Winlogon.exe ( NT/System) is impersonated by calling ImpersonateLoggedOnUser
● The impersonated token handle is duplicated by calling DuplicateTokenEx with
SecurityImpersonation, this creates a duplicated token.
● Using the duplicated, and impersonated token we can spawn services.exe calling
CreateProcessWithTokenW

.NET Profiler
Tsk Scheduler

Execution
.NET Profiler
Tsk Scheduler
Start execution to get System

Shamelessly copied this graph from: https://github.com/FULLSHADE/Auto-Elevate


Syscall Whispers2 for evasion
Syscall whispers helps with evasion by generating headers/ASM files that could be used
to make direct system calls, thus for avoiding previously AV hooked API’s.
Timeline of the attack process
The attack: Step #1 Defender makes use of mainly three components:
● MsMpEng.exe the main engine, running as System and protected
with Antimalware Light ( PPL )
● NisSrv.exe the network inspection service, running as Local Service
and protected with Antimalware Light ( PPL )
● MpCmdRun.exe the graphical interface running as current user.
The attack: Step #2
Escalate using Task scheduler using .NetProfiler
The attack: Step #3 After obtaining admin we need to escalate to system, run the
exploit to inject a DLL into a new instance of a PPL process of
services.exe, prior to that check that everything is clean forcing
a scan from Windows Defender. Then we execute.
The attack: Step #4 From this point
The attack: Step #5 Running the KillAV command remotely from Exploit Pack.
The attack: Step #6 On this step, to keep the AV components down we overwrite one
of the DLLs that are going to be mapped from disk, MpSvc.dll with
an exit(0), thus the Engine or Nis cannot respawn;

No one, sorry ! :-(


The attack: Final Step #7 At this final stage we have a reverse shell from a DLL injected into
a PPL (WintTcb-Light ) process ( services.exe ).

This process cannot be terminated, the virtual memory cannot be


accessed and/or debugged from any other process with a lower PPL.

Target machine
Microsoft Servicing Criteria for MS Windows
The criteria used by Microsoft when evaluating whether to provide a security update or guidance for a
reported vulnerability. Even a non-admin to PPL bypass is not a serviceable issue.

Source: https://www.microsoft.com/en-us/msrc/windows-security-servicing-criteria?rtc=1
Credits & PoC ( Github ):
Download the PoC: https://github.com/jsacco/PPL_Bypass/tree/main

To all the work and research done by James Forshaw from Project Zero:
https://googleprojectzero.blogspot.com/2018/08/windows-exploitation-tricks-exploiting.html

For the DLL Phantom Hollowing technique from Forrest Orr


https://www.forrest-orr.net/post/malicious-memory-artifacts-part-i-dll-hollowing

For the amazing work on Syscall Whispers Jackson T. https://github.com/jthuraisamy/SysWhispers

For making publicly available an implementation of NT/System token impersonation, thanks! FULLSHADE
https://github.com/FULLSHADE/Auto-Elevate

For an incredible implementation and the PPLDump PoC itm4n !


https://github.com/itm4n/PPLdump

To all those anonymous people from StackOverflow answers!


and Microsoft for not fixing this !

Thanks to:
Avast Red Team for the technical feedback !
$ questions /? > /dev/null 2>&1

You might also like