Tool
Hunt pack: Agrius
1,106 vendor-native detections · ready to paste into your SIEM · cross-linked to ATT&CK
Vendor-native detections covering the ATT&CK techniques attributed to Agrius - a ready-to-deploy hunt pack across Splunk, Elastic and Sentinel.
◈
Detections
50 shown of 1,106Suspicious modification of Global Administrator user properties
'This query will detect if user properties of Global Administrator are updated by an existing user. Usually only user administrator or other global administrator can update such properties.
Investigate if such user change is an attempt to elevate an existing low privileged identity or rogue administrator activity'
Show query
let query_frequency = 1h;
let query_period = 14d;
IdentityInfo
| where TimeGenerated > ago(query_period)
| where set_has_element(AssignedRoles, "Global Administrator")
| distinct AccountUPN, AccountObjectId
| join kind=inner (
AuditLogs
| where TimeGenerated > ago(query_frequency)
| where OperationName=~ "Update user" and Result =~ "success"
// | where isnotempty(InitiatedBy["user"])
| mv-expand TargetResource = TargetResources
| where TargetResource["type"] == "User"
| extend AccountObjectId = tostring(TargetResource["id"])
| where tostring(TargetResource["modifiedProperties"]) != "[]"
| mv-apply modifiedProperty = TargetResource["modifiedProperties"] on (
summarize modifiedProperties = make_bag(
bag_pack(tostring(modifiedProperty["displayName"]),
bag_pack("oldValue", trim(@'[\"\s]+', tostring(modifiedProperty["oldValue"])),
"newValue", trim(@'[\"\s]+', tostring(modifiedProperty["newValue"])))))
)
| where not(tostring(modifiedProperties["Included Updated Properties"]["newValue"]) in ("LastDirSyncTime", ""))
| where not(tostring(modifiedProperties["Included Updated Properties"]["newValue"]) == "StrongAuthenticationPhoneAppDetail" and isnotempty(modifiedProperties["StrongAuthenticationPhoneAppDetail"]) and tostring(array_sort_asc(extract_all(@'\"Id\"\:\"([^\"]+)\"', tostring(modifiedProperties["StrongAuthenticationPhoneAppDetail"]["newValue"])))) == tostring(array_sort_asc(extract_all(@'\"Id\"\:\"([^\"]+)\"', tostring(modifiedProperties["StrongAuthenticationPhoneAppDetail"]["oldValue"])))))
| extend
Initiator = iif(isnotempty(InitiatedBy["app"]), tostring(InitiatedBy["app"]["displayName"]), tostring(InitiatedBy["user"]["userPrincipalName"])),
InitiatorId = iif(isnotempty(InitiatedBy["app"]), tostring(InitiatedBy["app"]["servicePrincipalId"]), tostring(InitiatedBy["user"]["id"])),
IPAddress = tostring(InitiatedBy[tostring(bag_keys(InitiatedBy)[0])]["ipAddress"])
) on AccountObjectId
| project TimeGenerated, Category, Identity, Initiator, IPAddress, OperationName, Result, AccountUPN, InitiatedBy, AdditionalDetails, TargetResources, AccountObjectId, InitiatorId, CorrelationId
| extend
InitiatorName = tostring(split(Initiator, "@")[0]),
InitiatorUPNSuffix = tostring(split(Initiator, "@")[1]),
AccountName = tostring(split(AccountUPN, "@")[0]),
AccountUPNSuffix = tostring(split(AccountUPN, "@")[1])
URL Added to Application from Unknown Domain
'Detects a URL being added to an application where the domain is not one that is associated with the tenant.
The query uses domains seen in sign in logs to determine if the domain is associated with the tenant.
Applications associated with URLs not controlled by the organization can pose a security risk.
Ref: https://learn.microsoft.com/en-gb/entra/architecture/security-operations-applications#application-configuration-changes'
Show query
let domains =
SigninLogs
| where ResultType == 0
| extend domain = split(UserPrincipalName, "@")[1]
| extend domain = tostring(split(UserPrincipalName, "@")[1])
| summarize by tolower(tostring(domain));
AuditLogs
| where Category =~ "ApplicationManagement"
| where Result =~ "success"
| where OperationName =~ 'Update Application'
| mv-expand TargetResources
| mv-expand TargetResources.modifiedProperties
| where TargetResources_modifiedProperties.displayName =~ "AppAddress"
| extend Key = tostring(TargetResources_modifiedProperties.displayName)
| extend NewValue = TargetResources_modifiedProperties.newValue
| extend OldValue = TargetResources_modifiedProperties.oldValue
| where isnotempty(Key) and isnotempty(NewValue)
| project-reorder Key, NewValue, OldValue
| extend NewUrls = extract_all('"Address":([^,]*)', tostring(NewValue))
| extend OldUrls = extract_all('"Address":([^,]*)', tostring(OldValue))
| extend AddedUrls = set_difference(NewUrls, OldUrls)
| where array_length(AddedUrls) > 0
| extend UserAgent = iif(tostring(AdditionalDetails[0].key) == "User-Agent", tostring(AdditionalDetails[0].value), "")
| extend InitiatingAppName = tostring(InitiatedBy.app.displayName)
| extend InitiatingAppServicePrincipalId = tostring(InitiatedBy.app.servicePrincipalId)
| extend InitiatingUserPrincipalName = tostring(InitiatedBy.user.userPrincipalName)
| extend InitiatingAadUserId = tostring(InitiatedBy.user.id)
| extend InitiatingIPAddress = tostring(InitiatedBy.user.ipAddress)
| extend InitiatedBy = tostring(iff(isnotempty(InitiatingUserPrincipalName),InitiatingUserPrincipalName, InitiatingAppName))
| extend AppDisplayName = tostring(TargetResources.displayName)
| where isnotempty(AddedUrls)
| mv-expand AddedUrls
| extend AddedUrls = trim(@'"', tostring(AddedUrls))
| extend Domain = extract("^(?:https?:\\/\\/)?(?:[^@\\/\\n]+@)?(?:www\\.)?([^:\\/?\\n]+)/", 1, replace_string(tolower(AddedUrls), '"', ""))
| where isnotempty(Domain)
| extend Domain = strcat(split(Domain, ".")[-2], ".", split(Domain, ".")[-1])
| where Domain !in (domains)
| project-reorder TimeGenerated, AppDisplayName, AddedUrls, InitiatedBy, UserAgent, InitiatingIPAddress
| extend InitiatingAccountName = tostring(split(InitiatingUserPrincipalName, "@")[0]), InitiatingAccountUPNSuffix = tostring(split(InitiatingUserPrincipalName, "@")[1])
Unusual identity creation using exchange powershell
' The query below identifies creation of unusual identity by the Europium actor to mimic Microsoft Exchange Health Manager Service account using Exchange PowerShell commands
Reference: https://www.microsoft.com/security/blog/2022/09/08/microsoft-investigates-iranian-attacks-against-the-albanian-government/'
Show query
(union isfuzzy=true
(SecurityEvent
| where EventID==4688
| where CommandLine has_any ("New-Mailbox","Update-RoleGroupMember") and CommandLine has "HealthMailbox55x2yq"
| project TimeGenerated, DeviceName = Computer, AccountName = SubjectUserName, AccountDomain = SubjectDomainName, ProcessName, ProcessNameFullPath = NewProcessName, EventID, Activity, CommandLine, EventSourceName, Type
| extend InitiatingProcessAccount = strcat(AccountDomain, "\\", AccountName)
),
(DeviceProcessEvents
| where ProcessCommandLine has_any ("New-Mailbox","Update-RoleGroupMember") and ProcessCommandLine has "HealthMailbox55x2yq"
| extend timestamp = TimeGenerated, AccountDomain = InitiatingProcessAccountDomain, AccountName = InitiatingProcessAccountName
| extend InitiatingProcessAccount = strcat(AccountDomain, "\\", AccountName)
)
)
| extend HostName = tostring(split(DeviceName, ".")[0]), DomainIndex = toint(indexof(DeviceName, '.'))
| extend HostNameDomain = iff(DomainIndex != -1, substring(DeviceName, DomainIndex + 1), DeviceName)
User Account Created Using Incorrect Naming Format
'This query looks for accounts being created where the name does not match a defined pattern.
Attackers may attempt to add accounts as a means of establishing persistant access to an environment, looking for anomalies in created accounts may help identify illegitimately created accounts.
Created accounts should be investigated to ensure they were legitimated created.
The user_regex field in the query needs to be populated with the expected pattern for the environment before deployment.
R
Show query
// Add the environments expected username format regex below before deploying let user_regex = ""; AuditLogs | where OperationName =~ "Add user" | where Result =~ "success" | extend userAgent = tostring(AdditionalDetails[0].value) | extend InitiatingAppName = tostring(InitiatedBy.app.displayName) | extend InitiatingAppServicePrincipalId = tostring(InitiatedBy.app.servicePrincipalId) | extend InitiatingUserPrincipalName = tostring(InitiatedBy.user.userPrincipalName) | extend InitiatingAadUserId = tostring(InitiatedBy.user.id) | extend InitiatingIPAddress = tostring(InitiatedBy.user.ipAddress) | extend InitiatedBy = tostring(iff(isnotempty(InitiatingUserPrincipalName),InitiatingUserPrincipalName, InitiatingAppName)) | extend AddedUser = tostring(TargetResources[0].userPrincipalName) | where AddedUser matches regex user_regex | extend InitiatingAccountName = tostring(split(InitiatingUserPrincipalName, "@")[0]), InitiatingAccountUPNSuffix = tostring(split(InitiatingUserPrincipalName, "@")[1]) | extend TargetAccountName = tostring(split(AddedUser, "@")[0]), TargetAccountUPNSuffix = tostring(split(AddedUser, "@")[1])
User account created without expected attributes defined
'This query looks for accounts being created that do not have attributes populated that are commonly populated in the tenant.
Attackers may attempt to add accounts as a means of establishing persistant access to an environment, looking for anomalies in created accounts may help identify illegitimately created accounts.
Created accounts should be investigated to ensure they were legitimated created.
Ref: https://docs.microsoft.com/azure/active-directory/fundamentals/security-operations-user
Show query
let threshold = 10;
let default_ad_attributes = dynamic(["LastDirSyncTime", "StsRefreshTokensValidFrom", "Included Updated Properties", "AccountEnabled", "Action Client Name", "SourceAnchor"]);
let addUsers = AuditLogs
| where OperationName =~ "Add user"
| where Result =~ "success"
| extend AccountProperties = TargetResources[0].modifiedProperties
| mv-expand AccountProperties
;
addUsers
| evaluate bag_unpack(AccountProperties) : (displayName:string, oldValue: string, newValue: string , TenantId : string, SourceSystem : string, TimeGenerated : datetime, ResourceId : string, OperationName : string, OperationVersion : string, Category : string, ResultType : string, ResultSignature : string, ResultDescription : string, DurationMs : long, CorrelationId : string, Resource : string, ResourceGroup : string, ResourceProvider : string, Identity : string, Level : string, Location : string, AdditionalDetails : dynamic, Id : string, InitiatedBy : dynamic, LoggedByService : string, Result : string, ResultReason : string, TargetResources : dynamic, AADTenantId : string, ActivityDisplayName : string, ActivityDateTime : datetime, AADOperationType : string, Type : string)
| extend displayName = column_ifexists("displayName", "Unknown Value")
| summarize count() by displayName, TenantId
| where displayName !in (default_ad_attributes)
| top threshold by count_ desc
| summarize make_set(displayName) by TenantId
| join kind=inner (
addUsers
| extend CreatingUserPrincipalName = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)
| extend CreatingAadUserId = tostring(InitiatedBy.user.id)
| extend CreatingUserIPAddress = tostring(InitiatedBy.user.ipAddress)
| extend CreatedUserPrincipalName = tostring(TargetResources[0].userPrincipalName)
| extend PropName = tostring(AccountProperties.displayName))
on TenantId
| summarize makeset(PropName) by TimeGenerated, CorrelationId, CreatedUserPrincipalName, CreatingUserPrincipalName, CreatingAadUserId, CreatingUserIPAddress, tostring(set_displayName)
| extend missing_props = set_difference(todynamic(set_displayName), set_PropName)
| where array_length(missing_props) > 0
| join kind=innerunique (
AuditLogs
| where Result =~ "success"
| where OperationName =~ "Add user"
| extend CreatedUserPrincipalName = tostring(TargetResources[0].userPrincipalName))
on CorrelationId, CreatedUserPrincipalName
| extend ExpectedProperties = set_displayName
| project-away set_displayName, set_PropName
| extend InitiatingAccountName = tostring(split(CreatingUserPrincipalName, "@")[0]), InitiatingAccountUPNSuffix = tostring(split(CreatingUserPrincipalName, "@")[1])
| extend TargetAccountName = tostring(split(CreatedUserPrincipalName, "@")[0]), TargetAccountUPNSuffix = tostring(split(CreatedUserPrincipalName, "@")[1])
User joining Zoom meeting from suspicious timezone
'The alert shows users that join a Zoom meeting from a time zone other than the one the meeting was created in.
You can also whitelist known good time zones in the tz_whitelist value using the tz database name format https://en.wikipedia.org/wiki/List_of_tz_database_time_zones'
Show query
let schedule_lookback = 14d; let join_lookback = 1d; // If you want to whitelist specific timezones include them in a list here let tz_whitelist = dynamic([]); let meetings = ( ZoomLogs | where TimeGenerated >= ago(schedule_lookback) | where Event =~ "meeting.created" | extend MeetingId = tostring(parse_json(MeetingEvents).MeetingId) | extend SchedTimezone = tostring(parse_json(MeetingEvents).Timezone)); ZoomLogs | where TimeGenerated >= ago(join_lookback) | where Event =~ "meeting.participant_joined" | extend JoinedTimeZone = tostring(parse_json(MeetingEvents).Timezone) | extend MeetingName = tostring(parse_json(MeetingEvents).MeetingName) | extend MeetingId = tostring(parse_json(MeetingEvents).MeetingId) | where JoinedTimeZone !in (tz_whitelist) | join (meetings) on MeetingId | where SchedTimezone != JoinedTimeZone | project TimeGenerated, MeetingName, JoiningUser=payload_object_participant_user_name_s, JoinedTimeZone, SchedTimezone, MeetingScheduler=User1 | extend AccountName = tostring(split(JoiningUser, "@")[0]), AccountUPNSuffix = tostring(split(JoiningUser, "@")[1])
User login from different countries within 3 hours (Uses Authentication Normalization)
'This query searches for successful user logins from different countries within 3 hours.
To use this analytics rule, make sure you have deployed the [ASIM normalization parsers](https://aka.ms/ASimAuthentication)'
Show query
let timeframe = ago(3h);
let threshold = 2;
imAuthentication
| where TimeGenerated > timeframe
| where EventType == 'Logon'
and EventResult == 'Success'
| where isnotempty(SrcGeoCountry)
| summarize
StartTime = min(TimeGenerated)
, EndTime = max(TimeGenerated)
, Vendors = make_set(EventVendor, 128)
, Products = make_set(EventProduct, 128)
, NumOfCountries = dcount(SrcGeoCountry)
, Countries = make_set(SrcGeoCountry, 128)
by TargetUserId, TargetUsername, TargetUserType
| where NumOfCountries >= threshold
| where TargetUserType !in ("Application", "Service", "System", "Other", "Machine", "ServicePrincipal")
| extend
Name = iif(
TargetUsername contains "@"
, tostring(split(TargetUsername, '@', 0)[0])
, TargetUsername
),
UPNSuffix = iif(
TargetUsername contains "@"
, tostring(split(TargetUsername, '@', 1)[0])
, ""
)
Vulnerable Machines related to OMIGOD CVE-2021-38647
'This query uses the Azure Defender Security Nested Recommendations data to find machines vulnerable to OMIGOD CVE-2021-38647.
OMI is the Linux equivalent of Windows WMI and helps users manage configurations across remote and local environments. The query aims to find machines that have this OMI vulnerability (CVE-2021-38647).
Security Nested Recommendations data is sent to Microsoft Sentinel using the continuous export feature of Azure Defender(refrence link below).
Reference: https://www.wiz
Show query
SecurityNestedRecommendation | where RemediationDescription has 'CVE-2021-38647' | parse ResourceDetails with * 'virtualMachines/' VirtualMAchine '"' * | summarize arg_min(TimeGenerated, *) by TenantId, RecommendationSubscriptionId, VirtualMAchine, RecommendationName,Description,RemediationDescription, tostring(AdditionalData),VulnerabilityId | extend HostName = tostring(split(VirtualMAchine, ".")[0]), DomainIndex = toint(indexof(VirtualMAchine, '.')) | extend HostNameDomain = iff(DomainIndex != -1, substring(VirtualMAchine, DomainIndex + 1), VirtualMAchine)
Windows host username encoded in base64 web request
'This detection will identify network requests in HTTP proxy data that contains Base64 encoded usernames from machines in the DeviceEvents table.
This technique was seen usee by POLONIUM in their RunningRAT tool.'
Show query
let accountLookback = 3d;
let requestLookback = 3d;
let extraction_regex = @"(?:\?|&)[a-zA-Z0-9\%]*=([a-zA-Z0-9\/\+\=]*)";
// Collect account names and base64 encode them
DeviceEvents
| where TimeGenerated > ago(accountLookback)
| summarize make_set(DeviceId), make_set(DeviceName) by InitiatingProcessAccountName
| where isnotempty(InitiatingProcessAccountName)
| extend base64_user = base64_encode_tostring(InitiatingProcessAccountName)
| join (
// Collect requests and extract base64 parameters
CommonSecurityLog
| where TimeGenerated > ago(requestLookback)
| where isnotempty(RequestURL)
// Summarize early on the RequestURL
| summarize FirstRequest=min(TimeGenerated), LastRequest=max(TimeGenerated), NumberOfRequests=count() by RequestURL
| extend base64_candidate = extract_all(extraction_regex, RequestURL)
| mv-expand base64_candidate to typeof(string)
) on $left.base64_user == $right.base64_candidate
| project FirstRequest, LastRequest, NumberOfRequests, RequestURL, DeviceIds=set_DeviceId, DeviceNames=set_DeviceName, UserName=InitiatingProcessAccountName
Workspace deletion activity from an infected device
'This query will alert on any sign-ins from devices infected with malware in correlation with workspace deletion activity.
Attackers may attempt to delete workspaces containing compute instances after successful compromise to cause service unavailability to regular business operation.'
Show query
SecurityAlert
| where TimeGenerated > ago(1d)
| where ProductName == "Azure Active Directory Identity Protection"
| where AlertName == "Sign-in from an infected device"
| mv-apply EntityAccount=todynamic(Entities) on
(
where EntityAccount.Type == "account"
| extend AadTenantId = tostring(EntityAccount.AadTenantId), AadUserId = tostring(EntityAccount.AadUserId)
)
| mv-apply EntityIp=todynamic(Entities) on
(
where EntityIp.Type == "ip"
| extend IpAddress = tostring(EntityIp.Address)
)
| join kind=inner (
IdentityInfo
| distinct AccountTenantId, AccountObjectId, AccountUPN, AccountDisplayName
| extend UserAccount = AccountUPN
| extend UserName = AccountDisplayName
| where isnotempty(AccountDisplayName) and isnotempty(UserAccount)
| project AccountTenantId, AccountObjectId, UserAccount, UserName
)
on
$left.AadTenantId == $right.AccountTenantId,
$left.AadUserId == $right.AccountObjectId
| extend CompromisedEntity = iff(CompromisedEntity == "N/A" or isempty(CompromisedEntity), UserAccount, CompromisedEntity)
| project AlertName, AlertSeverity, CompromisedEntity, UserAccount, IpAddress, TimeGenerated, UserName
| join kind=inner
(
AzureActivity
| where OperationNameValue has_any ("/workspaces/computes/delete", "workspaces/delete")
| where ActivityStatusValue has_any ("Succeeded", "Success")
| project TimeGenerated, ResourceProviderValue, _ResourceId, SubscriptionId, UserAccount=Caller, IpAddress=CallerIpAddress, CorrelationId, OperationId, ResourceGroup, TenantId
) on IpAddress, UserAccount
| extend AccountName = tostring(split(UserAccount, "@")[0]), AccountUPNSuffix = tostring(split(UserAccount, "@")[1])
3CX Supply Chain Attack Network Indicators
The following analytic identifies DNS queries to domains associated with the 3CX supply chain attack. It leverages the Network_Resolution datamodel to detect these suspicious domain indicators. This activity is significant because it can indicate a potential compromise stemming from the 3CX supply chain attack, which is known for distributing malicious software through trusted updates. If confirmed malicious, this activity could allow attackers to establish a foothold in the network, exfiltrate sensitive data, or further propagate malware, leading to extensive damage and data breaches.
Show query
| tstats `security_content_summariesonly`
count min(_time) as firstTime
max(_time) as lastTime
from datamodel=Network_Resolution where
DNS.query=*
NOT DNS.query IN ("-", "unknown")
by DNS.answer DNS.answer_count DNS.query
DNS.query_count DNS.reply_code_id DNS.src
DNS.vendor_product
| `drop_dm_object_name(DNS)`
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| lookup 3cx_ioc_domains domain as query OUTPUT Description isIOC
| search isIOC=true
| `3cx_supply_chain_attack_network_indicators_filter`
ASL AWS Create Access Key
The following analytic identifies the creation of AWS IAM access keys by a user for another user, which can indicate privilege escalation. It leverages AWS CloudTrail logs to detect instances where the user creating the access key is different from the user for whom the key is created. This activity is significant because unauthorized access key creation can allow attackers to establish persistence or exfiltrate data via AWS APIs. If confirmed malicious, this could lead to unauthorized access to AWS services, data exfiltration, and long-term persistence in the environment.
Show query
`amazon_security_lake` api.operation=CreateAccessKey
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY actor.user.uid api.operation api.service.name
http_request.user_agent src_endpoint.ip actor.user.account.uid
cloud.provider cloud.region
| rename actor.user.uid as user api.operation as action api.service.name as dest http_request.user_agent as user_agent src_endpoint.ip as src actor.user.account.uid as vendor_account cloud.provider as vendor_product cloud.region as vendor_region
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `asl_aws_create_access_key_filter`ASL AWS Create Policy Version to allow all resources
The following analytic identifies the creation of a new AWS IAM policy version that allows access to all resources. It detects this activity by analyzing AWS CloudTrail logs for the CreatePolicyVersion event with a policy document that grants broad permissions. This behavior is significant because it violates the principle of least privilege, potentially exposing the environment to misuse or abuse. If confirmed malicious, an attacker could gain extensive access to AWS resources, leading to unauthorized actions, data exfiltration, or further compromise of the AWS environment.
Show query
`amazon_security_lake` api.operation=CreatePolicy
| spath input=api.request.data
| spath input=policyDocument
| regex Statement{}.Action="\*"
| regex Statement{}.Resource="\*"
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY actor.user.uid api.operation api.service.name
http_request.user_agent src_endpoint.ip actor.user.account.uid
cloud.provider cloud.region api.request.data
| rename actor.user.uid as user api.operation as action api.service.name as dest http_request.user_agent as user_agent src_endpoint.ip as src actor.user.account.uid as vendor_account cloud.provider as vendor_product cloud.region as vendor_region
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `asl_aws_create_policy_version_to_allow_all_resources_filter`ASL AWS Defense Evasion PutBucketLifecycle
The following analytic detects `PutBucketLifecycle` events in AWS CloudTrail logs where a user sets a lifecycle rule for an S3 bucket with an expiration period of fewer than three days. This detection leverages CloudTrail logs to identify suspicious lifecycle configurations. This activity is significant because attackers may use it to delete CloudTrail logs quickly, thereby evading detection and impairing forensic investigations. If confirmed malicious, this could allow attackers to cover their tracks, making it difficult to trace their actions and respond to the breach effectively.
Show query
`amazon_security_lake` api.operation=PutBucketLifecycle
| spath input=api.request.data path=LifecycleConfiguration.Rule.NoncurrentVersionExpiration.NoncurrentDays output=NoncurrentDays
| where NoncurrentDays < 3
| spath input=api.request.data
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY actor.user.uid api.operation api.service.name
http_request.user_agent src_endpoint.ip actor.user.account.uid
cloud.provider cloud.region NoncurrentDays
bucketName
| rename actor.user.uid as user api.operation as action api.service.name as dest http_request.user_agent as user_agent src_endpoint.ip as src actor.user.account.uid as vendor_account cloud.provider as vendor_product cloud.region as vendor_region
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `asl_aws_defense_evasion_putbucketlifecycle_filter`ASL AWS Detect Users creating keys with encrypt policy without MFA
The following analytic detects the creation of AWS KMS keys with an encryption policy accessible to everyone, including external entities. It leverages AWS CloudTrail logs from Amazon Security Lake to identify `CreateKey` or `PutKeyPolicy` events where the `kms:Encrypt` action is granted to all principals. This activity is significant as it may indicate a compromised account, allowing an attacker to misuse the encryption key to target other organizations. If confirmed malicious, this could lead to unauthorized data encryption, potentially disrupting operations and compromising sensitive information across multiple entities.
Show query
`amazon_security_lake` api.operation=PutKeyPolicy OR api.operation=CreateKey
| spath input=api.request.data path=policy output=policy
| spath input=policy
| rename Statement{}.Action as Action, Statement{}.Principal as Principal
| eval Statement=mvzip(Action,Principal,"
| ")
| mvexpand Statement
| eval action=mvindex(split(Statement, "
| "), 0)
| eval principal=mvindex(split(Statement, "
| "), 1)
| search action=kms*
| regex principal="\*"
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY actor.user.uid api.operation api.service.name
http_request.user_agent src_endpoint.ip actor.user.account.uid
cloud.provider cloud.region api.request.data
| rename actor.user.uid as user api.operation as action api.service.name as dest http_request.user_agent as user_agent src_endpoint.ip as src actor.user.account.uid as vendor_account cloud.provider as vendor_product cloud.region as vendor_region
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `asl_aws_detect_users_creating_keys_with_encrypt_policy_without_mfa_filter`ASL AWS IAM Successful Group Deletion
The following analytic detects the successful deletion of a group within AWS IAM, leveraging CloudTrail IAM events. This action, while not inherently malicious, can serve as a precursor to more sinister activities, such as unauthorized access or privilege escalation attempts. By monitoring for such deletions, the analytic aids in identifying potential preparatory steps towards an attack, allowing for early detection and mitigation. The identification of this behavior is crucial for a SOC to prevent the potential impact of an attack, which could include unauthorized access to sensitive resources or disruption of AWS environment operations.
Show query
`amazon_security_lake` api.operation=DeleteGroup status=Success
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY actor.user.uid api.operation api.service.name
http_request.user_agent src_endpoint.ip actor.user.account.uid
cloud.provider cloud.region
| rename actor.user.uid as user api.operation as action api.service.name as dest http_request.user_agent as user_agent src_endpoint.ip as src actor.user.account.uid as vendor_account cloud.provider as vendor_product cloud.region as vendor_region
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `asl_aws_iam_successful_group_deletion_filter`ASL AWS SAML Update identity provider
The following analytic detects updates to the SAML provider in AWS. It leverages AWS CloudTrail logs to identify the `UpdateSAMLProvider` event, analyzing fields such as `sAMLProviderArn`, `sourceIPAddress`, and `userIdentity` details. Monitoring updates to the SAML provider is crucial as it may indicate a perimeter compromise of federated credentials or unauthorized backdoor access set by an attacker. If confirmed malicious, this activity could allow attackers to manipulate identity federation, potentially leading to unauthorized access to cloud resources and sensitive data.
Show query
`amazon_security_lake` api.operation=UpdateSAMLProvider
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY actor.user.uid api.operation api.service.name
http_request.user_agent src_endpoint.ip actor.user.account.uid
cloud.provider cloud.region
| rename actor.user.uid as user api.operation as action api.service.name as dest http_request.user_agent as user_agent src_endpoint.ip as src actor.user.account.uid as vendor_account cloud.provider as vendor_product cloud.region as vendor_region
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `asl_aws_saml_update_identity_provider_filter`ASL AWS UpdateLoginProfile
The following analytic detects an AWS CloudTrail event where a user with permissions updates the login profile of another user. It leverages CloudTrail logs to identify instances where the user making the change is different from the user whose profile is being updated. This activity is significant because it can indicate privilege escalation attempts, where an attacker uses a compromised account to gain higher privileges. If confirmed malicious, this could allow the attacker to escalate their privileges, potentially leading to unauthorized access and control over sensitive resources within the AWS environment.
Show query
`amazon_security_lake` api.operation=UpdateLoginProfile
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY actor.user.uid api.operation api.service.name
http_request.user_agent src_endpoint.ip actor.user.account.uid
cloud.provider cloud.region
| rename actor.user.uid as user api.operation as action api.service.name as dest http_request.user_agent as user_agent src_endpoint.ip as src actor.user.account.uid as vendor_account cloud.provider as vendor_product cloud.region as vendor_region
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `asl_aws_updateloginprofile_filter`AWS Bedrock Delete Knowledge Base
The following analytic identifies attempts to delete AWS Bedrock Knowledge Bases, which are resources that store and manage domain-specific information for AI models. It monitors AWS CloudTrail logs for DeleteKnowledgeBase API calls. This activity could indicate an adversary attempting to remove knowledge bases after compromising credentials, potentially to disrupt business operations or remove traces of data access. Deleting knowledge bases could impact model performance, remove critical business context, or be part of a larger attack to degrade AI capabilities. If confirmed malicious, this could represent a deliberate attempt to cause service disruption or data loss.
Show query
`cloudtrail` eventSource=bedrock.amazonaws.com eventName=DeleteKnowledgeBase | rename user_name as user | stats count min(_time) as firstTime max(_time) as lastTime values(requestParameters.knowledgeBaseId) as knowledgeBaseIds by src user user_agent vendor_account vendor_product dest signature vendor_region | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `aws_bedrock_delete_knowledge_base_filter`
AWS Create Policy Version to allow all resources
The following analytic identifies the creation of a new AWS IAM policy version that allows access to all resources. It detects this activity by analyzing AWS CloudTrail logs for the CreatePolicyVersion event with a policy document that grants broad permissions. This behavior is significant because it violates the principle of least privilege, potentially exposing the environment to misuse or abuse. If confirmed malicious, an attacker could gain extensive access to AWS resources, leading to unauthorized actions, data exfiltration, or further compromise of the AWS environment.
Show query
`cloudtrail` eventName=CreatePolicyVersion eventSource = iam.amazonaws.com errorCode = success
| spath input=requestParameters.policyDocument output=key_policy_statements path=Statement{}
| mvexpand key_policy_statements
| spath input=key_policy_statements output=key_policy_action_1 path=Action
| where key_policy_action_1 = "*"
| rename user_name as user
| stats count min(_time) as firstTime max(_time) as lastTime values(key_policy_statements) as policy_added
BY signature dest user
user_agent src vendor_account
vendor_region vendor_product
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `aws_create_policy_version_to_allow_all_resources_filter`AWS CreateAccessKey
The following analytic identifies the creation of AWS IAM access keys by a user for another user, which can indicate privilege escalation. It leverages AWS CloudTrail logs to detect instances where the user creating the access key is different from the user for whom the key is created. This activity is significant because unauthorized access key creation can allow attackers to establish persistence or exfiltrate data via AWS APIs. If confirmed malicious, this could lead to unauthorized access to AWS services, data exfiltration, and long-term persistence in the environment.
Show query
`cloudtrail` eventName = CreateAccessKey userAgent !=console.amazonaws.com errorCode = success
| eval match=if(match(userIdentity.userName,requestParameters.userName),1,0)
| search match=0
| rename user_name as user
| stats count min(_time) as firstTime max(_time) as lastTime
BY signature dest user
user_agent src vendor_account
vendor_region vendor_product
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `aws_createaccesskey_filter`AWS CreateLoginProfile
The following analytic identifies the creation of a login profile for one AWS user by another, followed by a console login from the same source IP. It uses AWS CloudTrail logs to correlate the `CreateLoginProfile` and `ConsoleLogin` events based on the source IP and user identity. This activity is significant as it may indicate privilege escalation, where an attacker creates a new login profile to gain unauthorized access. If confirmed malicious, this could allow the attacker to escalate privileges and maintain persistent access to the AWS environment.
Show query
`cloudtrail` eventName = CreateLoginProfile
| rename requestParameters.userName as new_login_profile
| table src_ip eventName new_login_profile userIdentity.userName
| join new_login_profile src_ip [
| search `cloudtrail` eventName = ConsoleLogin
| rename userIdentity.userName as new_login_profile
| stats count values(eventName) min(_time) as firstTime max(_time) as lastTime
BY eventSource aws_account_id errorCode
user_agent eventID awsRegion
userIdentity.principalId user_arn new_login_profile
src_ip dest vendor_account
vendor_region vendor_product
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`]
| rename user_arn as user
| `aws_createloginprofile_filter`AWS Defense Evasion PutBucketLifecycle
The following analytic detects `PutBucketLifecycle` events in AWS CloudTrail logs where a user sets a lifecycle rule for an S3 bucket with an expiration period of fewer than three days. This detection leverages CloudTrail logs to identify suspicious lifecycle configurations. This activity is significant because attackers may use it to delete CloudTrail logs quickly, thereby evading detection and impairing forensic investigations. If confirmed malicious, this could allow attackers to cover their tracks, making it difficult to trace their actions and respond to the breach effectively.
Show query
`cloudtrail` eventName=PutBucketLifecycle user_type=IAMUser errorCode=success
| spath path=requestParameters{}.LifecycleConfiguration{}.Rule{}.Expiration{}.Days output=expiration_days
| spath path=requestParameters{}.bucketName output=bucket_name
| rename user_name as user
| stats count min(_time) as firstTime max(_time) as lastTime
BY signature dest user
user_agent src vendor_account
vendor_region vendor_product bucket_name
expiration_days
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `aws_defense_evasion_putbucketlifecycle_filter`AWS Detect Users creating keys with encrypt policy without MFA
The following analytic detects the creation of AWS KMS keys with an encryption policy accessible to everyone, including external entities. It leverages AWS CloudTrail logs to identify `CreateKey` or `PutKeyPolicy` events where the `kms:Encrypt` action is granted to all principals. This activity is significant as it may indicate a compromised account, allowing an attacker to misuse the encryption key to target other organizations. If confirmed malicious, this could lead to unauthorized data encryption, potentially disrupting operations and compromising sensitive information across multiple entities.
Show query
`cloudtrail` eventName=CreateKey OR eventName=PutKeyPolicy
| spath input=requestParameters.policy output=key_policy_statements path=Statement{}
| mvexpand key_policy_statements
| spath input=key_policy_statements output=key_policy_action_1 path=Action
| spath input=key_policy_statements output=key_policy_action_2 path=Action{}
| eval key_policy_action=mvappend(key_policy_action_1,key_policy_action_2)
| spath input=key_policy_statements output=key_policy_principal path=Principal.AWS
| search key_policy_action="kms:Encrypt" AND key_policy_principal="*"
| rename user_name as user
| stats count min(_time) as firstTime max(_time) as lastTime
BY signature dest user
user_agent src vendor_account
vendor_region vendor_product key_policy_action
key_policy_principal
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `aws_detect_users_creating_keys_with_encrypt_policy_without_mfa_filter`AWS Detect Users with KMS keys performing encryption S3
The following analytic identifies users with KMS keys performing encryption operations on S3 buckets. It leverages AWS CloudTrail logs to detect the `CopyObject` event where server-side encryption with AWS KMS is specified. This activity is significant as it may indicate unauthorized or suspicious encryption of data, potentially masking exfiltration or tampering efforts. If confirmed malicious, an attacker could be encrypting sensitive data to evade detection or preparing it for exfiltration, posing a significant risk to data integrity and confidentiality.
Show query
`cloudtrail` eventName=CopyObject requestParameters.x-amz-server-side-encryption="aws:kms"
| rename requestParameters.bucketName AS bucketName, requestParameters.x-amz-copy-source AS src_file, requestParameters.key AS dest_file
| rename user_name as user
| stats count min(_time) as firstTime max(_time) as lastTime
BY signature dest user
user_agent src vendor_account
vendor_region vendor_product bucketName
src_file dest_file
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `aws_detect_users_with_kms_keys_performing_encryption_s3_filter`AWS Exfiltration via Anomalous GetObject API Activity
The following analytic identifies anomalous GetObject API activity in AWS, indicating potential data exfiltration attempts. It leverages AWS CloudTrail logs and uses the `anomalydetection` command to detect unusual patterns in the frequency of GetObject API calls by analyzing fields such as "count," "user_type," and "user_arn" within a 10-minute window. This activity is significant as it may indicate unauthorized data access or exfiltration from S3 buckets. If confirmed malicious, attackers could exfiltrate sensitive data, leading to data breaches and compliance violations.
Show query
`cloudtrail` eventName=GetObject
| bin _time span=10m
| rename user_name as user
| stats count values(requestParameters.bucketName) as bucketName
BY signature dest user
user_agent src vendor_account
vendor_region vendor_product
| anomalydetection "count" "user" action=annotate
| search probable_cause=*
| `aws_exfiltration_via_anomalous_getobject_api_activity_filter`AWS Exfiltration via Batch Service
The following analytic identifies the creation of AWS Batch jobs that could potentially abuse the AWS Bucket Replication feature on S3 buckets. It leverages AWS CloudTrail logs to detect the `JobCreated` event, analyzing job details and their status. This activity is significant because attackers can exploit this feature to exfiltrate data by creating malicious batch jobs. If confirmed malicious, this could lead to unauthorized data transfer between S3 buckets, resulting in data breaches and loss of sensitive information.
Show query
`cloudtrail` eventName = JobCreated
| fillnull
| rename user_name as user
| stats count min(_time) as firstTime max(_time) as lastTime
BY signature dest user
user_agent src vendor_account
vendor_region vendor_product
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `aws_exfiltration_via_batch_service_filter`AWS Exfiltration via DataSync Task
The following analytic detects the creation of an AWS DataSync task, which could indicate potential data exfiltration. It leverages AWS CloudTrail logs to identify the `CreateTask` event from the DataSync service. This activity is significant because attackers can misuse DataSync to transfer sensitive data from a private AWS location to a public one, leading to data compromise. If confirmed malicious, this could result in unauthorized access to sensitive information, causing severe data breaches and compliance violations.
Show query
`cloudtrail` eventName = CreateTask eventSource="datasync.amazonaws.com"
| rename requestParameters.* as *
| rename user_name as user
| stats count min(_time) as firstTime max(_time) as lastTime
BY signature dest user
user_agent src vendor_account
vendor_region vendor_product destinationLocationArn
sourceLocationArn
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `aws_exfiltration_via_datasync_task_filter`AWS IAM Successful Group Deletion
The following analytic identifies the successful deletion of an IAM group in AWS. It leverages CloudTrail logs to detect `DeleteGroup` events with a success status. This activity is significant as it could indicate potential changes in user permissions or access controls, which may be a precursor to further unauthorized actions. If confirmed malicious, an attacker could disrupt access management, potentially leading to privilege escalation or unauthorized access to sensitive resources. Analysts should review related IAM events, such as recent user additions or new group creations, to assess the broader context.
Show query
`cloudtrail` eventSource=iam.amazonaws.com eventName=DeleteGroup errorCode=success (userAgent!=*.amazonaws.com)
| rename user_name as user
| stats count min(_time) as firstTime max(_time) as lastTime
BY signature dest user
user_agent src vendor_account
vendor_region vendor_product
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `aws_iam_successful_group_deletion_filter`AWS SAML Update identity provider
The following analytic detects updates to the SAML provider in AWS. It leverages AWS CloudTrail logs to identify the `UpdateSAMLProvider` event, analyzing fields such as `sAMLProviderArn`, `sourceIPAddress`, and `userIdentity` details. Monitoring updates to the SAML provider is crucial as it may indicate a perimeter compromise of federated credentials or unauthorized backdoor access set by an attacker. If confirmed malicious, this activity could allow attackers to manipulate identity federation, potentially leading to unauthorized access to cloud resources and sensitive data.
Show query
`cloudtrail` eventName=UpdateSAMLProvider
| rename user_name as user
| stats count min(_time) as firstTime max(_time) as lastTime values(requestParameters.sAMLProviderArn) as request_parameters
BY signature dest user
user_agent src vendor_account
vendor_region vendor_product
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `aws_saml_update_identity_provider_filter`AWS SetDefaultPolicyVersion
The following analytic detects when a user sets a default policy version in AWS. It leverages AWS CloudTrail logs to identify the `SetDefaultPolicyVersion` event from the IAM service. This activity is significant because attackers may exploit this technique for privilege escalation, especially if previous policy versions grant more extensive permissions than the current one. If confirmed malicious, this could allow an attacker to gain elevated access to AWS resources, potentially leading to unauthorized actions and data breaches.
Show query
`cloudtrail` eventName=SetDefaultPolicyVersion eventSource = iam.amazonaws.com
| rename user_name as user
| stats count min(_time) as firstTime max(_time) as lastTime
BY signature dest user
user_agent src vendor_account
vendor_region vendor_product
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `aws_setdefaultpolicyversion_filter`AWS Successful Single-Factor Authentication
The following analytic identifies a successful Console Login authentication event for an AWS IAM user account without Multi-Factor Authentication (MFA) enabled. It leverages AWS CloudTrail logs to detect instances where MFA was not used during login. This activity is significant as it may indicate a misconfiguration, policy violation, or potential account takeover attempt. If confirmed malicious, an attacker could gain unauthorized access to the AWS environment, potentially leading to data exfiltration, resource manipulation, or further privilege escalation.
Show query
`cloudtrail` eventName= ConsoleLogin errorCode=success "additionalEventData.MFAUsed"=No
| rename user_name as user
| stats count min(_time) as firstTime max(_time) as lastTime
BY signature dest user
user_agent src vendor_account
vendor_region vendor_product
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `aws_successful_single_factor_authentication_filter`AWS UpdateLoginProfile
The following analytic detects an AWS CloudTrail event where a user with permissions updates the login profile of another user. It leverages CloudTrail logs to identify instances where the user making the change is different from the user whose profile is being updated. This activity is significant because it can indicate privilege escalation attempts, where an attacker uses a compromised account to gain higher privileges. If confirmed malicious, this could allow the attacker to escalate their privileges, potentially leading to unauthorized access and control over sensitive resources within the AWS environment.
Show query
`cloudtrail` eventName = UpdateLoginProfile userAgent !=console.amazonaws.com errorCode = success
| eval match=if(match(userIdentity.userName,requestParameters.userName), 1,0)
| search match=0
| rename user_name as user
| stats count min(_time) as firstTime max(_time) as lastTime
BY signature dest user
user_agent src vendor_account
vendor_region vendor_product
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `aws_updateloginprofile_filter`Access LSASS Memory for Dump Creation
The following analytic detects attempts to dump the LSASS process memory, a common technique in credential dumping attacks. It leverages Sysmon logs, specifically EventCode 10, to identify suspicious call traces to dbgcore.dll and dbghelp.dll associated with lsass.exe. This activity is significant as it often precedes the theft of sensitive login credentials, posing a high risk of unauthorized access to systems and data. If confirmed malicious, attackers could gain access to critical credentials, enabling further compromise and lateral movement within the network.
Show query
`sysmon` EventCode=10 TargetImage=*lsass.exe CallTrace=*dbgcore.dll* OR CallTrace=*dbghelp.dll*
| stats count min(_time) as firstTime max(_time) as lastTime
BY CallTrace EventID GrantedAccess
Guid Opcode ProcessID
SecurityID SourceImage SourceProcessGUID
SourceProcessId TargetImage TargetProcessGUID
TargetProcessId UserID dest
granted_access parent_process_exec parent_process_guid
parent_process_id parent_process_name parent_process_path
process_exec process_guid process_id
process_name process_path signature
signature_id user_id vendor_product
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `access_lsass_memory_for_dump_creation_filter`Access to Vulnerable Ivanti Connect Secure Bookmark Endpoint
The following analytic identifies access to the /api/v1/configuration/users/user-roles/user-role/rest-userrole1/web/web-bookmarks/bookmark endpoint, which is associated with CVE-2023-46805 and CVE-2024-21887 vulnerabilities. It detects this activity by monitoring for GET requests that receive a 403 Forbidden response with an empty body. This behavior is significant as it indicates potential exploitation attempts against Ivanti Connect Secure systems. If confirmed malicious, attackers could exploit these vulnerabilities to gain unauthorized access or control over the affected systems, leading to potential data breaches or system compromise.
Show query
| tstats count min(_time) as firstTime max(_time) as lastTime FROM datamodel=Web
WHERE Web.url="*/api/v1/configuration/users/user-roles/user-role/rest-userrole1/web/web-bookmarks/bookmark*" Web.http_method=GET Web.status=403
BY Web.src, Web.dest, Web.http_user_agent,
Web.status, Web.url source
| `drop_dm_object_name("Web")`
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `access_to_vulnerable_ivanti_connect_secure_bookmark_endpoint_filter`Adobe ColdFusion Access Control Bypass
The following analytic detects potential exploitation attempts against Adobe ColdFusion vulnerabilities CVE-2023-29298 and CVE-2023-26360.
It monitors requests to specific ColdFusion Administrator endpoints, especially those with an unexpected additional forward slash, using the Web datamodel.
This activity is significant for a SOC as it indicates attempts to bypass access controls, which can lead to unauthorized access to ColdFusion administration endpoints.
If confirmed malicious, this could result in data theft, brute force attacks, or further exploitation of other vulnerabilities, posing a serious security risk to the environment.
Show query
| tstats `security_content_summariesonly`
count min(_time) as firstTime
max(_time) as lastTime
FROM datamodel=Web WHERE
Web.url IN (
"*//CFIDE/adminapi*",
"*//CFIDE/administrator*",
"*//CFIDE/componentutils*",
"*//CFIDE/main*",
"*//CFIDE/restplay*",
"*//CFIDE/servermanager*",
"*//CFIDE/wizards*",
"*//restplay*",
)
Web.status=200
BY Web.http_user_agent Web.status Web.http_method
Web.url Web.url_length Web.src Web.dest
| `drop_dm_object_name("Web")`
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `adobe_coldfusion_access_control_bypass_filter`Adobe ColdFusion Unauthenticated Arbitrary File Read
The following analytic detects potential exploitation of the Adobe ColdFusion vulnerability, CVE-2023-26360, which allows unauthenticated arbitrary file read.
It monitors POST requests to the "/cf_scripts/scripts/ajax/ckeditor/*" endpoint using the Web datamodel.
This activity can be significant due to the vulnerability's high CVSS score of 9.8, indicating severe risk.
If confirmed malicious, it could lead to unauthorized data access, further attacks, or severe operational disruptions.
Show query
| tstats `security_content_summariesonly`
count min(_time) as firstTime
max(_time) as lastTime
FROM datamodel=Web WHERE
Web.url="*/cf_scripts/scripts/ajax/ckeditor/*"
Web.status=200
Web.http_method=POST
BY Web.http_user_agent Web.status Web.http_method
Web.url Web.url_length Web.src Web.dest
| `drop_dm_object_name("Web")`
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `adobe_coldfusion_unauthenticated_arbitrary_file_read_filter`AdsiSearcher Account Discovery
The following analytic detects the use of the `[Adsisearcher]` type accelerator in PowerShell to query Active Directory for domain users. It leverages PowerShell Script Block Logging (EventCode=4104) to identify script blocks containing `[adsisearcher]`, `objectcategory=user`, and `.findAll()`. This activity is significant as it may indicate an attempt by adversaries or Red Teams to enumerate domain users for situational awareness and Active Directory discovery. If confirmed malicious, this could lead to further reconnaissance, privilege escalation, or lateral movement within the network.
Show query
`powershell` EventCode=4104 ScriptBlockText = "*[adsisearcher]*" ScriptBlockText = "*objectcategory=user*" ScriptBlockText = "*.findAll()*"
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY dest signature signature_id
user_id vendor_product EventID
Guid Opcode Name
Path ProcessID ScriptBlockId
ScriptBlockText
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `adsisearcher_account_discovery_filter`Allow Inbound Traffic By Firewall Rule Registry
The following analytic detects suspicious modifications to firewall rule registry settings that allow inbound traffic on specific ports with a public profile. It leverages data from the Endpoint.Registry data model, focusing on registry paths and values indicative of such changes. This activity is significant as it may indicate an adversary attempting to grant remote access to a machine by modifying firewall rules. If confirmed malicious, this could enable unauthorized remote access, potentially leading to further exploitation, data exfiltration, or lateral movement within the network.
Show query
| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime FROM datamodel=Endpoint.Registry WHERE (Registry.registry_path= "*\\System\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\FirewallRules\\*" Registry.registry_value_data = "*|Action=Allow|*" Registry.registry_value_data = "*|Dir=In|*" Registry.registry_value_data = "*|LPort=*") by Registry.action Registry.dest Registry.process_guid Registry.process_id Registry.registry_hive Registry.registry_path Registry.registry_key_name Registry.registry_value_data Registry.registry_value_name Registry.registry_value_type Registry.status Registry.user Registry.vendor_product | `drop_dm_object_name(Registry)` | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `allow_inbound_traffic_by_firewall_rule_registry_filter`
Allow Inbound Traffic In Firewall Rule
The following analytic detects a suspicious PowerShell command that allows inbound traffic to a specific local port within the public profile. It leverages PowerShell script block logging (EventCode 4104) to identify commands containing keywords like "firewall," "Inbound," "Allow," and "-LocalPort." This activity is significant because it may indicate an attacker attempting to establish remote access by modifying firewall rules. If confirmed malicious, this could allow unauthorized access to the machine, potentially leading to further exploitation and data exfiltration.
Show query
`powershell` EventCode=4104 ScriptBlockText = "*firewall*" ScriptBlockText = "*Inbound*" ScriptBlockText = "*Allow*" ScriptBlockText = "*-LocalPort*"
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY dest signature signature_id
user_id vendor_product EventID
Guid Opcode Name
Path ProcessID ScriptBlockId
ScriptBlockText
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `allow_inbound_traffic_in_firewall_rule_filter`Azure AD Authentication Failed During MFA Challenge
The following analytic identifies failed authentication attempts against an Azure AD tenant during the Multi-Factor Authentication (MFA) challenge, specifically flagged by error code 500121. It leverages Azure AD SignInLogs to detect these events. This activity is significant as it may indicate an adversary attempting to authenticate using compromised credentials on an account with MFA enabled. If confirmed malicious, this could suggest an ongoing effort to bypass MFA protections, potentially leading to unauthorized access and further compromise of the affected account.
Show query
`azure_monitor_aad` category=SignInLogs properties.status.errorCode=500121 | rename properties.* as *, authenticationDetails{}.* as * | eval time=strptime(authenticationStepDateTime,"%Y-%m-%dT%H:%M:%S") | eval auth_detail=mvzip(strftime(time, "%Y-%m-%dT%H:%M:%S"),authenticationStepResultDetail," - "), auth_msg=mvappend('status.additionalDetails', authenticationStepResultDetail) | eval auth_method=mvmap(authenticationMethod, if(isnull(mvfind('mfaDetail.authMethod',authenticationMethod)), authenticationMethod, null())) | search NOT auth_msg="MFA successfully completed" | rename userAgent as user_agent | fillnull | stats count min(_time) as firstTime max(_time) as lastTime by dest user src vendor_account vendor_product auth_method auth_msg user_agent signature | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `azure_ad_authentication_failed_during_mfa_challenge_filter`Azure AD AzureHound UserAgent Detected
This detection identifies the presence of the default AzureHound user-agent string within Microsoft Graph Activity logs and NonInteractive SignIn Logs. AzureHound is a tool used for gathering information about Azure Active Directory environments, often employed by security professionals for legitimate auditing purposes. However, it can also be leveraged by malicious actors to perform reconnaissance activities, mapping out the Azure AD infrastructure to identify potential vulnerabilities and targets for further exploitation. Detecting its usage can help in identifying unauthorized access attempts and preemptively mitigating potential security threats to your Azure environment.
Show query
`azure_monitor_aad` category IN (MicrosoftGraphActivityLogs, NonInteractiveUserSignInLogs) properties.userAgent=azurehound*
| rename properties.userAgent as user_agent
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY dest user src
vendor_account vendor_product user_agent
signature
| iplocation src
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `azure_ad_azurehound_useragent_detected_filter`Azure AD External Guest User Invited
The following analytic detects the invitation of an external guest user within Azure AD. It leverages Azure AD AuditLogs to identify events where an external user is invited, using fields such as operationName and initiatedBy. Monitoring these invitations is crucial as they can lead to unauthorized access if abused. If confirmed malicious, this activity could allow attackers to gain access to internal resources, potentially leading to data breaches or further exploitation of the environment.
Show query
`azure_monitor_aad` operationName="Invite external user"
| rename properties.* as *
| rename initiatedBy.user.userPrincipalName as initiatedBy
| rename targetResources{}.type as type
| rename userAgent as user_agent
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY dest user src
vendor_account vendor_product user_agent
initiatedBy type signature
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `azure_ad_external_guest_user_invited_filter`Azure AD Multiple AppIDs and UserAgents Authentication Spike
The following analytic detects unusual authentication activity in Azure AD, specifically when a single user account has over 8 authentication attempts using 3+ unique application IDs and 5+ unique user agents within a short period. It leverages Azure AD audit logs, focusing on authentication events and using statistical thresholds. This behavior is significant as it may indicate an adversary probing for MFA requirements. If confirmed malicious, it suggests a compromised account, potentially leading to further exploitation, lateral movement, and data exfiltration. Early detection is crucial to prevent substantial harm.
Show query
`azure_monitor_aad` category=SignInLogs operationName="Sign-in activity" (properties.authenticationRequirement="multiFactorAuthentication" properties.status.additionalDetails="MFA required in Azure AD") OR (properties.authenticationRequirement=singleFactorAuthentication "properties.authenticationDetails{}.succeeded"=true)
| bucket span=5m _time
| rename properties.* as *
| rename userAgent as user_agent
| fillnull
| stats count dc(appId) as unique_app_ids dc(user_agent) as unique_user_agents min(_time) as firstTime max(_time) as lastTime values(dest) as dest values(user_agent) as user_agent
BY user src vendor_account
vendor_product signature
| where count > 5 and unique_app_ids > 2 and unique_user_agents > 5
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `azure_ad_multiple_appids_and_useragents_authentication_spike_filter`Azure AD Multiple Failed MFA Requests For User
The following analytic identifies multiple failed multi-factor authentication (MFA) requests for a single user within an Azure AD tenant. It leverages Azure AD Sign-in Logs, specifically error code 500121, to detect more than 10 failed MFA attempts within 10 minutes. This behavior is significant as it may indicate an adversary attempting to bypass MFA by bombarding the user with repeated authentication prompts. If confirmed malicious, this activity could lead to unauthorized access, allowing attackers to compromise user accounts and potentially escalate their privileges within the environment.
Show query
`azure_monitor_aad` category=SignInLogs operationName="Sign-in activity" properties.status.errorCode=500121 properties.status.additionalDetails!="MFA denied; user declined the authentication"
| rename properties.* as *
| bucket span=10m _time
| rename userAgent as user_agent
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime values(dest) as dest values(src) as src
BY user, status.additionalDetails, appDisplayName,
user_agent, vendor_account, vendor_product,
signature
| where count > 10
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `azure_ad_multiple_failed_mfa_requests_for_user_filter`Azure AD Multiple Service Principals Created by SP
The following analytic detects when a single service principal in Azure AD creates more than three unique OAuth applications within a 10-minute span. It leverages Azure AD audit logs, specifically monitoring the 'Add service principal' operation initiated by service principals. This behavior is significant as it may indicate an attacker using a compromised or malicious service principal to rapidly establish multiple service principals, potentially staging an attack. If confirmed malicious, this activity could facilitate network infiltration or expansion, allowing the attacker to gain unauthorized access and persist within the environment.
Show query
`azure_monitor_aad` operationName="Add service principal" properties.initiatedBy.app.appId=*
| rename properties.* as *
| bucket span=10m _time
| rename targetResources{}.displayName as displayName
| rename targetResources{}.type as type
| rename initiatedBy.app.displayName as src_user
| rename userAgent as user_agent
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime dc(displayName) as unique_apps values(displayName) as displayName values(dest) as dest values(src) as src values(user) as user values(user_agent) as user_agent
BY src_user vendor_account vendor_product
signature
| where unique_apps > 3
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `azure_ad_multiple_service_principals_created_by_sp_filter`Azure AD Multiple Service Principals Created by User
The following analytic identifies instances where a single user creates more than three unique OAuth applications within a 10-minute timeframe in Azure AD. It detects this activity by monitoring the 'Add service principal' operation and aggregating data in 10-minute intervals. This behavior is significant as it may indicate an adversary rapidly creating multiple service principals to stage an attack or expand their foothold within the network. If confirmed malicious, this activity could allow attackers to establish persistence, escalate privileges, or access sensitive information within the Azure environment.
Show query
`azure_monitor_aad` operationName="Add service principal" properties.initiatedBy.user.id=*
| rename properties.* as *
| bucket span=10m _time
| rename targetResources{}.displayName as displayName
| rename userAgent as user_agent
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime dc(displayName) as unique_apps values(displayName) as displayName values(dest) as dest values(src) as src values(user) as user values(user_agent) as user_agent
BY src_user vendor_account vendor_product
signature
| where unique_apps > 3
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `azure_ad_multiple_service_principals_created_by_user_filter`Azure AD Privileged Authentication Administrator Role Assigned
The following analytic detects the assignment of the Privileged Authentication Administrator role to an Azure AD user. It leverages Azure Active Directory audit logs to identify when this specific role is assigned. This activity is significant because users in this role can set or reset authentication methods for any user, including those in privileged roles like Global Administrators. If confirmed malicious, an attacker could change credentials and assume the identity and permissions of high-privilege users, potentially leading to unauthorized access to sensitive information and critical configurations.
Show query
`azure_monitor_aad` "operationName"="Add member to role" "properties.targetResources{}.modifiedProperties{}.newValue"="\"Privileged Authentication Administrator\""
| rename properties.* as *
| rename initiatedBy.user.userPrincipalName as initiatedBy
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY dest user src
vendor_account vendor_product initiatedBy
signature
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `azure_ad_privileged_authentication_administrator_role_assigned_filter`Azure AD Privileged Graph API Permission Assigned
The following analytic detects the assignment of high-risk Graph API permissions in Azure AD, specifically Application.ReadWrite.All, AppRoleAssignment.ReadWrite.All, and RoleManagement.ReadWrite.Directory. It uses azure_monitor_aad data to scan AuditLogs for 'Update application' operations, identifying when these permissions are assigned. This activity is significant as it grants broad control over Azure AD, including application and directory settings. If confirmed malicious, it could lead to unauthorized modifications and potential security breaches, compromising the integrity and security of the Azure AD environment. Immediate investigation is required.
Show query
`azure_monitor_aad` category=AuditLogs operationName="Update application" | eval newvalue = mvindex('properties.targetResources{}.modifiedProperties{}.newValue',0) | spath input=newvalue | search "{}.RequiredAppPermissions{}.EntitlementId"=" 1bfefb4e-e0b5-418b-a88f-73c46d2cc8e9" OR "{}.RequiredAppPermissions{}.EntitlementId" ="06b708a9-e830-4db3-a914-8e69da51d44f" OR "{}.RequiredAppPermissions{}.EntitlementId" ="9e3f62cf-ca93-4989-b6ce-bf83c28f9fe8" | eval Permissions = '{}.RequiredAppPermissions{}.EntitlementId' | fillnull | stats count min(_time) as firstTime max(_time) as lastTime by dest user src vendor_account vendor_product Permissions signature | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `azure_ad_privileged_graph_api_permission_assigned_filter`Azure AD Service Principal Authentication
The following analytic identifies authentication events of service principals in Azure Active Directory. It leverages the `azure_monitor_aad` data source, specifically targeting "Sign-in activity" within ServicePrincipalSignInLogs. This detection gathers details such as sign-in frequency, timing, source IPs, and accessed resources. Monitoring these events is significant for SOC teams to distinguish between normal application authentication and potential anomalies, which could indicate compromised credentials or malicious activities. If confirmed malicious, attackers could gain unauthorized access to resources, leading to data breaches or further exploitation within the environment.
Show query
`azure_monitor_aad` operationName="Sign-in activity" category=ServicePrincipalSignInLogs
| rename properties.* as *
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY dest user src
vendor_account vendor_product resourceDisplayName
resourceId signature
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `azure_ad_service_principal_authentication_filter`Showing 301-350 of 1,106