SigninLogs |extend TimeInUK = CreatedDateTime|extend day = (dayofweek(TimeInUK))
| extend daystarting = tostring(day) //daystrating definitions, 1=Monday, 2=Tuesday,
3=Wednesday, 4=Thursday, 5=Friday, 6=Saturday, 7=Sunday| where daystarting
== "6.00:00:00" or daystarting == "7.00:00:00" or hourofday(TimeInUK)
!between (7...18)| project TimeGenerated , TimeInUK , UserPrincipalName
, day , AppDisplayName , username = UserPrincipalName |
join (UserWatchlist_CL | project-rename username = Username_s )
on username | project TimeInUK , day , username , AppDisplayName)*
|
+|2|Use a watchlist to dismiss expected alerts|Data Sources – Azure Defender for IoT, list of user and device pairs uploaded into a Watchlist,let timeframe = 10m;let lookback = 1d;let account_created =SecurityEvent
| where TimeGenerated > ago(lookback+timeframe)| where EventID == "4720"
// A user account was created| where AccountType =~ "User"
| project creationTime = TimeGenerated, CreateEventID =
EventID,Activity, Computer, TargetUserName, UserPrincipalName,
AccountUsedToCreate = SubjectUserName, TargetSid,
SubjectUserSid;account_created | join kind= inner (account_deleted)
on Computer, TargetUserName| where deletionTime - creationTime
< lookback| where tolong(deletionTime - creationTime)
>= 0|extend timestamp = creationTime, AccountCustomEntity
= AccountUsedToCreate, HostCustomEntity = Computer*
|
+|4|Detect Solorigate Network Beacon|Data sources: DNS, CISCO ASA, Palo Alto Networks, Microsoft 365 Defender. KQL Query: let domains = dynamic(["incomeupdate.com","zupertech.com","databasegalore.com","panhardware.com","avsvmcloud.com","digitalcollege.org","freescanonline.com","deftsecurity.com","thedoccloud.com","virtualdataserver.com","lcomputers.com","webcodez.com","globalnetworkissues.com","kubecloud.com","seobundlekit.com","solartrackingsystem.net","virtualwebdata.com"]);let timeframe = 6h;(union isfuzzy=true(CommonSecurityLog | where TimeGenerated >= ago(timeframe)| parse Message with * '(' DNSName ')' * | where DNSName in~ (domains) or DestinationHostName has_any (domains) or RequestURL has_any(domains) | extend AccountCustomEntity = SourceUserID, HostCustomEntity = DeviceName, IPCustomEntity = SourceIP ),(DnsEvents | where TimeGenerated >= ago(timeframe) | extend DNSName = Name| where isnotempty(DNSName)| where DNSName in~ (domains) | extend IPCustomEntity = ClientIP),VMConnection| where TimeGenerated >= ago(timeframe)| parse RemoteDnsCanonicalNames with * '["' DNSName '"]' *| where isnotempty(DNSName)| where DNSName in~ (domains)| extend IPCustomEntity = RemoteIp ),(DeviceNetworkEvents | where TimeGenerated >= ago(timeframe)| where isnotempty(RemoteUrl)| where RemoteUrl has_any (domains)| extend DNSName = RemoteUrl| extend IPCustomEntity = RemoteIP| extend HostCustomEntity = DeviceName)) *
|
+|5 |An IP address that had (failed) attempts to sign in to one or more disabled accounts signed in successfully to another account.|Data Sources: Azure AD.Analytics that looks for specific Azure AD Sign-In log entrieslet lookBack = 1d;SigninLogs | where TimeGenerated >= ago(lookBack)
| where ResultType == "50057"| where ResultDescription == "User account
is disabled.The account has been disabled by an administrator."|
summarize StartTimeUtc = min(TimeGenerated),EndTimeUtc
= max(TimeGenerated),
disabledAccountLoginAttempts = count(),disabledAccountsTargeted
= dcount(UserPrincipalName), applicationsTargeted
= dcount(AppDisplayName), disabledAccountSet
= makeset(UserPrincipalName),applicationSet
= makeset(AppDisplayName) by IPAddress| order by
disabledAccountLoginAttempts desc| join
kind= leftouter (// Consider these IPs suspicious - and alert
any related successful sign-insSigninLogs| where TimeGenerated
>= ago(lookBack)| where ResultType == 0| summarize
successfulAccountSigninCount = dcount(UserPrincipalName), successfulAccountSigninSet
= makeset(UserPrincipalName, 15) by IPAddress// Assume IPs associated with sign-ins
from 100+ distinct user accounts are safe| where successfulAccountSigninCount
< 100) on IPAddress// IPs from which attempts to authenticate
as disabled user accounts originated, and had a non-zero
success rate for some other account| where successfulAccountSigninCount
!= 0| project StartTimeUtc, EndTimeUtc, IPAddress, disabledAccountLoginAttempts,
disabledAccountsTargeted, disabledAccountSet, applicationSet,
successfulAccountSigninCount,successfulAccountSigninSet|
order by disabledAccountLoginAttempts| extend timestamp =
StartTimeUtc,IPCustomEntity = IPAddress
|
+|6|Detect Brute Force attack based on statistical detections|Data sources: Azure AD. KQL Query:let signin_threshold = toscalar(SigninLogs | where TimeGenerated >= startofday(ago(7d))
and TimeGenerated < startofday(now()) | where ResultType !in ("0", "50125", "50140")
| where IPAddress != "127.0.0.1" | summarize cnt=count() by IPAddress, bin(TimeGenerated, 1d)
| summarize percentile(cnt, 95)); | SigninLogs| where signin_threshold > 10 and Location == "KE"
|
+
+
+
+
diff --git a/Tools/RuleMigration/Data table mapping.xlsx b/Tools/RuleMigration/Data table mapping.xlsx
new file mode 100644
index 0000000000000000000000000000000000000000..217f54b2df620e8de0900ee7d6072e4ae4b993c1
GIT binary patch
literal 92524
zcmeFYbzD_zyDm(KARr~6l!yuv($Z2Q7<8v}NjFF%0*ZhbgoKom(jpBi0s