Merge pull request #2195 from Azure/pebryan/2021-4-8_HuntingTimeFrameFix
Pebryan/2021 4 8 hunting time frame fix
This commit is contained in:
Коммит
158019e9f6
|
@ -17,9 +17,7 @@ relevantTechniques:
|
|||
- T1484
|
||||
query: |
|
||||
|
||||
let timeframe = 7d;
|
||||
AWSCloudTrail
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where EventName in~ ("AttachGroupPolicy", "AttachRolePolicy", "AttachUserPolicy", "CreatePolicy",
|
||||
"DeleteGroupPolicy", "DeletePolicy", "DeleteRolePolicy", "DeleteUserPolicy", "DetachGroupPolicy",
|
||||
"PutUserPolicy", "PutGroupPolicy", "CreatePolicyVersion", "DeletePolicyVersion", "DetachRolePolicy", "CreatePolicy")
|
||||
|
|
|
@ -16,10 +16,8 @@ relevantTechniques:
|
|||
- T1098
|
||||
query: |
|
||||
|
||||
let timeframe = 1d;
|
||||
// Creating separate table for RemoveRoleToInstanceProfile
|
||||
let RemoveRole=AWSCloudTrail
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where EventName in~ ("RemoveRoleFromInstanceProfile") and isempty(ErrorMessage)
|
||||
| extend RoleRemoved = tostring(parse_json(RequestParameters).roleName), InstanceProfileName = tostring(parse_json(RequestParameters).instanceProfileName), TimeRemoved=TimeGenerated
|
||||
| extend UserIdentityUserName = iff(isnotempty(UserIdentityUserName), UserIdentityUserName, tostring(split(UserIdentityArn,'/')[-1]))
|
||||
|
@ -27,7 +25,6 @@ query: |
|
|||
SourceIpAddress, AWSRegion, EventSource, RoleRemoved, InstanceProfileName;
|
||||
// Creating separate table for AddRoleToInstanceProfile
|
||||
let AddRole=AWSCloudTrail
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where EventName in~ ("AddRoleToInstanceProfile") and isempty(ErrorMessage)
|
||||
| extend UserIdentityUserName = iff(isnotempty(UserIdentityUserName), UserIdentityUserName, tostring(split(UserIdentityArn,'/')[-1]))
|
||||
| extend RoleAdded = tostring(parse_json(RequestParameters).roleName), InstanceProfileName = tostring(parse_json(RequestParameters).instanceProfileName), TimeAdded=TimeGenerated
|
||||
|
|
|
@ -23,11 +23,9 @@ tactics:
|
|||
relevantTechniques:
|
||||
- T1550.001
|
||||
query: |
|
||||
let auditLookback = 1d;
|
||||
// Include your additions to the allow list below as needed
|
||||
let AllowedUserList = dynamic(["Microsoft Cloud App Security","ADConnectSyncAccount1","SyncAccount2"]);
|
||||
AuditLogs
|
||||
| where TimeGenerated > ago(auditLookback)
|
||||
| where OperationName has 'StsRefreshTokenValidFrom'
|
||||
| where TargetResources[0].modifiedProperties != '[]'
|
||||
| where TargetResources[0].modifiedProperties !has 'DirectorySync'
|
||||
|
|
|
@ -13,11 +13,9 @@ relevantTechniques:
|
|||
- T1496
|
||||
query: |
|
||||
|
||||
let timeframe = 1d;
|
||||
let opValues = dynamic(["Microsoft.SecurityInsights/alertRules/write", "Microsoft.SecurityInsights/alertRules/delete"]);
|
||||
// Azure Sentinel Analytics - Rule Create / Update / Delete
|
||||
AzureActivity
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where Category == "Administrative"
|
||||
| where OperationNameValue in (opValues)
|
||||
| where ActivitySubstatusValue in ("Created", "OK")
|
||||
|
|
|
@ -19,14 +19,11 @@ relevantTechniques:
|
|||
- T1087
|
||||
query: |
|
||||
|
||||
let timeframe = 7d;
|
||||
AzureActivity
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where OperationName == "List Storage Account Keys"
|
||||
| where ActivityStatus == "Succeeded"
|
||||
| join kind= inner (
|
||||
AzureActivity
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where OperationName == "List Storage Account Keys"
|
||||
| where ActivityStatus == "Succeeded"
|
||||
| project ExpectedIpAddress=CallerIpAddress, Caller
|
||||
|
|
|
@ -15,7 +15,6 @@ relevantTechniques:
|
|||
query: |
|
||||
|
||||
AzureActivity
|
||||
| where TimeGenerated >= ago(1d)
|
||||
| where ActivityStatusValue == "Succeeded"
|
||||
| where ResourceGroup has "cloud-shell-storage"
|
||||
| where OperationNameValue == "Microsoft.Storage/storageAccounts/listKeys/action"
|
||||
|
|
|
@ -18,7 +18,6 @@ query: |
|
|||
let IP_Data = (externaldata(network:string)
|
||||
[@"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Sample%20Data/Feeds/VPS_Networks.csv"] with (format="csv"));
|
||||
AzureActivity
|
||||
| where TimeGenerated > ago(3d)
|
||||
| where CategoryValue =~ "Administrative"
|
||||
| evaluate ipv4_lookup(IP_Data, CallerIpAddress, network, return_unmatched = false)
|
||||
| summarize Operations = make_set(OperationNameValue), StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by CallerIpAddress, Caller
|
||||
|
|
|
@ -13,11 +13,9 @@ relevantTechniques:
|
|||
- T1496
|
||||
query: |
|
||||
|
||||
let timeframe = 1d;
|
||||
let opValues = dynamic(["Microsoft.Network/networkSecurityGroups/write", "Microsoft.Network/networkSecurityGroups/delete"]);
|
||||
// Azure NSG Create / Update / Delete
|
||||
AzureActivity
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where Category == "Administrative"
|
||||
| where OperationNameValue in (opValues)
|
||||
| where ActivitySubstatusValue in ("Created", "OK")
|
||||
|
|
|
@ -13,11 +13,9 @@ relevantTechniques:
|
|||
- T1496
|
||||
query: |
|
||||
|
||||
let timeframe = 1d;
|
||||
let opValues = dynamic(["Microsoft.SecurityInsights/dataConnectors/write", "Microsoft.SecurityInsights/dataConnectors/delete"]);
|
||||
// Azure Sentinel Data Connectors Update / Delete
|
||||
AzureActivity
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where Category == "Administrative"
|
||||
| where OperationNameValue in (opValues)
|
||||
| where ActivitySubstatusValue in ("Created", "OK")
|
||||
|
|
|
@ -13,11 +13,9 @@ relevantTechniques:
|
|||
- T1496
|
||||
query: |
|
||||
|
||||
let timeframe = 1d;
|
||||
let opValues = dynamic(["microsoft.insights/workbooks/write", "microsoft.insights/workbooks/delete"]);
|
||||
// Azure Sentinel Workbook Create / Update / Delete
|
||||
AzureActivity
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where Category == "Administrative"
|
||||
| where OperationNameValue in (opValues)
|
||||
| where ActivitySubstatusValue in ("Created", "OK")
|
||||
|
|
|
@ -14,9 +14,7 @@ relevantTechniques:
|
|||
- T1496
|
||||
query: |
|
||||
|
||||
let timeframe = 7d;
|
||||
AzureActivity
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where OperationName == "Create or Update Virtual Machine" or OperationName == "Create Deployment"
|
||||
| where ActivityStatus == "Succeeded"
|
||||
| project Resource, ResourceGroup
|
||||
|
|
|
@ -13,9 +13,7 @@ relevantTechniques:
|
|||
- T1496
|
||||
query: |
|
||||
|
||||
let timeframe = 7d;
|
||||
AzureActivity
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where OperationName == "Create or Update Virtual Machine" or OperationName == "Create Deployment"
|
||||
| where ActivityStatus == "Succeeded"
|
||||
| make-series dcount(ResourceId) default=0 on EventSubmissionTimestamp in range(ago(7d), now(), 1d) by Caller
|
||||
|
|
|
@ -14,15 +14,12 @@ relevantTechniques:
|
|||
- T1098
|
||||
query: |
|
||||
|
||||
let timeframe = 7d;
|
||||
AzureActivity
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where OperationName == "Create role assignment"
|
||||
| where ActivityStatus == "Succeeded"
|
||||
| project Caller, CallerIpAddress
|
||||
| evaluate basket()
|
||||
| join kind=leftouter (AzureActivity
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where OperationName == "Create role assignment"
|
||||
| where ActivityStatus == "Succeeded"
|
||||
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by Caller, CallerIpAddress)
|
||||
|
|
|
@ -15,9 +15,7 @@ relevantTechniques:
|
|||
- T1496
|
||||
query: |
|
||||
|
||||
let timeframe = 7d;
|
||||
AzureActivity
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where OperationName has_any ("Create", "Update") and OperationName has_any ("Ip", "Security Rule")
|
||||
// Choosing Accepted here because it has the Rule Attributes included
|
||||
| where ActivityStatus == "Accepted"
|
||||
|
|
|
@ -13,9 +13,7 @@ relevantTechniques:
|
|||
- T1098
|
||||
- T1089
|
||||
query: |
|
||||
let timeframe = 7d;
|
||||
AzureDevOpsAuditing
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where OperationName =="OrganizationPolicy.PolicyValueUpdated"
|
||||
| where Data.PolicyName == "Policy.EnforceAADConditionalAccess"
|
||||
| where Data.PolicyValue == "OFF"
|
||||
|
|
|
@ -8,16 +8,13 @@ tactics:
|
|||
relevantTechniques:
|
||||
- T1195
|
||||
query: |
|
||||
let timeframe = 30d;
|
||||
let alert_threshold = 0;
|
||||
AzureDevOpsAuditing
|
||||
| where TimeGenerated > ago(timeframe)
|
||||
| where OperationName matches regex "Artifacts.Feed.(Org|Project).Create"
|
||||
| extend FeedName = tostring(Data.FeedName)
|
||||
| extend FeedId = tostring(Data.FeedId)
|
||||
| join kind = leftouter (
|
||||
SecurityAlert
|
||||
| where TimeGenerated > ago(timeframe)
|
||||
| where ProviderName == "IPC"
|
||||
| extend AadUserId = tostring(parse_json(Entities)[0].AadUserId)
|
||||
| summarize Alerts=count() by AadUserId) on $left.ActorUserId == $right.AadUserId
|
||||
|
|
|
@ -8,14 +8,11 @@ tactics:
|
|||
relevantTechniques:
|
||||
- T1578
|
||||
query: |
|
||||
let timeframe = 7d;
|
||||
AzureDevOpsAuditing
|
||||
| where TimeGenerated > ago(timeframe)
|
||||
| where OperationName =~ "Library.VariableGroupModified"
|
||||
| extend variables = Data.Variables
|
||||
| extend VariableGroupName = tostring(Data.VariableGroupName)
|
||||
| join (AzureDevOpsAuditing
|
||||
| where TimeGenerated > ago(timeframe)
|
||||
| where OperationName =~ "Library.VariableGroupModified"
|
||||
| extend variables = Data.Variables
|
||||
| extend VariableGroupName = tostring(Data.VariableGroupName)) on VariableGroupName
|
||||
|
|
|
@ -13,9 +13,7 @@ relevantTechniques:
|
|||
- T1098
|
||||
- T1089
|
||||
query: |
|
||||
let timeframe = 7d;
|
||||
AzureDevOpsAuditing
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where OperationName == "Group.UpdateGroupMembership.Add"
|
||||
| where Category == "Modify"
|
||||
| where Area == "Group"
|
||||
|
|
|
@ -14,9 +14,7 @@ relevantTechniques:
|
|||
- T1036
|
||||
query: |
|
||||
|
||||
let timeframe = 14d;
|
||||
AzureDevOpsAuditing
|
||||
| where TimeGenerated > ago(timeframe)
|
||||
| where ActorCUID != '00000000-0000-0000-0000-000000000000' and ActorDisplayName != "Azure DevOps User"
|
||||
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), DisplayNameCount = dcount(ActorDisplayName), ActorDisplayNames = make_set(ActorDisplayName), make_set(IpAddress), make_set(ProjectName) by ActorCUID, ActorUPN
|
||||
| where DisplayNameCount > 1
|
||||
|
|
|
@ -12,8 +12,6 @@ relevantTechniques:
|
|||
- T1098
|
||||
query: |
|
||||
|
||||
let timeframe = 7d;
|
||||
AzureDevOpsAuditing
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where OperationName == 'Git.RefUpdatePoliciesBypassed'
|
||||
| extend timestamp = TimeGenerated, AccountCustomEntity = ActorUPN, IPCustomEntity = IpAddress
|
|
@ -13,9 +13,7 @@ relevantTechniques:
|
|||
- T1098
|
||||
- T1089
|
||||
query: |
|
||||
let timeframe = 7d;
|
||||
AzureDevOpsAuditing
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where OperationName =="OrganizationPolicy.PolicyValueUpdated"
|
||||
| where Data.PolicyName == "Policy.DisallowAadGuestUserAccess"
|
||||
| where Data.PolicyValue == "OFF"
|
||||
|
|
|
@ -11,9 +11,7 @@ tactics:
|
|||
relevantTechniques:
|
||||
- T1213
|
||||
query: |
|
||||
let timeframe = 7d;
|
||||
AzureDevOpsAuditing
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where Area == "Project"
|
||||
| where OperationName == "Project.UpdateVisibilityCompleted"
|
||||
| where Data.PreviousProjectVisibility == "private"
|
||||
|
|
|
@ -13,9 +13,7 @@ relevantTechniques:
|
|||
- T1098
|
||||
- T1089
|
||||
query: |
|
||||
let timeframe = 7d;
|
||||
AzureDevOpsAuditing
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where OperationName == "OrganizationPolicy.PolicyValueUpdated"
|
||||
| where Data.PolicyName == "Policy.AllowAnonymousAccess"
|
||||
| where Data.PolicyValue == "ON"
|
||||
|
|
|
@ -13,9 +13,7 @@ relevantTechniques:
|
|||
- T1098
|
||||
- T1089
|
||||
query: |
|
||||
let timeframe = 7d;
|
||||
AzureDevOpsAuditing
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where Data.ProjectVisibility == "Public"
|
||||
| where OperationName == "Project.CreateCompleted"
|
||||
| extend timestamp = TimeGenerated, AccountCustomEntity = ActorUPN, IPCustomEntity = IpAddress
|
||||
|
|
|
@ -14,7 +14,6 @@ tags:
|
|||
query: |
|
||||
|
||||
let threshold = 5m;
|
||||
let timeRange = 15d;
|
||||
//Union the file and blob data
|
||||
let StorageData =
|
||||
union
|
||||
|
@ -22,7 +21,6 @@ query: |
|
|||
StorageBlobLogs;
|
||||
//Get file and blob uploads
|
||||
StorageData
|
||||
| where TimeGenerated > ago(timeRange)
|
||||
//File upload operations
|
||||
| where StatusText =~ "Success"
|
||||
| where OperationName =~ "PutBlob" or OperationName =~ "PutRange"
|
||||
|
@ -30,8 +28,7 @@ query: |
|
|||
| extend Uri = tostring(split(Uri, "?", 0)[0])
|
||||
//Join with deletions, this will return 0 rows if there was no deletion
|
||||
| join (
|
||||
StorageData
|
||||
|where TimeGenerated > ago(timeRange)
|
||||
StorageData
|
||||
//File deletion operations
|
||||
| where OperationName =~ "DeleteBlob" or OperationName =~ "DeleteFile"
|
||||
| extend Uri = tostring(split(Uri, "?", 0)[0])
|
||||
|
@ -42,7 +39,6 @@ query: |
|
|||
| join (
|
||||
StorageData
|
||||
|where Category =~ "StorageRead"
|
||||
|where TimeGenerated > ago(timeRange)
|
||||
//File download events
|
||||
| where OperationName =~ "GetBlob" or OperationName =~ "GetFile"
|
||||
//Again, parse the URI to remove the parameters as they change per request
|
||||
|
|
|
@ -15,19 +15,16 @@ tags:
|
|||
query: |
|
||||
|
||||
let threshold = 5m;
|
||||
let timerange = 7d;
|
||||
let StorageData =
|
||||
union
|
||||
StorageFileLogs,
|
||||
StorageBlobLogs;
|
||||
StorageData
|
||||
| where TimeGenerated > ago(timerange)
|
||||
| where StatusText =~ "Success"
|
||||
| where OperationName =~ "PutBlob" or OperationName =~ "PutRange"
|
||||
| extend Uri = tostring(split(Uri, "?", 0)[0])
|
||||
| join (
|
||||
StorageData
|
||||
| where TimeGenerated > ago(timerange)
|
||||
| where StatusText =~ "Success"
|
||||
| where OperationName =~ "DeleteBlob" or OperationName =~ "DeleteFile"
|
||||
| extend Uri = tostring(split(Uri, "?", 0)[0])
|
||||
|
|
|
@ -16,7 +16,6 @@ query: |
|
|||
|
||||
union StorageFileLogs,
|
||||
StorageBlobLogs
|
||||
| where TimeGenerated > ago(7d)
|
||||
//File upload operations
|
||||
| where OperationName =~ "PutBlob" or OperationName =~ "PutRange"
|
||||
//Parse out the uploader IP
|
||||
|
@ -35,7 +34,6 @@ query: |
|
|||
| project-away list_hexChar, ResponseMd5
|
||||
| join (
|
||||
DeviceFileEvents
|
||||
| where TimeGenerated > ago(7d)
|
||||
| where ActionType =~ "FileCreated"
|
||||
| where isnotempty(MD5)
|
||||
| extend p = pack("FileCreateTime", TimeGenerated, "Device", DeviceName, "DeviceId", DeviceId, "FileName", FileName, "InititatingProcess", InitiatingProcessFileName)
|
||||
|
|
|
@ -19,7 +19,6 @@ query: |
|
|||
union
|
||||
StorageFileLogs,
|
||||
StorageBlobLogs
|
||||
| where TimeGenerated > ago(3d)
|
||||
| where StatusText =~ "Success"
|
||||
| where OperationName =~ "DeleteBlob" or OperationName =~ "DeleteFile"
|
||||
| extend CallerIpAddress = tostring(split(CallerIpAddress, ":", 0)[0])
|
||||
|
|
|
@ -17,7 +17,6 @@ query: |
|
|||
union
|
||||
StorageFileLogs,
|
||||
StorageBlobLogs
|
||||
| where TimeGenerated > ago(7d)
|
||||
//File upload operations
|
||||
| where StatusText =~ "Success"
|
||||
| where OperationName =~ "PutBlob" or OperationName =~ "PutRange"
|
||||
|
|
|
@ -15,14 +15,12 @@ tags:
|
|||
- Ignite2021
|
||||
query: |
|
||||
|
||||
let TimeRange = 7d;
|
||||
//Period of time to look back in signin logs
|
||||
let lookback = 1m;
|
||||
let TargetFile = "mimikatz.exe"; //Example
|
||||
union
|
||||
StorageFileLogs,
|
||||
StorageBlobLogs
|
||||
| where TimeGenerated > ago(TimeRange)
|
||||
//Collect file uploads
|
||||
| where StatusText =~ "Success"
|
||||
| where OperationName =~ "PutBlob" or OperationName =~ "PutRange"
|
||||
|
@ -35,7 +33,6 @@ query: |
|
|||
| extend WindowStart = FileUploadTime - lookback
|
||||
| join (
|
||||
SigninLogs
|
||||
| where TimeGenerated > ago(TimeRange)
|
||||
| project AzureLoginTime=TimeGenerated, UserPrincipalName, IPAddress, LoginUserAgent=UserAgent
|
||||
) on $left.CallerIpAddress == $right.IPAddress
|
||||
//Look back in the signinlogs for the most recent login
|
||||
|
|
|
@ -18,11 +18,9 @@ relevantTechniques:
|
|||
- T1048
|
||||
query: |
|
||||
|
||||
let timeframe = 7d;
|
||||
// Add additional TLDs to this list are reuqired.
|
||||
// Add additional TLDs to this list are required.
|
||||
let abusedTLD = dynamic(["click", "club", "download", "xxx", "xyz"]);
|
||||
DnsEvents
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where Name has "."
|
||||
| extend tld = tostring(split(Name, ".")[-1])
|
||||
| where tld in~ (abusedTLD)
|
||||
|
|
|
@ -12,10 +12,8 @@ relevantTechniques:
|
|||
- T1046
|
||||
query: |
|
||||
|
||||
let timeframe = 1d;
|
||||
let threshold = 10;
|
||||
DnsEvents
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where Name contains "in-addr.arpa"
|
||||
| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), NameCount = dcount(Name), Names = make_set(Name), ClientIPCount = count() by ClientIP
|
||||
| where NameCount > threshold
|
||||
|
|
|
@ -19,19 +19,18 @@ relevantTechniques:
|
|||
- T1048
|
||||
query: |
|
||||
|
||||
let timeframe = 1d;
|
||||
// Setting URI length threshold count, shorter URI's may cause noise, change as needed
|
||||
let uriThreshold = 150;
|
||||
let LocalDomains =
|
||||
(
|
||||
DnsEvents | where TimeGenerated >= ago(1d)
|
||||
DnsEvents
|
||||
| summarize count() by Computer
|
||||
| extend SubDomain = tolower(strcat(tostring(split(Computer, ".")[-2]),".", tostring(split(Computer, ".")[-1])))
|
||||
| distinct SubDomain
|
||||
);
|
||||
let DomainLookups =
|
||||
(
|
||||
DnsEvents | where TimeGenerated >= ago(1d)
|
||||
DnsEvents
|
||||
| where SubType =~ "LookupQuery"
|
||||
| where ipv4_is_match("127.0.0.1", ClientIP) == False
|
||||
| where Name !endswith ".local" and Name !startswith "_" and Name !startswith "#"
|
||||
|
|
|
@ -16,7 +16,6 @@ relevantTechniques:
|
|||
- T1496
|
||||
query: |
|
||||
|
||||
let timeframe = 1d;
|
||||
let badDomains = dynamic(["agrdwrtj.us", "bctxawdt.us", "cokfqwjmferc.us", "cxbenjiikmhjcerbj.us", "depuisgef.us", "edoknehyvbl.us",
|
||||
"enyeikruptiukjorq.com", "frullndjtkojlu.us", "gcidpiuvamynj.us", "gxrytjoclpvv.us", "hanoluexjqcf.us", "iarirjjrnuornts.us",
|
||||
"ifbjoosjqhaeqjjwaerri.us", "iouenviwrc.us", "kuuelejkfwk.us", "lkbsxkitgxttgaobxu.us", "nnnlafqfnrbynwor.us", "ns768.com",
|
||||
|
@ -24,7 +23,6 @@ query: |
|
|||
"ryitsfeogisr.us", "srwcjdfrtnhnjekjerl.us", "thstlufnunxaksr.us", "udrgtaxgdyv.us", "w5q7spejg96n.com", "xmqlcikldft.us",
|
||||
"yobvyjmjbsgdfqnh.us", "yrwgugricfklb.us", "ywpvqhlqnssecpdemq.us"]);
|
||||
DnsEvents
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where Name in~ (badDomains)
|
||||
| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), count() by Computer, ClientIP, WannaCrypt_Related_Domain = Name
|
||||
| extend timestamp = StartTimeUtc, HostCustomEntity = Computer, IPCustomEntity = ClientIP
|
||||
|
|
|
@ -22,7 +22,6 @@ query: |
|
|||
let dictionary = dynamic(["r","q","3","g","s","a","l","t","6","u","1","i","y","f","z","o","p","5","7","2","d","4","9","b","n","x","8","c","v","m","k","e","w","h","j"]);
|
||||
let regex_bad_domains = SigninLogs
|
||||
//Collect domains from tenant from signin logs
|
||||
| where TimeGenerated > ago(1d)
|
||||
| extend domain = tostring(split(UserPrincipalName, "@", 1)[0])
|
||||
| where domain != ""
|
||||
| summarize by domain
|
||||
|
@ -50,7 +49,6 @@ query: |
|
|||
//Key to join to DNS
|
||||
| extend key = 1;
|
||||
DnsEvents
|
||||
| where TimeGenerated > ago(1d)
|
||||
| summarize by Name
|
||||
| extend key = 1
|
||||
//For each DNS query join the malicious domain list
|
||||
|
|
|
@ -11,8 +11,6 @@ relevantTechniques:
|
|||
- T1089
|
||||
query: |
|
||||
|
||||
let timeframe = 14d;
|
||||
GitHubAudit
|
||||
| where TimeGenerated > ago(timeframe)
|
||||
| where Action == "org.disable_oauth_app_restrictions"
|
||||
| project TimeGenerated, Action, Actor, Country
|
||||
|
|
|
@ -9,9 +9,7 @@ relevantTechniques:
|
|||
- T1213
|
||||
query: |
|
||||
|
||||
let timeframe = 14d;
|
||||
GitHubAudit
|
||||
| where TimeGenerated > ago(timeframe)
|
||||
| where Action == "repo.access"
|
||||
| where OperationType == "MODIFY"
|
||||
| where Visibility == "PUBLIC"
|
||||
|
|
|
@ -9,22 +9,18 @@ relevantTechniques:
|
|||
- T1537
|
||||
query: |
|
||||
|
||||
let RunTime = 1h;
|
||||
let CollaboratorsUserToRepoMapping = (
|
||||
GitHubRepo
|
||||
| where TimeGenerated < ago(RunTime)
|
||||
| where Action == "Collaborators"
|
||||
| distinct Repository , Actor, Organization);
|
||||
let UserCommitsInRepoMapping = (
|
||||
GitHubRepo
|
||||
| where Action == "Commits"
|
||||
| where TimeGenerated < ago(RunTime)
|
||||
| distinct Repository ,Actor, Organization);
|
||||
union CollaboratorsUserToRepoMapping, UserCommitsInRepoMapping
|
||||
| summarize ContributedToRepos = make_set(Repository) by Actor, Organization
|
||||
| join kind=innerunique (
|
||||
GitHubRepo
|
||||
| where TimeGenerated > ago(RunTime)
|
||||
| where Action == "Forks"
|
||||
| distinct Repository , Actor, Organization
|
||||
) on Actor, Organization
|
||||
|
|
|
@ -15,15 +15,12 @@ query: |
|
|||
|
||||
let UI_apps = dynamic(['ASI_Portal','AzureMonitorLogsConnector','AppAnalytics']);
|
||||
let threshold = 3;
|
||||
let timeframe = 1d;
|
||||
LAQueryLogs
|
||||
| where TimeGenerated > ago(timeframe)
|
||||
| where (ResponseRowCount == 10001 and RequestClientApp in(UI_apps)) or (ResponseRowCount > 10001 and RequestClientApp !in(UI_apps))
|
||||
| summarize count() by AADEmail
|
||||
| where count_ > threshold
|
||||
| join kind=rightsemi (
|
||||
LAQueryLogs
|
||||
| where TimeGenerated > ago(timeframe)
|
||||
| where (ResponseRowCount == 10001 and RequestClientApp in(UI_apps)) or (ResponseRowCount > 10001 and RequestClientApp !in(UI_apps)))
|
||||
on AADEmail
|
||||
| extend timestamp = TimeGenerated, AccountCustomEntity = AADEmail
|
||||
|
|
|
@ -18,16 +18,13 @@ query: |
|
|||
// To exclude key phrases or tables to exclude add to these lists
|
||||
let table_exclusions = dynamic(["AuditLogs","SigninLogs", "LAQueryLogs", "SecurityEvent"]);
|
||||
let keyword_exclusion = dynamic(["reset user password", "change user password"]);
|
||||
let timeframe = 7d;
|
||||
LAQueryLogs
|
||||
| where TimeGenerated > ago(timeframe)
|
||||
| where RequestClientApp != 'Sentinel-General'
|
||||
| extend querytext_lower = tolower(QueryText)
|
||||
| where querytext_lower has_any(keywords)
|
||||
| project TimeGenerated, AADEmail, QueryText, RequestClientApp, RequestTarget, ResponseCode, ResponseRowCount, ResponseDurationMs, CorrelationId
|
||||
| extend timestamp = TimeGenerated, AccountCustomEntity = AADEmail
|
||||
| join kind=leftanti ( LAQueryLogs
|
||||
| where TimeGenerated > ago(timeframe)
|
||||
| where RequestClientApp != 'Sentinel-General'
|
||||
| extend querytext_lower = tolower(QueryText)
|
||||
| where QueryText has_any(table_exclusions) or querytext_lower has_any(keyword_exclusion))
|
||||
|
|
|
@ -18,9 +18,7 @@ relevantTechniques:
|
|||
- T1496
|
||||
query: |
|
||||
|
||||
let timeframe = 7d;
|
||||
AzureActivity
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
// We look for any Operation that modified and then was accepted or succeeded where a publicipaddress component is referenced
|
||||
| where OperationName has_any ("Create", "Update", "Delete")// Virtual Machine" or OperationName == "Create Deployment"
|
||||
| where ActivityStatus has_any ("Succeeded", "Accepted")
|
||||
|
@ -37,7 +35,6 @@ query: |
|
|||
| join kind= inner (
|
||||
union isfuzzy=true
|
||||
(AzureNetworkAnalytics_CL
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
// Controlling for Schema Version and later parsing - This is Version 2 and Public IPs only
|
||||
| where isnotempty(FASchemaVersion_s) and isnotempty(DestPublicIPs_s)
|
||||
| extend SchemaVersion = FASchemaVersion_s
|
||||
|
@ -51,8 +48,7 @@ query: |
|
|||
| extend NSG_Name = tostring(split(NSG, "/")[-1])
|
||||
),
|
||||
(
|
||||
AzureNetworkAnalytics_CL
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
AzureNetworkAnalytics_CL
|
||||
// Controlling for Schema Version and later parsing - This is Version 1
|
||||
| where isempty(FASchemaVersion_s)
|
||||
// Controlling for public IPs only
|
||||
|
|
|
@ -18,17 +18,14 @@ relevantTechniques:
|
|||
- T1008
|
||||
query: |
|
||||
|
||||
let timeframe = 1d;
|
||||
let badNames = dynamic(["aaa.stage.", "post.1"]);
|
||||
(union isfuzzy=true
|
||||
(DnsEvents
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
(DnsEvents
|
||||
| where Name has_any (badNames)
|
||||
| extend Domain = Name, SourceIp = ClientIP, RemoteIP = todynamic(IPAddresses)
|
||||
| mvexpand RemoteIP
|
||||
| extend RemoteIP = tostring(RemoteIP)),
|
||||
(VMConnection
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where isnotempty(RemoteDnsCanonicalNames)
|
||||
| parse RemoteDnsCanonicalNames with * '["' DNSName '"]' *
|
||||
| where DNSName has_any (badNames)
|
||||
|
|
|
@ -14,12 +14,9 @@ relevantTechniques:
|
|||
- T1071.001
|
||||
query: |
|
||||
|
||||
let lookback = 7d;
|
||||
let domainLookback = 7d;
|
||||
let domainCountThreshold = 100; //Maxiumum number of times a domain ahs been visited
|
||||
//Backdoor.HTTP.BEACON.[Yelp GET]
|
||||
let FEQuery1 = CommonSecurityLog
|
||||
| where TimeGenerated > ago(lookback)
|
||||
| where RequestMethod == "GET"
|
||||
| where RequestURL contains "&parent_request_id="
|
||||
| where RequestURL matches regex @"&parent_request_id=(?:[A-Za-z0-9_\/\+\-\%]{128,1000})={0,2}[^\r\n]{0,256}"
|
||||
|
@ -28,7 +25,6 @@ query: |
|
|||
| project TimeGenerated, Quality, RuleName, DeviceVendor, DeviceProduct, TenantId, SourceIP, DestinationIP, DestinationHostName, RequestMethod, RequestURL;
|
||||
//Backdoor.HTTP.BEACON.[CSBundle CDN GET]
|
||||
let FEQuery2 = CommonSecurityLog
|
||||
| where TimeGenerated > ago(lookback)
|
||||
| where RequestMethod == "GET"
|
||||
| where FileType =~ "GZIP"
|
||||
| where RequestURL matches regex @"(?:\/v1\/queue|\/v1\/profile|\/v1\/docs\/wsdl|\/v1\/pull)"
|
||||
|
@ -37,7 +33,6 @@ query: |
|
|||
| project TimeGenerated, Quality, RuleName, DeviceVendor, DeviceProduct, TenantId, SourceIP, DestinationIP, DestinationHostName, RequestMethod, RequestURL;
|
||||
//Backdoor.HTTP.BEACON.[CSBundle USAToday GET]
|
||||
let FEQuery3 = CommonSecurityLog
|
||||
| where TimeGenerated > ago(lookback)
|
||||
| where RequestMethod == "GET"
|
||||
| where isempty(RequestContext)
|
||||
| where RequestURL matches regex @"(?:\/USAT-GUP\/user\/|\/entertainment\/|\/entertainment\/navdd-q1a2z3Z6TET4gv2PNfXpaJAniOzOajK7M\.min\.json|\/global-q1a2z3C4M2nNlQYzWhCC0oMSEFjQbW1KA\.min\.json|\/life\/|\/news\/weather\/|\/opinion\/|\/sports\/|\/sports\/navdd-q1a2z3JHa8KzCRLOQAnDoVywVWF7UwxJs\.min\.json|\/tangstatic\/js\/main-q1a2z3b37df2b1\.min\.js|\/tangstatic\/js\/pbjsandwich-q1a2z300ab4198\.min\.js|\/tangstatic\/js\/pg-q1a2z3bbc110a4\.min\.js|\/tangsvc\/pg\/3221104001\/|\/ta`ngsvc\/pg\/5059005002\/|\/tangsvc\/pg\/5066496002\/|\/tech\/|\/travel\/)"
|
||||
|
@ -47,7 +42,6 @@ query: |
|
|||
| project TimeGenerated, Quality, RuleName, DeviceVendor, DeviceProduct, TenantId, SourceIP, DestinationIP, DestinationHostName, RequestMethod, RequestURL;
|
||||
//Backdoor.HTTP.BEACON.[CSBundle Original POST]
|
||||
let FEQuery4 = CommonSecurityLog
|
||||
| where TimeGenerated > ago(lookback)
|
||||
| where RequestMethod == "POST"
|
||||
| where isempty(RequestContext)
|
||||
| where RequestURL matches regex @"(?:\/v4\/links\/check-activity\/check|\/v1\/stats|\/gql|\/api2\/json\/check\/ticket|\/1.5\/95648064\/storage\/history|\/1.5\/95648064\/storage\/tabs|\/u\/0\/_\/og\/botguard\/get|\/ev\/prd001001|\/ev\/ext001001|\/gp\/aw\/ybh\/handlers|\/v3\/links\/ping-beat\/check)"
|
||||
|
@ -56,7 +50,6 @@ query: |
|
|||
| project TimeGenerated, Quality, RuleName, DeviceVendor, DeviceProduct, TenantId, SourceIP, DestinationIP, DestinationHostName, RequestMethod, RequestURL;
|
||||
//Backdoor.HTTP.BEACON.[CSBundle MSOffice POST
|
||||
let FEQuery5 = CommonSecurityLog
|
||||
| where TimeGenerated > ago(lookback)
|
||||
| where RequestMethod == "POST"
|
||||
| where isempty(RequestContext)
|
||||
| where RequestURL contains "/v1/push"
|
||||
|
@ -65,7 +58,6 @@ query: |
|
|||
| project TimeGenerated, Quality, RuleName, DeviceVendor, DeviceProduct, TenantId, SourceIP, DestinationIP, DestinationHostName, RequestMethod, RequestURL;
|
||||
//Backdoor.HTTP.BEACON.[CSBundle NYTIMES POST]
|
||||
let FEQuery6 = CommonSecurityLog
|
||||
| where TimeGenerated > ago(lookback)
|
||||
| where RequestMethod == "POST"
|
||||
| where isempty(RequestContext)
|
||||
| where RequestURL matches regex @"(?:\/track|\/api\/v1\/survey\/embed|\/svc\/weather\/v2)"
|
||||
|
@ -74,7 +66,6 @@ query: |
|
|||
| project TimeGenerated, Quality, RuleName, DeviceVendor, DeviceProduct, TenantId, SourceIP, DestinationIP, DestinationHostName, RequestMethod, RequestURL;
|
||||
//Backdoor.HTTP.BEACON.[CSBundle MSOffice GET]
|
||||
let FEQuery7 = CommonSecurityLog
|
||||
| where TimeGenerated > ago(lookback)
|
||||
| where RequestMethod == "GET"
|
||||
| where isempty(RequestContext)
|
||||
| where RequestURL matches regex @"(?:\/updates|\/license\/eula|\/docs\/office|\/software-activation)"
|
||||
|
@ -83,7 +74,6 @@ query: |
|
|||
| project TimeGenerated, Quality, RuleName, DeviceVendor, DeviceProduct, TenantId, SourceIP, DestinationIP, DestinationHostName, RequestMethod, RequestURL;
|
||||
//Backdoor.HTTP.BEACON.[CSBundle MSOffice POST]
|
||||
let FEQuery8 = CommonSecurityLog
|
||||
| where TimeGenerated > ago(lookback)
|
||||
| where RequestMethod == "POST"
|
||||
| where isempty(RequestContext)
|
||||
| where RequestURL contains "/notification"
|
||||
|
@ -92,7 +82,6 @@ query: |
|
|||
| project TimeGenerated, Quality, RuleName, DeviceVendor, DeviceProduct, TenantId, SourceIP, DestinationIP, DestinationHostName, RequestMethod, RequestURL;
|
||||
//Backdoor.HTTP.BEACON.[CSBundle Original GET]
|
||||
let FEQuery9 = CommonSecurityLog
|
||||
| where TimeGenerated > ago(lookback)
|
||||
| where RequestMethod == "GET"
|
||||
| where isempty(RequestContext)
|
||||
| where RequestURL matches regex @"(?:\/api2\/json\/access\/ticket|\/api2\/json\/cluster\/resources|\/api2\/json\/cluster\/tasks|\/en-us\/p\/onerf\/MeSilentPassport|\/en-us\/p\/book-2\/8MCPZJJCC98C|\/en-us\/store\/api\/checkproductinwishlist|\/gp\/cerberus\/gv|\/gp\/aj\/private\/reviewsGallery\/get-application-resources|\/gp\/aj\/private\/reviewsGallery\/get-image-gallery-assets|\/v1\/buckets\/default\/ext-5dkJ19tFufpMZjVJbsWCiqDcclDw\/records|\/v3\/links\/ping-centre|\/v4\/links\/activity-stream|\/wp-content\/themes\/am43-6\/dist\/records|\/wp-content\/themes\/am43-6\/dist\/records|\/wp-includes\/js\/script\/indigo-migrate)"
|
||||
|
@ -104,7 +93,6 @@ query: |
|
|||
Results
|
||||
| join (
|
||||
CommonSecurityLog
|
||||
| where TimeGenerated > ago(domainLookback)
|
||||
| where DestinationHostName != ""
|
||||
| summarize DomainCount=count() by DestinationHostName)
|
||||
on $left.DestinationHostName == $right.DestinationHostName
|
||||
|
|
|
@ -16,10 +16,8 @@ relevantTechniques:
|
|||
- T1078
|
||||
query: |
|
||||
|
||||
let timeframe = 1d;
|
||||
(union isfuzzy=true
|
||||
(SecurityEvent
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
(SecurityEvent
|
||||
| where EventID == 4625
|
||||
//4625: An account failed to log on
|
||||
| where AccountType == 'User'
|
||||
|
@ -30,8 +28,7 @@ query: |
|
|||
| project Computer, Account, Reason , TimeGenerated
|
||||
),
|
||||
(
|
||||
SecurityEvent
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
SecurityEvent
|
||||
| where EventID == 4769
|
||||
//4769: A Kerberos service ticket was requested ( Kerberos Auth)
|
||||
| parse EventData with * 'Status">' Status "<" *
|
||||
|
@ -46,7 +43,6 @@ query: |
|
|||
),
|
||||
(
|
||||
SecurityEvent
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where EventID == 4776
|
||||
// 4776: The domain controller attempted to validate the credentials for an account ( NTLM Auth)
|
||||
| where Status == "0xc0000193"
|
||||
|
@ -60,8 +56,7 @@ query: |
|
|||
| project Computer, Account, Reason , TimeGenerated
|
||||
) ,
|
||||
(
|
||||
SigninLogs
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
SigninLogs
|
||||
| where ResultType == "50057"
|
||||
| extend Reason =
|
||||
case(
|
||||
|
|
|
@ -18,11 +18,10 @@ relevantTechniques:
|
|||
- T1110
|
||||
query: |
|
||||
|
||||
let lookback = 1d;
|
||||
let fl_Min = 3;
|
||||
let un_MatchMin = 2;
|
||||
let upnFunc = (startTimeSpan:timespan, tableName:string){
|
||||
table(tableName) | where TimeGenerated >= ago(lookback)
|
||||
let upnFunc = (tableName:string){
|
||||
table(tableName)
|
||||
| extend Operation = columnifexists("Operation", "Sign-in activity")
|
||||
| where Operation == "UserLoginFailed" or Operation == "Sign-in activity"
|
||||
| extend Result = columnifexists("ResultType", "tempValue")
|
||||
|
@ -57,8 +56,8 @@ query: |
|
|||
| summarize UserNames = makeset(UserNameOnly),
|
||||
fl_Count = count() by bin(TimeGenerated, 10m), First4char, First6char, First8char, Last4char, Last6char, Last8char, Type
|
||||
};
|
||||
let SigninList = upnFunc(lookback,"SigninLogs");
|
||||
let OffActList = upnFunc(lookback,"OfficeActivity");
|
||||
let SigninList = upnFunc("SigninLogs");
|
||||
let OffActList = upnFunc("OfficeActivity");
|
||||
let UserNameList = (union isfuzzy=true SigninList, OffActList);
|
||||
let Char4List = UserNameList
|
||||
| project TimeGenerated, First4char, Last4char, UserNames, fl_Count, Type
|
||||
|
|
|
@ -31,11 +31,9 @@ query: |
|
|||
let regparams5 = dynamic(['reg add "HKLM\\SYSTEM\\CurrentControlSet\\services\\HealthService"', 'reg add "HKLM\\SYSTEM\\CurrentControlSet\\Services\\Sense"', 'reg add "HKLM\\SYSTEM\\CurrentControlSet\\Services\\WinDefend"', 'reg add "HKLM\\SYSTEM\\CurrentControlSet\\Services\\MsSecFlt"', 'reg add "HKLM\\SYSTEM\\CurrentControlSet\\Services\\DiagTrack"', 'reg add "HKLM\\SYSTEM\\CurrentControlSet\\Services\\SgrmBroker"', 'reg add "HKLMSYSTEM\\CurrentControlSet\\Services\\SgrmAgent"', 'reg add "HKLM\\SYSTEM\\CurrentControlSet\\Services\\AATPSensorUpdater"' , 'reg add "HKLM\\SYSTEM\\CurrentControlSet\\Services\\AATPSensor"', 'reg add "HKLM\\SYSTEM\\CurrentControlSet\\Services\\mpssvc"']);
|
||||
let regparams6 = dynamic(['/d 4','/d "4"','/d 0x00000004']);
|
||||
let regparams7 = dynamic(['/d 1','/d "1"','/d 0x00000001']);
|
||||
let timeframe = 1d;
|
||||
(union isfuzzy=true
|
||||
(
|
||||
SecurityEvent
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where EventID == 4688
|
||||
| extend ProcessName = tostring(split(NewProcessName, '\\')[-1])
|
||||
| where ProcessName in~ (includeProc)
|
||||
|
@ -49,14 +47,12 @@ query: |
|
|||
),
|
||||
(
|
||||
Event
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where Source =~ "Microsoft-Windows-SENSE"
|
||||
| where EventID == 87 and ParameterXml in ("<Param>sgrmbroker</Param>", "<Param>WinDefend</Param>")
|
||||
| project TimeGenerated, Computer, Account = UserName, EventID, Activity = RenderedDescription, EventSourceName = Source, Type
|
||||
),
|
||||
(
|
||||
DeviceProcessEvents
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where InitiatingProcessFileName in~ (includeProc)
|
||||
| where (InitiatingProcessCommandLine has_any(action) and InitiatingProcessCommandLine has_any (service2) and InitiatingProcessParentFileName != 'cscript.exe')
|
||||
or (InitiatingProcessCommandLine has_any (params1) and InitiatingProcessCommandLine has 'Set-MpPreference' and InitiatingProcessCommandLine has '$true')
|
||||
|
|
|
@ -28,10 +28,8 @@ query: |
|
|||
// Provide customLimit value with default above domainLimit value so it will not block unless changed
|
||||
let customLimit = 11;
|
||||
let domainLimit = 10;
|
||||
let lookback = 14d;
|
||||
let domainLookback = union isfuzzy=true
|
||||
(AuditLogs
|
||||
| where TimeGenerated >= ago(lookback)
|
||||
| extend UserPrincipalName = tolower(tostring(TargetResources.[0].userPrincipalName))
|
||||
// parse out AuditLog values for various locations where UPN could be
|
||||
| extend UserPrincipalName = iff(isnotempty(UserPrincipalName),
|
||||
|
@ -49,7 +47,6 @@ query: |
|
|||
//| where RareDomainCount <= customLimit
|
||||
),
|
||||
(OfficeActivity
|
||||
| where TimeGenerated >= ago(lookback)
|
||||
| extend UserPrincipalName = tolower(UserId)
|
||||
| where UserPrincipalName has "@" or UserPrincipalName startswith "NT AUTHORITY"
|
||||
| extend RareDomain = toupper(tostring(split(UserPrincipalName, "@")[-1]))
|
||||
|
@ -60,7 +57,6 @@ query: |
|
|||
//| where RareDomainCount <= customLimit
|
||||
),
|
||||
(SigninLogs
|
||||
| where TimeGenerated >= ago(lookback)
|
||||
| where UserPrincipalName has "@" or UserPrincipalName startswith "NT AUTHORITY"
|
||||
| extend RareDomain = toupper(tostring(split(UserPrincipalName, "@")[-1]))
|
||||
| summarize RareDomainCount = count() by Type, RareDomain
|
||||
|
@ -70,7 +66,6 @@ query: |
|
|||
);
|
||||
let AuditLogsRef = domainLookback | join (
|
||||
AuditLogs
|
||||
| where TimeGenerated >= ago(lookback)
|
||||
| extend UserPrincipalName = tolower(tostring(TargetResources.[0].userPrincipalName))
|
||||
| extend UserPrincipalName = iff(isempty(UserPrincipalName), tostring(InitiatedBy.user.userPrincipalName), UserPrincipalName)
|
||||
| extend RareDomain = toupper(tostring(split(UserPrincipalName, "@")[-1]))
|
||||
|
@ -80,7 +75,6 @@ query: |
|
|||
) on Type, RareDomain;
|
||||
let OfficeActivityRef = domainLookback | join (
|
||||
OfficeActivity
|
||||
| where TimeGenerated >= ago(lookback)
|
||||
| extend UserPrincipalName = tolower(UserId)
|
||||
| where UserPrincipalName has "@" or UserPrincipalName startswith "NT AUTHORITY"
|
||||
| extend RareDomain = toupper(tostring(split(UserPrincipalName, "@")[-1]))
|
||||
|
@ -89,7 +83,6 @@ query: |
|
|||
) on Type, RareDomain;
|
||||
let SigninLogsRef = domainLookback | join (
|
||||
SigninLogs
|
||||
| where TimeGenerated >= ago(lookback)
|
||||
| extend UserPrincipalName = tolower(UserId)
|
||||
| where UserPrincipalName has "@" or UserPrincipalName startswith "NT AUTHORITY"
|
||||
| extend RareDomain = toupper(tostring(split(UserPrincipalName, "@")[-1]))
|
||||
|
|
|
@ -18,11 +18,9 @@ tags:
|
|||
- NOBELIUM
|
||||
query: |
|
||||
|
||||
let timeframe = 30d;
|
||||
(union isfuzzy=true
|
||||
(
|
||||
SecurityEvent
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
SecurityEvent
|
||||
| where EventID == '4688'
|
||||
| where tolower(NewProcessName) has 'solarwinds'
|
||||
| extend MachineName = Computer , Process = NewProcessName
|
||||
|
@ -30,14 +28,12 @@ query: |
|
|||
),
|
||||
(
|
||||
DeviceProcessEvents
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where tolower(InitiatingProcessFolderPath) has 'solarwinds'
|
||||
| extend MachineName = DeviceName , Process = InitiatingProcessFolderPath, Account = AccountName
|
||||
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), MachineCount = dcount(MachineName), AccountCount = dcount(Account), MachineNames = make_set(MachineName), Accounts = make_set(Account) by Process, Type
|
||||
),
|
||||
(
|
||||
Event
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where Source == "Microsoft-Windows-Sysmon"
|
||||
| where EventID == 1
|
||||
| extend Image = EventDetail.[4].["#text"]
|
||||
|
|
|
@ -28,17 +28,14 @@ relevantTechniques:
|
|||
- T1110
|
||||
query: |
|
||||
|
||||
let timeframe = 7d;
|
||||
let action = dynamic(["change ", "changed ", "reset "]);
|
||||
let pWord = dynamic(["password ", "credentials "]);
|
||||
(union isfuzzy=true
|
||||
(SecurityEvent
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where EventID in (4723,4724)
|
||||
| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), ResultDescriptions = makeset(Activity), ActionCount = count() by Resource = Computer, OperationName = strcat("TargetAccount: ", TargetUserName), UserId = Account, Type
|
||||
),
|
||||
(AuditLogs
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where OperationName has_any (pWord) and OperationName has_any (action)
|
||||
| extend InitiatedBy = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)
|
||||
| extend TargetUserPrincipalName = tostring(TargetResources[0].userPrincipalName)
|
||||
|
@ -47,7 +44,6 @@ query: |
|
|||
| extend ResultDescriptions = tostring(ResultDescriptions)
|
||||
),
|
||||
(OfficeActivity
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where (ExtendedProperties has_any (pWord) or ModifiedProperties has_any (pWord)) and (ExtendedProperties has_any (action) or ModifiedProperties has_any (action))
|
||||
| extend ResultDescriptions = case(
|
||||
OfficeWorkload =~ "AzureActiveDirectory", tostring(ExtendedProperties),
|
||||
|
@ -56,12 +52,10 @@ query: |
|
|||
| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), ResultDescriptions = makeset(ResultDescriptions), ActionCount = count() by Resource = OfficeWorkload, OperationName = strcat(Operation, " - ", ResultStatus), IPAddress = ClientIP, UserId, Type
|
||||
),
|
||||
(Syslog
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where SyslogMessage has_any (pWord) and SyslogMessage has_any (action)
|
||||
| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), ResultDescriptions = makeset(SyslogMessage), ActionCount = count() by Resource = HostName, OperationName = Facility , IPAddress = HostIP, ProcessName, Type
|
||||
),
|
||||
(SigninLogs
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where OperationName =~ "Sign-in activity" and ResultType has_any ("50125", "50133")
|
||||
| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), ResultDescriptions = makeset(ResultDescription), CorrelationIds = makeset(CorrelationId), ActionCount = count() by Resource, OperationName = strcat(OperationName, " - ", ResultType), IPAddress, UserId = UserPrincipalName, Type
|
||||
)
|
||||
|
|
|
@ -26,13 +26,11 @@ relevantTechniques:
|
|||
- T1203
|
||||
query: |
|
||||
|
||||
let timeframe = 14d;
|
||||
let UserAgentList = "Internet Explorer |Mozilla/4\\.0 \\(compatible; MSIE 6\\.0; Windows NT 5\\.1; SV1; InfoPath\\.2\\)|Mozilla/5\\.0 \\(Windows NT 10\\.0; Win32; x32; rv:60\\.0\\)|Mozilla/4\\.0 \\(compatible; Metasploit RSPEC\\)|Mozilla/4\\.0 \\(compatible; MSIE 6\\.1; Windows NT\\)|Mozilla/4\\.0 \\(compatible; MSIE 6\\.0; Windows NT 5\\.1\\)|Mozilla/4\\.0 \\(compatible; MSIE 8\\.0; Windows NT 6\\.0; Trident/4\\.0\\)|Mozilla/4\\.0 \\(compatible; MSIE 7\\.0; Windows NT 6\\.0; Trident/4\\.0; SIMBAR={7DB0F6DE-8DE7-4841-9084-28FA914B0F2E}; SLCC1; \\.N|Mozilla/5\\.0 \\(Windows; U; Windows NT 5\\.1; en-US\\) AppleWebKit/525\\.13 \\(KHTML, like Gecko\\) Chrome/4\\.0\\.221\\.6 Safari/525\\.13|Mozilla/5\\.0 \\(compatible; MSIE 9\\.0; Windows NT 6\\.1; WOW64; Trident/5\\.0; MAAU\\)|Mozilla/5\\.0[^\\s]|Mozilla/4\\.0 \\(compatible; SPIPE/1\\.0|Mozilla/5\\.0 \\(Windows NT 6\\.3; rv:39\\.0\\) Gecko/20100101 Firefox/35\\.0|Sametime Community Agent|X-FORWARDED-FOR|DotDotPwn v2\\.1|SIPDROID|wordpress hash grabber|exploit|okhttp/";
|
||||
// Excluding for IIS, as the main malicious usage for okhttp that we have seen was in the OfficeActivity logs and this can create noise for IIS.
|
||||
let ExcludeIIS = "okhttp/";
|
||||
(union isfuzzy=true
|
||||
(OfficeActivity
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where ExtendedProperties has "UserAgent"
|
||||
| extend UserAgent = extractjson("$[0].Value", ExtendedProperties, typeof(string))
|
||||
| where UserAgent matches regex UserAgentList
|
||||
|
@ -41,7 +39,6 @@ query: |
|
|||
),
|
||||
(
|
||||
W3CIISLog
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| extend UserAgent = replace('\\+', ' ', csUserAgent)
|
||||
| where UserAgent matches regex UserAgentList
|
||||
| where UserAgent !startswith ExcludeIIS
|
||||
|
@ -51,7 +48,6 @@ query: |
|
|||
),
|
||||
(
|
||||
AWSCloudTrail
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where UserAgent matches regex UserAgentList
|
||||
| extend SourceIP = SourceIpAddress
|
||||
| project TimeGenerated, Type, UserAgent, SourceIP
|
||||
|
|
|
@ -13,11 +13,9 @@ relevantTechniques:
|
|||
query: |
|
||||
|
||||
// If you want to look at user added further than 7 days ago adjust this value
|
||||
let time_ago = 7d;
|
||||
// If you want to change the timeframe of how quickly accounts need to be added and removed change this value
|
||||
let time_delta = 1h;
|
||||
OfficeActivity
|
||||
| where TimeGenerated > ago(time_ago)
|
||||
| where OfficeWorkload =~ "MicrosoftTeams"
|
||||
| where Operation =~ "MemberAdded"
|
||||
| extend UPN = tostring(parse_json(Members)[0].UPN)
|
||||
|
@ -25,7 +23,6 @@ query: |
|
|||
| project TimeAdded=TimeGenerated, Operation, UPN, UserWhoAdded = UserId, TeamName, TeamGuid
|
||||
| join (
|
||||
OfficeActivity
|
||||
| where TimeGenerated > ago(time_ago)
|
||||
| where OfficeWorkload =~ "MicrosoftTeams"
|
||||
| where Operation =~ "MemberRemoved"
|
||||
| extend UPN = tostring(parse_json(Members)[0].UPN)
|
||||
|
|
|
@ -15,9 +15,7 @@ relevantTechniques:
|
|||
- T1020
|
||||
query: |
|
||||
|
||||
let timeframe = 14d;
|
||||
OfficeActivity
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where OfficeWorkload == "Exchange"
|
||||
| where Operation in~ ("New-TransportRule", "Set-TransportRule")
|
||||
| extend p = parse_json(Parameters)
|
||||
|
|
|
@ -17,9 +17,7 @@ query: |
|
|||
// Adjust these thresholds to suit your environment.
|
||||
let threshold = 2;
|
||||
let time_threshold = timespan(5m);
|
||||
let timeframe = 30d;
|
||||
OfficeActivity
|
||||
| where TimeGenerated > ago(timeframe)
|
||||
| where OfficeWorkload =~ "MicrosoftTeams"
|
||||
| where Operation =~ "BotAddedToTeam"
|
||||
| summarize Start=max(TimeGenerated), End=min(TimeGenerated), Teams = makeset(TeamName)
|
||||
|
|
|
@ -15,9 +15,7 @@ query: |
|
|||
// Adjust this value to change how many teams a user is made owner of before detecting
|
||||
let max_owner_count = 3;
|
||||
// Change this value to adjust how larger timeframe the query is run over.
|
||||
let time_window = 1d;
|
||||
let high_owner_count = (OfficeActivity
|
||||
| where TimeGenerated > ago(time_window)
|
||||
| where OfficeWorkload =~ "MicrosoftTeams"
|
||||
| where Operation =~ "MemberRoleChanged"
|
||||
| extend Member = tostring(parse_json(Members)[0].UPN)
|
||||
|
@ -27,7 +25,6 @@ query: |
|
|||
| where dcount_TeamName > max_owner_count
|
||||
| project Member);
|
||||
OfficeActivity
|
||||
| where TimeGenerated > ago(time_window)
|
||||
| where OfficeWorkload =~ "MicrosoftTeams"
|
||||
| where Operation =~ "MemberRoleChanged"
|
||||
| extend Member = tostring(parse_json(Members)[0].UPN)
|
||||
|
|
|
@ -15,18 +15,14 @@ query: |
|
|||
|
||||
// Adjust this value to change how many Teams should be deleted before including
|
||||
let max_delete = 3;
|
||||
// Adjust this value to change the timewindow the query runs over
|
||||
let time_window = 1d;
|
||||
let deleting_users = (
|
||||
OfficeActivity
|
||||
| where TimeGenerated > ago(time_window)
|
||||
| where OfficeWorkload =~ "MicrosoftTeams"
|
||||
| where Operation =~ "TeamDeleted"
|
||||
| summarize count() by UserId
|
||||
| where count_ > max_delete
|
||||
| project UserId);
|
||||
OfficeActivity
|
||||
| where TimeGenerated > ago(time_window)
|
||||
| where OfficeWorkload =~ "MicrosoftTeams"
|
||||
| where Operation =~ "TeamDeleted"
|
||||
| where UserId in (deleting_users)
|
||||
|
|
|
@ -16,9 +16,7 @@ relevantTechniques:
|
|||
- T1020
|
||||
query: |
|
||||
|
||||
let timeframe = 14d;
|
||||
OfficeActivity
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where (Operation =~ "Set-Mailbox" and Parameters contains 'ForwardingSmtpAddress')
|
||||
or (Operation =~ 'New-InboxRule' and Parameters contains 'ForwardTo')
|
||||
| extend parsed=parse_json(Parameters)
|
||||
|
|
|
@ -14,17 +14,14 @@ relevantTechniques:
|
|||
- T1566
|
||||
query: |
|
||||
|
||||
let timeframe = 7d;
|
||||
let threshold = 1m;
|
||||
OfficeActivity
|
||||
| where TimeGenerated > ago(timeframe)
|
||||
| where OfficeWorkload =~ "MicrosoftTeams"
|
||||
| where Operation == "MemberAdded"
|
||||
| extend TeamName = iff(isempty(TeamName), Members[0].UPN, TeamName)
|
||||
| project TimeGenerated, UploaderID=UserId, TeamName
|
||||
| join (
|
||||
OfficeActivity
|
||||
| where TimeGenerated > ago(timeframe)
|
||||
| where RecordType == "SharePointFileOperation"
|
||||
| where SourceRelativeUrl has "Microsoft Teams Chat Files"
|
||||
| where Operation == "FileUploaded"
|
||||
|
|
|
@ -19,8 +19,7 @@ query: |
|
|||
|
||||
// Reserved FileNames/Extension for Windows
|
||||
let Reserved = dynamic(['CON', 'PRN', 'AUX', 'NUL', 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9', 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9']);
|
||||
let endtime = 1d;
|
||||
OfficeActivity | where TimeGenerated >= ago(endtime)
|
||||
OfficeActivity
|
||||
| where isnotempty(SourceFileExtension)
|
||||
| where SourceFileExtension in~ (Reserved) or SourceFileName in~ (Reserved)
|
||||
| where UserAgent !has "Mac OS"
|
||||
|
|
|
@ -13,17 +13,14 @@ relevantTechniques:
|
|||
- T1036
|
||||
query: |
|
||||
|
||||
let timeframe = 14d;
|
||||
let known_ext = dynamic(["lnk","log","option","config", "manifest", "partial"]);
|
||||
let excluded_users = dynamic(["app@sharepoint"]);
|
||||
OfficeActivity
|
||||
| where TimeGenerated > ago(timeframe)
|
||||
| where RecordType =~ "SharePointFileOperation" and isnotempty(SourceFileName)
|
||||
| where OfficeObjectId has ".exe." and SourceFileExtension !in~ (known_ext)
|
||||
| extend Extension = extract("[^.]*.[^.]*$",0, OfficeObjectId)
|
||||
| join kind= leftouter (
|
||||
OfficeActivity
|
||||
| where TimeGenerated > ago(timeframe)
|
||||
| where RecordType =~ "SharePointFileOperation" and (Operation =~ "FileDownloaded" or Operation =~ "FileAccessed")
|
||||
| where SourceFileExtension !in~ (known_ext)
|
||||
) on OfficeObjectId
|
||||
|
|
|
@ -21,9 +21,7 @@ tags:
|
|||
- NOBELIUM
|
||||
query: |
|
||||
|
||||
let timeframe = 1d;
|
||||
OfficeActivity
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where Operation == "MailboxLogin" and Logon_Type != "Owner"
|
||||
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), count() by Operation, OrganizationName, UserType, UserId, MailboxOwnerUPN, Logon_Type, ClientIP
|
||||
| extend timestamp = StartTime, AccountCustomEntity = UserId, IPCustomEntity = ClientIP
|
||||
|
|
|
@ -20,9 +20,7 @@ relevantTechniques:
|
|||
- T1114
|
||||
query: |
|
||||
|
||||
let timeframe = 1d;
|
||||
OfficeActivity
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where Operation == "MailboxLogin"
|
||||
| where ClientInfoString == "Client=Microsoft.Exchange.Powershell; Microsoft WinRM Client"
|
||||
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), count() by Operation, OrganizationName, UserType, UserId, MailboxOwnerUPN, Logon_Type, ClientInfoString
|
||||
|
|
|
@ -9,7 +9,6 @@ requiredDataConnectors:
|
|||
tactics:
|
||||
- InitialAccess
|
||||
query: |
|
||||
let lbtime = 24h;
|
||||
let scoreThreshold = 80;
|
||||
ProofpointPOD
|
||||
| where EventType == 'message'
|
||||
|
|
|
@ -9,7 +9,6 @@ requiredDataConnectors:
|
|||
tactics:
|
||||
- InitialAccess
|
||||
query: |
|
||||
let lbtime = 24h;
|
||||
let scoreThreshold = 80;
|
||||
ProofpointPOD
|
||||
| where EventType == 'message'
|
||||
|
|
|
@ -9,7 +9,6 @@ requiredDataConnectors:
|
|||
tactics:
|
||||
- InitialAccess
|
||||
query: |
|
||||
let lbtime = 24h;
|
||||
let scoreThreshold = 80;
|
||||
ProofpointPOD
|
||||
| where EventType == 'message'
|
||||
|
|
|
@ -9,7 +9,6 @@ requiredDataConnectors:
|
|||
tactics:
|
||||
- InitialAccess
|
||||
query: |
|
||||
let lbtime = 24h;
|
||||
let scoreThreshold = 80;
|
||||
ProofpointPOD
|
||||
| where EventType == 'message'
|
||||
|
|
|
@ -9,7 +9,6 @@ requiredDataConnectors:
|
|||
tactics:
|
||||
- InitialAccess
|
||||
query: |
|
||||
let lbtime = 24h;
|
||||
let scoreThreshold = 80;
|
||||
ProofpointPOD
|
||||
| where EventType == 'message'
|
||||
|
|
|
@ -11,7 +11,6 @@ tactics:
|
|||
query: |
|
||||
let threshold = 10;
|
||||
ProofpointPOD
|
||||
| where TimeGenerated > ago(24h)
|
||||
| where EventType == 'message'
|
||||
| where NetworkDirection == 'inbound'
|
||||
| where FilterDisposition !in ('reject', 'discard')
|
||||
|
|
|
@ -9,9 +9,7 @@ requiredDataConnectors:
|
|||
tactics:
|
||||
- InitialAccess
|
||||
query: |
|
||||
let lbtime = 24h;
|
||||
ProofpointPOD
|
||||
| where TimeGenerated > ago(lbtime)
|
||||
| where EventType == 'message'
|
||||
| where NetworkDirection == 'inbound'
|
||||
| extend isCorrupted = todynamic(MsgParts)[0]['isCorrupted']
|
||||
|
|
|
@ -9,9 +9,7 @@ requiredDataConnectors:
|
|||
tactics:
|
||||
- InitialAccess
|
||||
query: |
|
||||
let lbtime = 24h;
|
||||
ProofpointPOD
|
||||
| where TimeGenerated > ago(lbtime)
|
||||
| where EventType == 'message'
|
||||
| where NetworkDirection == 'outbound'
|
||||
| extend isCorrupted = todynamic(MsgParts)[0]['isCorrupted']
|
||||
|
|
|
@ -9,9 +9,7 @@ requiredDataConnectors:
|
|||
tactics:
|
||||
- InitialAccess
|
||||
query: |
|
||||
let lbtime = 24h;
|
||||
ProofpointPOD
|
||||
| where TimeGenerated > ago(lbtime)
|
||||
| where EventType == 'message'
|
||||
| where NetworkDirection == 'inbound'
|
||||
| extend attachedFileType = todynamic(MsgParts)[0]['detectedExt']
|
||||
|
|
|
@ -17,7 +17,6 @@ query: |
|
|||
// SQLEvent is not the table name, it is the function name that should already be imported into your workspace.
|
||||
// The underlying table where the data exists is the Event table.
|
||||
SQLEvent
|
||||
| where TimeGenerated >= ago(1d)
|
||||
| where LogonResult has "failed"
|
||||
| summarize count() by TimeGenerated, CurrentUser, Reason, ClientIP
|
||||
| extend timestamp = TimeGenerated, AccountCustomEntity = CurrentUser, IPCustomEntity = ClientIP
|
||||
|
|
|
@ -17,12 +17,10 @@ query: |
|
|||
|
||||
// SQLEvent is not the table name, it is the function name that should already be imported into your workspace.
|
||||
// The underlying table where the data exists is the Event table.
|
||||
// the timeframe and threshold can be changed below as per requirement.
|
||||
// the threshold can be changed below as per requirement.
|
||||
//
|
||||
let TimeFrame = 1d;
|
||||
let failedThreshold = 3;
|
||||
SQLEvent
|
||||
| where TimeGenerated >= ago(TimeFrame)
|
||||
| where LogonResult has "failed"
|
||||
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), TotalFailedLogons = count() by ClientIP, CurrentUser, Computer
|
||||
| where TotalFailedLogons >= failedThreshold
|
||||
|
|
|
@ -17,12 +17,10 @@ query: |
|
|||
|
||||
// SQLEvent is not the table name, it is the function name that should already be imported into your workspace.
|
||||
// The underlying table where the data exists is the Event table.
|
||||
// the timeframe and threshold can be changed below as per requirement
|
||||
// the threshold can be changed below as per requirement
|
||||
//
|
||||
let TimeFrame = 1d;
|
||||
let failedThreshold = 3;
|
||||
SQLEvent
|
||||
| where TimeGenerated >= ago(TimeFrame)
|
||||
| where LogonResult has "failed"
|
||||
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), TotalFailedLogons = count() by CurrentUser, ClientIP
|
||||
| where TotalFailedLogons >= failedThreshold
|
||||
|
|
|
@ -20,7 +20,6 @@ query: |
|
|||
// This query checks for new user account created on SQL Server using the SQLEvent() parser
|
||||
//
|
||||
SQLEvent
|
||||
| where TimeGenerated >= ago(1d)
|
||||
| where Statement has "Create Login"
|
||||
| parse Statement with "CREATE LOGIN [" TargetUser:string "]" *
|
||||
| project TimeGenerated, Computer, Action, ClientIP, CurrentUser, DatabaseName, TargetUser, ObjectName, Statement
|
||||
|
|
|
@ -21,7 +21,6 @@ query: |
|
|||
// The underlying table where the data exists is the Event table.
|
||||
// This query tracks user added into SecurityAdmingroup
|
||||
SQLEvent
|
||||
| where TimeGenerated >= ago(1d)
|
||||
| where Statement has "Alter Server role" and Statement has "add member"
|
||||
| parse Statement with * "ADD MEMBER [" TargetUser:string "]" *
|
||||
| where ObjectName has "securityadmin"
|
||||
|
|
|
@ -24,7 +24,6 @@ query: |
|
|||
// This query checks for user removed from a database by parsing the statement field at the query time.
|
||||
//
|
||||
SQLEvent
|
||||
| where TimeGenerated >= ago(1d)
|
||||
| where Statement has "Alter role" and Statement has "drop member"
|
||||
| parse Statement with * "DROP MEMBER [" TargetUser:string "]" *
|
||||
| project TimeGenerated, Computer, Action, ClientIP, CurrentUser, DatabaseName, TargetUser, ObjectName, Statement
|
||||
|
|
|
@ -23,7 +23,6 @@ query: |
|
|||
// The underlying table where the data exists is the Event table.
|
||||
// This query checks for user removed from SecurityAdmin Role
|
||||
SQLEvent
|
||||
| where TimeGenerated >= ago(1d)
|
||||
| where Statement has "Alter Server role" and Statement has "drop member"
|
||||
| parse Statement with * "DROP MEMBER [" TargetUser:string "]" *
|
||||
| where ObjectName has "securityadmin"
|
||||
|
|
|
@ -23,7 +23,6 @@ query: |
|
|||
// The underlying table where the data exists is the Event table.
|
||||
// This query checks for user removed from a ServerRole
|
||||
SQLEvent
|
||||
| where TimeGenerated >= ago(1d)
|
||||
| where Statement has "Alter Server role" and Statement has "drop member"
|
||||
| parse Statement with * "DROP MEMBER [" TargetUser:string "]" *
|
||||
| project TimeGenerated, Computer, Action, ClientIP, CurrentUser, DatabaseName, TargetUser, ObjectName, Statement
|
||||
|
|
|
@ -21,7 +21,6 @@ query: |
|
|||
// The underlying table where the data exists is the Event table.
|
||||
// This query looking for Alter role commands and extracts username which was altered and target objectName
|
||||
SQLEvent
|
||||
| where TimeGenerated >= ago(1d)
|
||||
| where Statement contains "Alter role" and Statement has "add member"
|
||||
| parse Statement with * "ADD MEMBER [" TargetUser:string "]" *
|
||||
| project TimeGenerated, Computer, Action, ClientIP, CurrentUser, DatabaseName, TargetUser, ObjectName, Statement
|
||||
|
|
|
@ -14,12 +14,10 @@ tactics:
|
|||
- Persistence
|
||||
query: |
|
||||
let scriptExtensions = dynamic([".php", ".jsp", ".js", ".aspx", ".asmx", ".asax", ".cfm", ".shtml"]);
|
||||
let timeRange = 3d;
|
||||
let lookupWindow = 1m;
|
||||
let lookupBin = lookupWindow / 2.0;
|
||||
let distinctIpThreshold = 3;
|
||||
let alerts = SecurityAlert
|
||||
| where TimeGenerated > ago(timeRange)
|
||||
| extend alertData = parse_json(Entities), recordGuid = new_guid();
|
||||
let shellAlerts = alerts
|
||||
| where ProviderName =~ "MDATP"
|
||||
|
@ -53,14 +51,12 @@ query: |
|
|||
| project recordGuid, TimeGenerated, ImageName, CommandLine, TimeKey = bin(TimeGenerated, lookupBin), HostName, DnsDomain
|
||||
| extend Start = TimeGenerated;
|
||||
let baseline = W3CIISLog
|
||||
| where TimeGenerated > ago(timeRange)
|
||||
| project-rename SourceIP=cIP, PageAccessed=csUriStem
|
||||
| summarize dcount(SourceIP) by PageAccessed
|
||||
| where dcount_SourceIP <= distinctIpThreshold;
|
||||
commandKeyedData
|
||||
| join kind=inner (
|
||||
W3CIISLog
|
||||
| where TimeGenerated > ago(timeRange)
|
||||
W3CIISLog
|
||||
| where csUriStem has_any(scriptExtensions)
|
||||
| extend splitUriStem = split(csUriStem, "/")
|
||||
| extend FileName = splitUriStem[-1] | extend firstDir = splitUriStem[-2] | extend TimeKey = range(bin(TimeGenerated-lookupWindow, lookupBin), bin(TimeGenerated, lookupBin),lookupBin)
|
||||
|
|
|
@ -13,10 +13,8 @@ tactics:
|
|||
- PrivilegeEscalation
|
||||
- Persistence
|
||||
query: |
|
||||
let timeWindow = 3d;
|
||||
let scriptExtensions = dynamic([".php", ".jsp", ".js", ".aspx", ".asmx", ".asax", ".cfm", ".shtml"]);
|
||||
SecurityAlert
|
||||
| where TimeGenerated > ago(timeWindow)
|
||||
SecurityAlert
|
||||
| where ProviderName =~ "MDATP"
|
||||
| extend alertData = parse_json(Entities)
|
||||
| mvexpand alertData
|
||||
|
@ -27,8 +25,7 @@ query: |
|
|||
| extend FileName = alertData.Name
|
||||
| project TimeGenerated, tostring(FileName), alertData.Directory
|
||||
| join (
|
||||
W3CIISLog
|
||||
| where TimeGenerated > ago(timeWindow)
|
||||
W3CIISLog
|
||||
| where csUriStem has_any(scriptExtensions)
|
||||
| extend splitUriStem = split(csUriStem, "/")
|
||||
| extend FileName = splitUriStem[-1]
|
||||
|
|
|
@ -11,9 +11,7 @@ tactics:
|
|||
relevantTechniques:
|
||||
- T1531
|
||||
query: |
|
||||
let timeframe = 7d;
|
||||
SecurityEvent
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where EventID == 4740
|
||||
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), LockoutsCount = count() by Activity, Account, TargetSid, TargetDomainName, SourceComputerId, SourceDomainController = Computer
|
||||
| extend timestamp = StartTime, AccountCustomEntity = Account, HostCustomEntity = TargetDomainName
|
||||
|
|
|
@ -13,10 +13,8 @@ relevantTechniques:
|
|||
- T1105
|
||||
|
||||
query: |
|
||||
let timeframe = 1d;
|
||||
Event
|
||||
//This query uses sysmon data depending on table name used this may need updataing
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where Source == "Microsoft-Windows-Sysmon"
|
||||
| where EventID == 1
|
||||
| extend RenderedDescription = tostring(split(RenderedDescription, ":")[0])
|
||||
|
|
|
@ -13,9 +13,7 @@ relevantTechniques:
|
|||
- T1110
|
||||
query: |
|
||||
|
||||
let timeframe = 1d;
|
||||
SecurityEvent
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where AccountType == 'User' and EventID == 4625
|
||||
| extend Reason = case(
|
||||
SubStatus == '0xc000005e', 'No logon servers available to service the logon request',
|
||||
|
|
|
@ -24,7 +24,6 @@ query: |
|
|||
let WellKnownLocalSIDs = "S-1-5-[0-9][0-9]$";
|
||||
let protocols = dynamic(['cifs', 'ldap', 'RPCSS', 'host' , 'HTTP', 'RestrictedKrbHost', 'TERMSRV', 'msomsdksvc', 'mssqlsvc']);
|
||||
SecurityEvent
|
||||
| where TimeGenerated >= ago(1d)
|
||||
| where EventID == 4648
|
||||
| where SubjectUserSid != 'S-1-0-0' // this is the Nobody SID which really means No security principal was included.
|
||||
| where not(SubjectUserSid matches regex WellKnownLocalSIDs) //excluding system account/service account as this is generally normal
|
||||
|
|
|
@ -26,14 +26,12 @@ tags:
|
|||
- Solorigate
|
||||
- NOBELIUM
|
||||
query: |
|
||||
let startdate = 1d;
|
||||
let lookupwindow = 2m;
|
||||
let threshold = 3; //number of commandlines in the set below
|
||||
let DCADFSServersList = dynamic (["DCServer01", "DCServer02", "ADFSServer01"]); // Enter a reference list of hostnames for your DC/ADFS servers
|
||||
let tokens = dynamic(["objectcategory","domainlist","dcmodes","adinfo","trustdmp","computers_pwdnotreqd","Domain Admins", "objectcategory=person", "objectcategory=computer", "objectcategory=*"]);
|
||||
SecurityEvent
|
||||
//| where Computer in (DCADFSServersList) // Uncomment to limit it to your DC/ADFS servers list if specified above or any pattern in hostnames (startswith, matches regex, etc).
|
||||
| where TimeGenerated between (ago(startdate) .. now())
|
||||
| where EventID == 4688
|
||||
| where CommandLine has_any (tokens)
|
||||
| where CommandLine matches regex "(.*)>(.*)"
|
||||
|
|
|
@ -14,9 +14,7 @@ relevantTechniques:
|
|||
- T1110
|
||||
query: |
|
||||
|
||||
let timeframe = 1d;
|
||||
SecurityEvent
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where EventID in (4624, 4625)
|
||||
| where AccountType == 'User'
|
||||
| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), Amount = count() by LogonTypeName
|
||||
|
|
|
@ -15,12 +15,10 @@ relevantTechniques:
|
|||
- T1078
|
||||
query: |
|
||||
|
||||
let timeframe = 10d;
|
||||
// For AD SID mappings - https://docs.microsoft.com/windows/security/identity-protection/access-control/active-directory-security-groups
|
||||
let WellKnownLocalSID = "S-1-5-32-5[0-9][0-9]$";
|
||||
let WellKnownGroupSID = "S-1-5-21-[0-9]*-[0-9]*-[0-9]*-5[0-9][0-9]$|S-1-5-21-[0-9]*-[0-9]*-[0-9]*-1102$|S-1-5-21-[0-9]*-[0-9]*-[0-9]*-1103$";
|
||||
SecurityEvent
|
||||
| where TimeGenerated > ago(timeframe)
|
||||
| where AccountType == "User"
|
||||
// 4728 - A member was added to a security-enabled global group
|
||||
// 4732 - A member was added to a security-enabled local group
|
||||
|
|
|
@ -14,12 +14,9 @@ relevantTechniques:
|
|||
- T1078
|
||||
query: |
|
||||
|
||||
// TimeFrame is the number of lookback days, default is last 14 days
|
||||
let timeframe = 14d;
|
||||
// TimeDelta is the difference between when the account was created and when it was deleted, default is set to 10min or less
|
||||
let timedelta = 10m;
|
||||
SecurityEvent
|
||||
| where TimeGenerated > ago(timeframe)
|
||||
// A user account was created
|
||||
| where EventID == "4720"
|
||||
| where AccountType == "User"
|
||||
|
@ -27,7 +24,6 @@ query: |
|
|||
AccountUsedToCreate = SubjectUserName, TargetSid, SubjectUserSid
|
||||
| join kind= inner (
|
||||
SecurityEvent
|
||||
| where TimeGenerated > ago(timeframe)
|
||||
// A user account was deleted
|
||||
| where EventID == "4726"
|
||||
| where AccountType == "User"
|
||||
|
|
|
@ -16,9 +16,7 @@ query: |
|
|||
|
||||
// Create DataTable with your own values, example below shows dummy usernames that are authorized and for what domain
|
||||
let List = datatable(AuthorizedUser:string, Domain:string)["Bob", "Domain", "joe", "domain", "MATT", "DOMAIN"];
|
||||
let timeframe = 1d;
|
||||
SecurityEvent
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where EventID in (4728, 4729, 4732, 4733, 4746, 4747, 4751, 4752, 4756, 4757, 4761, 4762)
|
||||
| join kind= leftanti (
|
||||
List
|
||||
|
|
|
@ -16,9 +16,7 @@ query: |
|
|||
|
||||
// Create DataTable with your own values, example below shows dummy usernames that are authorized and for what domain
|
||||
let List = datatable(AuthorizedUser:string, Domain:string)["Bob", "Domain", "joe", "domain", "MATT", "DOMAIN"];
|
||||
let timeframe = 1d;
|
||||
SecurityEvent
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where EventID == 4720
|
||||
| where AccountType == "User"
|
||||
| join kind= leftanti (
|
||||
|
|
|
@ -14,10 +14,8 @@ query: |
|
|||
|
||||
// Create DataTable with your own values, example below shows dummy usernames that are authorized and for what domain
|
||||
let List = datatable(VIPUser:string, Domain:string)["Bob", "Domain", "joe", "domain", "MATT", "DOMAIN"];
|
||||
let timeframe = 10m;
|
||||
List | extend Account = strcat(Domain,"\\",VIPUser) | join kind= inner (
|
||||
SecurityEvent
|
||||
| where TimeGenerated > ago(timeframe)
|
||||
| where EventID == "4625"
|
||||
| where AccountType == "User"
|
||||
| where LogonType == "2" or LogonType == "3"
|
||||
|
|
|
@ -10,7 +10,6 @@ tactics:
|
|||
- Execution
|
||||
query: |
|
||||
|
||||
let timeframe = 1d;
|
||||
let ProcessCreationEvents=() {
|
||||
let processEvents=SecurityEvent
|
||||
| where EventID==4688
|
||||
|
@ -21,7 +20,6 @@ query: |
|
|||
};
|
||||
// Daily summary of cscript activity - extracting script name and parameters from commandline:
|
||||
ProcessCreationEvents
|
||||
| where EventTime >= ago(timeframe)
|
||||
| where FileName =~ "cscript.exe"
|
||||
// remove commandline switches
|
||||
| project EventTime, ComputerName, AccountName, removeSwitches = replace(@"/+[a-zA-Z0-9:]+", "", ProcessCommandLine)
|
||||
|
|
|
@ -10,7 +10,6 @@ tactics:
|
|||
- Discovery
|
||||
query: |
|
||||
|
||||
let timeframe = 1d;
|
||||
let ProcessCreationEvents=() {
|
||||
let processEvents=SecurityEvent
|
||||
| where EventID==4688
|
||||
|
@ -21,7 +20,6 @@ query: |
|
|||
InitiatingProcessFileName=ParentProcessName,InitiatingProcessCommandLine="",InitiatingProcessParentFileName="";
|
||||
processEvents};
|
||||
ProcessCreationEvents
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where FileName == 'net.exe' and AccountName != "" and ProcessCommandLine !contains '\\' and ProcessCommandLine !contains '/add'
|
||||
| where (ProcessCommandLine contains ' user ' or ProcessCommandLine contains ' group ') and (ProcessCommandLine endswith ' /do' or ProcessCommandLine endswith ' /domain')
|
||||
| extend Target = extract("(?i)[user|group] (\"*[a-zA-Z0-9-_ ]+\"*)", 1, ProcessCommandLine) | filter Target != ''
|
||||
|
|
|
@ -14,9 +14,7 @@ tactics:
|
|||
- Execution
|
||||
query: |
|
||||
|
||||
let timeframe = 1d;
|
||||
SecurityEvent
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where NewProcessName endswith "\\svchost.exe"
|
||||
| where SubjectUserSid !in ("S-1-5-18", "S-1-5-19", "S-1-5-20")
|
||||
| where NewProcessName !contains ":\\Windows\\System32"
|
||||
|
|
|
@ -18,9 +18,7 @@ relevantTechniques:
|
|||
- T1110
|
||||
query: |
|
||||
|
||||
let timeframe = 1d;
|
||||
SecurityEvent
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where EventID==4688
|
||||
| project TimeGenerated, ComputerName=Computer,AccountName=SubjectUserName,
|
||||
AccountDomain=SubjectDomainName, FileName=tostring(split(NewProcessName, '\\')[-1]),
|
||||
|
|
|
@ -11,7 +11,6 @@ tactics:
|
|||
- CommandAndControl
|
||||
query: |
|
||||
|
||||
let timeframe = 1d;
|
||||
let ProcessCreationEvents=() {
|
||||
let processEvents=SecurityEvent
|
||||
| where EventID==4688
|
||||
|
@ -21,7 +20,6 @@ query: |
|
|||
InitiatingProcessFileName=ParentProcessName,InitiatingProcessCommandLine="",InitiatingProcessParentFileName="";
|
||||
processEvents};
|
||||
ProcessCreationEvents
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
| where FileName in~ ("powershell.exe", "powershell_ise.exe")
|
||||
| where ProcessCommandLine has "Net.WebClient"
|
||||
or ProcessCommandLine has "DownloadFile"
|
||||
|
|
|
@ -13,7 +13,6 @@ tactics:
|
|||
- Execution
|
||||
query: |
|
||||
|
||||
let timeframe = 1d;
|
||||
let ProcessCreationEvents=() {
|
||||
let processEvents=SecurityEvent
|
||||
| where EventID==4688
|
||||
|
@ -28,7 +27,6 @@ query: |
|
|||
processEvents;
|
||||
};
|
||||
let normalizedProcesses = ProcessCreationEvents
|
||||
| where TimeGenerated >= ago(timeframe)
|
||||
// normalize guids
|
||||
| project TimeGenerated, FileName = replace("[0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}", "<guid>", FileName)
|
||||
// normalize digits away
|
||||
|
|
|
@ -15,10 +15,8 @@ relevantTechniques:
|
|||
- T1078
|
||||
query: |
|
||||
|
||||
let timeRange=ago(14d);
|
||||
SigninLogs
|
||||
// Forces Log Analytics to recognize that the query should be run over full time range
|
||||
| where TimeGenerated >= timeRange
|
||||
| extend locationString= strcat(tostring(LocationDetails["countryOrRegion"]), "/",
|
||||
tostring(LocationDetails["state"]), "/", tostring(LocationDetails["city"]), ";")
|
||||
| project TimeGenerated, AppDisplayName, UserPrincipalName, locationString
|
||||
|
|
|
@ -17,10 +17,8 @@ relevantTechniques:
|
|||
- T1078
|
||||
query: |
|
||||
|
||||
let timeRange = ago(14d);
|
||||
SigninLogs
|
||||
// Forces Log Analytics to recognize that the query should be run over full time range
|
||||
| where TimeGenerated >= timeRange
|
||||
| extend locationString= strcat(tostring(LocationDetails["countryOrRegion"]), "/",
|
||||
tostring(LocationDetails["state"]), "/", tostring(LocationDetails["city"]), ";")
|
||||
| project TimeGenerated, AppDisplayName , UserPrincipalName, locationString
|
||||
|
@ -34,7 +32,6 @@ query: |
|
|||
| top 3 by Slope desc
|
||||
// Extract the set of locations for each top user:
|
||||
| join kind=inner (SigninLogs
|
||||
| where TimeGenerated >= timeRange
|
||||
| extend locationString= strcat(tostring(LocationDetails["countryOrRegion"]), "/",
|
||||
tostring(LocationDetails["state"]), "/", tostring(LocationDetails["city"]), ";")
|
||||
| summarize locationList = makeset(locationString), threeDayWindowLocationCount=dcount(locationString) by AppDisplayName, UserPrincipalName,
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче