Detections/MultipleDataSources/MalformedUserAgents.yaml (109 lines of code) (raw):

id: a357535e-f722-4afe-b375-cff362b2b376 name: Malformed user agent description: | 'Malware authors will sometimes hardcode user agent string values when writing the network communication component of their malware. Malformed user agents can be an indication of such malware.' severity: Medium requiredDataConnectors: - connectorId: WAF dataTypes: - AzureDiagnostics - connectorId: Office365 dataTypes: - OfficeActivity - connectorId: AzureActiveDirectory dataTypes: - SigninLogs - connectorId: AzureActiveDirectory dataTypes: - AADNonInteractiveUserSignInLogs - connectorId: AWS dataTypes: - AWSCloudTrail - connectorId: AzureMonitor(IIS) dataTypes: - W3CIISLog queryFrequency: 1d queryPeriod: 1d triggerOperator: gt triggerThreshold: 0 tactics: - InitialAccess - CommandAndControl - Execution relevantTechniques: - T1189 - T1071 - T1203 query: | (union isfuzzy=true (OfficeActivity | where UserAgent != ""), (OfficeActivity | where RecordType in ("AzureActiveDirectory", "AzureActiveDirectoryStsLogon") | extend OperationName = Operation | parse ExtendedProperties with * 'User-Agent\\":\\"' UserAgent2 '\\' * | parse ExtendedProperties with * 'UserAgent", "Value": "' UserAgent1 '"' * | where isnotempty(UserAgent1) or isnotempty(UserAgent2) | extend UserAgent = iff( RecordType == 'AzureActiveDirectoryStsLogon', UserAgent1, UserAgent2) | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by UserAgent, SourceIP = ClientIP, Account = UserId, Type, RecordType, Operation ), (AzureDiagnostics | where ResourceType =~ "APPLICATIONGATEWAYS" | where OperationName =~ "ApplicationGatewayAccess" | extend ClientIP = columnifexists("clientIP_s", "None"), UserAgent = columnifexists("userAgent_s", "None") | where UserAgent != '-' | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by UserAgent, SourceIP = ClientIP, requestUri_s, httpMethod_s, host_s, requestQuery_s, Type ), ( W3CIISLog | where isnotempty(csUserAgent) | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by UserAgent = csUserAgent, SourceIP = cIP, Account = csUserName, Type, sSiteName, csMethod, csUriStem ), ( AWSCloudTrail | where isnotempty(UserAgent) | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by UserAgent, SourceIP = SourceIpAddress, Account = UserIdentityUserName, Type, EventSource, EventName ), (SigninLogs | where isnotempty(UserAgent) | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by UserAgent, SourceIP = IPAddress, Account = UserPrincipalName, Type, OperationName, tostring(LocationDetails), tostring(DeviceDetail), AppDisplayName, ClientAppUsed ), (AADNonInteractiveUserSignInLogs | where isnotempty(UserAgent) | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by UserAgent, SourceIP = IPAddress, Account = UserPrincipalName, Type, OperationName, tostring(LocationDetails), tostring(DeviceDetail), AppDisplayName, ClientAppUsed ) ) // Likely artefact of hardcoding | where UserAgent startswith "User" or UserAgent startswith '\"' // Incorrect casing or (UserAgent startswith "Mozilla" and not(UserAgent contains_cs "Mozilla")) // Incorrect casing or UserAgent contains_cs "(Compatible;" // Missing MSIE version or UserAgent matches regex @"MSIE\s?;" // Incorrect spacing around MSIE version or UserAgent matches regex @"MSIE(?:\d|.{1,5}?\d\s;)" | extend AccountName = split(Account, "@")[0], UPNSuffix = split(Account, "@")[1] entityMappings: - entityType: Account fieldMappings: - identifier: FullName columnName: Account - identifier: Name columnName: AccountName - identifier: UPNSuffix columnName: UPNSuffix - entityType: IP fieldMappings: - identifier: Address columnName: SourceIP version: 1.0.6 kind: Scheduled metadata: source: kind: Community author: name: Microsoft Security Research support: tier: Community categories: domains: [ "Security - Threat Protection" ]