Detection rules › Kusto

LDAP reconnaissance via search filters

Author
FalconForce
Source
github.com/FalconForceTeam/FalconFriday

This query collects LDAP queries executed on systems monitored by Defender for Endpoint. The filter and distinguished name attributes of these queries are extracted and matched against a list of IOCs obtained from popular reconnaissance tools.

MITRE ATT&CK coverage

References

Event coverage

ProviderEvent/ActionTypeTitle
Defender-DeviceEventsLdapSearchLDAP search
LDAP-ClientEvent ID 30LDAP search request

Rule body kusto

let timeframe = 2*1h;
let suspect_search_filter=dynamic([
    "(&(&(objectCategory=person)(objectClass=user))(|(description=*pass*)(comment=*pass*)))", // Metasploit IOC [1].
    "(&(objectCategory=computer)(operatingSystem=*server*))", // Metasploit IOC [1].
    "(&(objectClass=group))", // Metasploit IOC [1].
    "(&(objectClass=group)(managedBy=*)),(&(objectClass=group)(managedBy=*)(groupType:1.2.840.113556.1.4.803:=2147483648))", // Metasploit IOC [1].
    "(&(sAMAccountType=805306369)(dnshostname=*))", // Powerview IOC [1].
    "(&(samAccountType=805306368)(samAccountName=*)", // Powerview IOC [1].
    "(&(samAccountType=805306368)(servicePrincipalName=*)", // Powerview IOC [1].
    "(&(objectClass=msDFS-Linkv2))", // Powerview IOC [1].
    "(&(objectCategory =organizationalUnit)(name=*))" // Powerview IOC [1].
//  "(samAccountType=805306368)" // Empire IOC [1] - disabled by default, since it is too generic.
    "objectClass=trustedDomain", // Recon IOC [2].
//  "objectClass=crossRef", // Recon IOC [2].
    "userAccountControl:1.2.840.113556.1.4.803:=524288", // Recon IOC [2].
    "userAccountControl:1.2.840.113556.1.4.803:=4194304", // AD Recon IOC [2].
    "anr=Remote Desktop Users", // AD Recon IOC [2].
    "defender-tokenData=*", // AD Recon IOC [2].
    "Domain Admins",  // AD Recon IOC, based on own research.
    "Enterprise Admins", // AD Recon IOC, based on own research.
    "CN=Administrators", //  AD Recon IOC, based on own research.
    "(schemaIDGUID=*)", // Sharphound IOC, based on own research.
//  "(objectclass=domain)", // Sharphound IOC, based on own research.
    "(&(objectclass=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))" // Sharphound IOC, based on own research.
    "(|(samAccountType=805306368)(samAccountType=805306369)(objectclass=organizationalUnit))", // Sharphound IOC, based on own research.
    "(samAccountType=805306368)(samAccountType=805306369)" // Sharphound IOC, based on own research.
]);
let suspect_dn=dynamic([
    "CN=DnsAdmins", // AD Recon IOC, based on own research.
    "CN=Domain Controllers", // Sharphound IOC, based on own research.
    "CN=DnsAdmins", // Sharphound IOC, based on own research.
    "CN=Read-only Domain Controllers", // Sharphound IOC, based on own research.
    "CN=Cloneable Domain Controllers" // Sharphound IOC, based on own research.
]);
DeviceEvents
| where ingestion_time() >= ago(timeframe)
| where ActionType =~ "LdapSearch"
// Begin environment-specific filter.
// End environment-specific filter.
| where not(InitiatingProcessFolderPath startswith @"c:\program files\azure advanced threat protection sensor\" and InitiatingProcessVersionInfoOriginalFileName == @"Microsoft.Tri.Sensor.exe")
| extend AdditionalFields=parse_json(AdditionalFields)
| extend SearchFilter=tostring(AdditionalFields.SearchFilter)
| extend DistinguishedName=tostring(AdditionalFields.DistinguishedName)
| extend AttributeList=tostring(AdditionalFields.AttributeList)
| where SearchFilter has_any(suspect_search_filter) or DistinguishedName has_any(suspect_dn)
| project-reorder DeviceName, InitiatingProcessFolderPath, SearchFilter, DistinguishedName, InitiatingProcessCommandLine
// Begin environment-specific filter.
// End environment-specific filter.
// FileProfile is case-sensitive and works on lower-case hashes.
| extend InitiatingProcessSHA1=tolower(InitiatingProcessSHA1)
| invoke FileProfile(InitiatingProcessSHA1, 1000)
| where not(Signer =~ "Microsoft Corporation" and IsCertificateValid == 1 and InitiatingProcessFileName =~ "microsoft.tri.sensor.exe")
| where not(Signer =~ "Microsoft Corporation" and IsCertificateValid == 1 and SoftwareName =~ "Endpoint Configuration Manager")
| where not(Signer =~ "Microsoft Corporation" and IsCertificateValid == 1 and SoftwareName contains "AD Connect")
| where not(Signer =~ "Microsoft Windows" and IsCertificateValid == 1 and InitiatingProcessFileName =~ "Microsoft.IdentityServer.ServiceHost.exe")
| where not(InitiatingProcessFolderPath =~ @"c:\windows\system32\lsass.exe")
// Begin environment-specific filter.
// End environment-specific filter.