CVE-2023-23397 - Microsoft Outlook Privilege Escalation / NTLM Relay Detection

April 1, 2026 ยท View on GitHub

Query Information

MITRE ATT&CK Technique(s)

Technique IDTitleLink
T1187Forced AuthenticationForced Authentication
T1078Valid AccountsValid Accounts

Description

Detection queries for CVE-2023-23397, a critical Microsoft Outlook vulnerability where a specially crafted email triggers NTLM authentication to an attacker-controlled server. Detects rundll32 loading davclnt.dll with external IP connections.

Risk

CVE-2023-23397 is a zero-click vulnerability exploited by Russian APT28 (Fancy Bear) in attacks against European targets. It allows NTLM credential theft with no user interaction required.

Author

References

Defender For Endpoint

SecurityEvent | where EventID == 4688 | where (ParentProcessName endswith @'\svchost.exe' and NewProcessName endswith @'\rundll32.exe' and CommandLine contains @'C:\windows\system32\davclnt.dll,DavSetCookie' and CommandLine matches regex @'(?i)://\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}') and not (CommandLine has_any (@'://10.',@'://192.168.',@'://172.16.',@'://172.17.',@'://172.18.',@'://172.19.',@'://172.20.',@'://172.21.',@'://172.22.',@'://172.23.',@'://172.24.',@'://172.25.',@'://172.26.',@'://172.27.',@'://172.28.',@'://172.29.',@'://172.30.',@'://172.31.',@'://127.',@'://169.254.'))
//pseudocode
SecurityEvent
| where ((Process contains ("rundll32.exe") and CommandLine contains("davclnt.dll"))
| where not ((ParentProcessName contains ("cmd.exe"))
| project TimeGenerated, Computer, tostring(EventID), ParentProcessName, NewProcessName, CommandLine, SubjectUserName, SourceComputerId, processID=tolong(NewProcessId), parentProcessID=tolong(ProcessId), EventData 
| order by TimeGenerated
DeviceProcessEvents | where (InitiatingProcessFolderPath endswith @'\svchost.exe' and FolderPath endswith @'\rundll32.exe' and ProcessCommandLine contains @'C:\windows\system32\davclnt.dll,DavSetCookie' and ProcessCommandLine matches regex @'(?i)://\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}') and not (ProcessCommandLine has_any (@'://10.',@'://192.168.',@'://172.16.',@'://172.17.',@'://172.18.',@'://172.19.',@'://172.20.',@'://172.21.',@'://172.22.',@'://172.23.',@'://172.24.',@'://172.25.',@'://172.26.',@'://172.27.',@'://172.28.',@'://172.29.',@'://172.30.',@'://172.31.',@'://127.',@'://169.254.'))
//playing with these at present
DeviceNetworkEvents
| extend f = extract(@'(?i)://(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})',1,InitiatingProcessCommandLine)
| where InitiatingProcessFileName =~ "rundll32.exe" and ipv4_is_private(RemoteIP) == false and isnotempty(f) //and not (RemoteIP has_any ("127.","169.254."))
| project TimeGenerated, ActionType, DeviceName, InitiatingProcessFileName, InitiatingProcessFolderPath, InitiatingProcessCommandLine, InitiatingProcessId, InitiatingProcessMD5, InitiatingProcessParentFileName, InitiatingProcessParentId, LocalIP, LocalPort, RemoteIP, RemotePort, RemoteUrl
//playing with these at present
DeviceNetworkEvents
| extend f = extract(@'(?i)://(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})',1,InitiatingProcessCommandLine)
| where InitiatingProcessFileName =~ "rundll32.exe" and ipv4_is_private(RemoteIP) == false and isnotempty(f) and not (RemoteIP has_any ("127.","169.254."))
| project TimeGenerated, ActionType, DeviceName, InitiatingProcessFileName, InitiatingProcessFolderPath, InitiatingProcessCommandLine, InitiatingProcessId, InitiatingProcessMD5, InitiatingProcessParentFileName, InitiatingProcessParentId, LocalIP, LocalPort, RemoteIP, RemotePort, RemoteUrl
DeviceTvmSoftwareVulnerabilities
| where CveId =~ "CVE-2023-23397"
| distinct DeviceName
//Identify outbound SMB connections to public IPs
DeviceNetworkEvents
| where RemotePort == 445 and ipv4_is_private(RemoteIP) == false and RemoteIP !~ "127.0.0.1" and RemoteIP !startswith "169.254."

Sentinel

SecurityEvent | where EventID == 4688 | where (ParentProcessName endswith @'\svchost.exe' and NewProcessName endswith @'\rundll32.exe' and CommandLine contains @'C:\windows\system32\davclnt.dll,DavSetCookie' and CommandLine matches regex @'(?i)://\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}') and not (CommandLine has_any (@'://10.',@'://192.168.',@'://172.16.',@'://172.17.',@'://172.18.',@'://172.19.',@'://172.20.',@'://172.21.',@'://172.22.',@'://172.23.',@'://172.24.',@'://172.25.',@'://172.26.',@'://172.27.',@'://172.28.',@'://172.29.',@'://172.30.',@'://172.31.',@'://127.',@'://169.254.'))
//pseudocode
SecurityEvent
| where ((Process contains ("rundll32.exe") and CommandLine contains("davclnt.dll"))
| where not ((ParentProcessName contains ("cmd.exe"))
| project TimeGenerated, Computer, tostring(EventID), ParentProcessName, NewProcessName, CommandLine, SubjectUserName, SourceComputerId, processID=tolong(NewProcessId), parentProcessID=tolong(ProcessId), EventData 
| order by TimeGenerated
DeviceProcessEvents | where (InitiatingProcessFolderPath endswith @'\svchost.exe' and FolderPath endswith @'\rundll32.exe' and ProcessCommandLine contains @'C:\windows\system32\davclnt.dll,DavSetCookie' and ProcessCommandLine matches regex @'(?i)://\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}') and not (ProcessCommandLine has_any (@'://10.',@'://192.168.',@'://172.16.',@'://172.17.',@'://172.18.',@'://172.19.',@'://172.20.',@'://172.21.',@'://172.22.',@'://172.23.',@'://172.24.',@'://172.25.',@'://172.26.',@'://172.27.',@'://172.28.',@'://172.29.',@'://172.30.',@'://172.31.',@'://127.',@'://169.254.'))
//playing with these at present
DeviceNetworkEvents
| extend f = extract(@'(?i)://(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})',1,InitiatingProcessCommandLine)
| where InitiatingProcessFileName =~ "rundll32.exe" and ipv4_is_private(RemoteIP) == false and isnotempty(f) //and not (RemoteIP has_any ("127.","169.254."))
| project TimeGenerated, ActionType, DeviceName, InitiatingProcessFileName, InitiatingProcessFolderPath, InitiatingProcessCommandLine, InitiatingProcessId, InitiatingProcessMD5, InitiatingProcessParentFileName, InitiatingProcessParentId, LocalIP, LocalPort, RemoteIP, RemotePort, RemoteUrl
//playing with these at present
DeviceNetworkEvents
| extend f = extract(@'(?i)://(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})',1,InitiatingProcessCommandLine)
| where InitiatingProcessFileName =~ "rundll32.exe" and ipv4_is_private(RemoteIP) == false and isnotempty(f) and not (RemoteIP has_any ("127.","169.254."))
| project TimeGenerated, ActionType, DeviceName, InitiatingProcessFileName, InitiatingProcessFolderPath, InitiatingProcessCommandLine, InitiatingProcessId, InitiatingProcessMD5, InitiatingProcessParentFileName, InitiatingProcessParentId, LocalIP, LocalPort, RemoteIP, RemotePort, RemoteUrl
DeviceTvmSoftwareVulnerabilities
| where CveId =~ "CVE-2023-23397"
| distinct DeviceName
//Identify outbound SMB connections to public IPs
DeviceNetworkEvents
| where RemotePort == 445 and ipv4_is_private(RemoteIP) == false and RemoteIP !~ "127.0.0.1" and RemoteIP !startswith "169.254."