DEF CON 31 – New Novel WFP filter attack for privilege escalation
I recently returned from the DEF CON 2023 conference in Las Vegas and amongst many of the briefings that I attended the talk by Ron Ben Yizhak was particularly interesting. His talk was called “#NoFilter - Abusing Windows Filtering Platform for Privilege Escalation”.
Whilst privilege escalation attacks are fairly common against the Windows platform this particular technique showcased an evasive and previously undetected privileged escalation technique that abuses the Windows Filtering Platform (WFP).
WFP and Attack technique overview
The WFP is a native platform in Windows that has its own API. Amongst over things it provides the ability to block or allow network traffic at any layer in the system based on several fields. It allows for the development of security products such as network monitoring tools, IDS and host firewalls.
During the course of researching the WFP, 3 attack methods were looked at:
Attack #1 - Duplicating tokens via WFP
The handle table of another process can be retrieved by calling NtQueryInformationProcess. This table lists the tokens held by the process. The handles to those tokens can be duplicated for another process to escalate to SYSTEM.
This technique can be modified to perform the duplication in the kernel instead of calling DuplicateHandle from user mode.
Device IO request is sent to call WfpAleProcessTokenReference. It will attach to the address space of the service, duplicate the token of the service that belongs to SYSTEM, and will store it in the hash table.
The LUID of the new token will be returned to the caller, and then WfpAleQueryTokenById will be called with the LUID. Handle to a SYSTEM token will be returned to the caller. The access of the handle is hard coded to be TOKEN_DUPLICATE, but it can be duplicated to gain TOKEN_ALL_ACCESS permissions.
This method was compared against the techniques from the overview. The token of several services can be duplicated only by using this method, such as LSM, Winmgmt, Schedule, and more.
Furthermore, the action of duplicating a handle to a SYSTEM token from a service into a process running with lower permissions is suspicious and might be detected, even by underperforming EDR solutions. This technique will evade this detection by avoiding the call to DuplicateHandle.
Additional cross-references to the token insertion function reveal relation to IPSec. Maybe using IPSec will insert a token?
IPSEC
Internet Protocol security is a set of protocols that ensure communication over the network is done securely and privately by using cryptographic security services. Integrating it at the Internet layer provides security for almost all TCP/IP protocols. The authentication and encryption process protects against attacks like network sniffers, data modification, identity spoofing, and denial of service.
IPSec sets up a secure connection between two machines before exchanging data. This is done with the Internet Key Exchange (IKE) service. It exchanges secret keys and other protection-related parameters. Authentication can be done with Kerberos V5, certificates, or a pre-shared key.
Another authentication protocol, AuthIP, can be used instead of IKE. It is a newer protocol that expands IKE with more authentication options. An IPSec policy can be configured through the Microsoft Management Console (MMC) snap-in, or by using the WFP API. The APIs give the developers the ability to set a more specific network traffic filtering model.
Microsoft provides an example for programmatically configuring an IPSec policy on the machine that uses a pre-shared key for authentication. While the policy is installed, the token of each process that creates a connection that matches the policy is inserted into the hash table stored in tcpip.sys.
According to the IPSec documentation, the reason this is done is because IPsec impersonates the security context under which the socket is created.
The LUID of the token is unknown to the attacker. This value is used for the modifiedId parameter for FwpsOpenToken0 and later as the index into the hash table. This value ranges between 1 and 0x1000, so it can be brute forced.
Attack #2 - Trigger IPSec Connection
Forcing a service to initiate a connection that matches the policy will result in inserting a SYSTEM token into the table. In this case, the Print Spooler service will be abused to achieve this. It has a documented IDL file, which makes it easier to find RPC methods that will make the service connect to a socket.
One such function is RpcOpenPrinter, which retrieves a handle for a printer by name. When setting the name to "\\127.0.0.1" the service will connect to the localhost. After this RPC call, multiple device IO requests to WfpAleQueryTokenById can be made until it returns a SYSTEM token.
This is a stealthier technique than the previous one. Configuring an IPSec policy is a legitimate action that can be done by network admins or to secure a connection to a server. Also, the policy doesn’t alter the communication; no service should be affected by it and EDR solutions monitoring network activity will most likely ignore connections to the local host. Another advantage is that there is no need to call WfpAleProcessTokenReference since the driver automatically adds the token to the hash table.
Can more services be manipulated to gain other tokens?
Attack #3 - Manipulate User Service
Gaining the token of another user logged on to the machine can lead to lateral movement in the domain. If the token can be added to the hash table a process can be launched with this user's permissions.
RPC servers running as logged-on users (and not as “NT ATHORITY\SYSTEM”) were searched for. The following script looks for processes running as the domain admin then checking if they expose an RPC interface. This led to SyncController.dll.
Once multiple sessions are active on the machine, every session will launch the OneSyncSvc service with the user's permissions. This service loads SyncController.dll, which registers the RPC interface 923c9623-db7f-4b34-9e6d-e86580f8ca2a.
This interface has a method called AccountsMgmtRpcDiscoverExchangeServerAuthType that receives a string in the following format: [email protected].
The steps to abuse this service include the following:
- Configure an IPSec policy for connections to the localhost with pre-shared key.
- Enum services and find the pid of OneSyncSvc running in the target session.
- Find the handle to the ALPC port. Since the interface of SyncController is exposed by several services, the RPC connection cannot be based on this interface; rather the unique ALPC port opened by the targeted service needs to be found.
- Create a listener thread for 127.0.0.1:443. Normally, there is no service listening on this port so another thread will be launched to listen to this address.
- Call the RPC method. It will cause the service to connect to the local host with port 443. While the connection is active, the token of the user from the other session is stored inside the table.
- Bruteforce the LUID of the new token while OneSyncSvc is connected to the socket.
- Launch process with the new token.
OneSyncSvc and SyncController.dll were never abused by an offensive tool, and the RPC call should not trigger security solutions.
Detection
These attacks were developed to be as stealthy as possible, but they can still be detected by looking for the following events on the machine:
- Configuring new IPSec policies that don’t match the known network configuration.
- RPC calls to Spooler / OneSyncSvc while an IPSec policy is active.
- Brute force the LUID of a token via multiple calls to WfpAleQueryTokenById.
- Device IO request to the device WfpAle by processes other than the BFE service.
The Windows Filtering Platform generates logs for events. Most logs are about packets drops or failures during the key exchange process. It is possible to generate logs about packets that were allowed to be sent. This must be set explicitly — and it is not recommended — as it will generate a lot of noise. Even when generating those logs it will be difficult to detect the attacks. The following log is about a connection made during the attack:
This log shows that the spooler service was allowed to connect to port 135 on the localhost. There is no mention of an IPSec policy or an RPC method that invoked this connection.
Conclusion
At the end of talk Ben Ron Yizhak made mention of the fact that although he reported his research to Microsoft but their response was that the behaviour he had uncovered was by design and did not recognise it as a security flaw!
- A single RPC call was reverse-engineered to achieve lateral movement and privilege escalation.
- Various components of the Windows Filtering Platform were analyzed.
- Security mechanisms protecting the platform were bypassed.
- Leads were shared to further abuse this platform.
Several attacks were developed, and their advantages include the following:
- Avoided the use of WinAPI which is typically monitored by security products.
- Execute programs as SYSTEM and other logged on users (most tools only elevate to SYSTEM)
- Stealthier than ever before — barely any evidence and log entries
- Undetected by several security products
His research can be found at this GitHub Repo.
His original blogpost is here at DeepInstinct.