Sylog to Zoom
This commit is contained in:
Родитель
b1faf7dc83
Коммит
8c900dafa2
|
@ -1,7 +1,7 @@
|
||||||
id: d0ae35df-0eaf-491f-b23e-8190e4f3ffe9
|
id: d0ae35df-0eaf-491f-b23e-8190e4f3ffe9
|
||||||
name: Rare process running on a Linux host
|
name: Rare process running on a Linux host
|
||||||
description: |
|
description: |
|
||||||
'Looks for rare processes that are running on Linux hosts. Looks for process seen less than 14 times in last 7 days,
|
'Looks for rare processes that are running on Linux hosts. Looks for process seen less than 14 times in last 7 days,
|
||||||
or observed rate is less than 1% of of the average for the environment and fewer than 100.'
|
or observed rate is less than 1% of of the average for the environment and fewer than 100.'
|
||||||
requiredDataConnectors:
|
requiredDataConnectors:
|
||||||
- connectorId: Syslog
|
- connectorId: Syslog
|
||||||
|
@ -15,26 +15,27 @@ relevantTechniques:
|
||||||
- T1053
|
- T1053
|
||||||
- T1037
|
- T1037
|
||||||
query: |
|
query: |
|
||||||
let starttime = 7d;
|
|
||||||
let endtime = 1m;
|
let starttime = todatetime('{{StartTimeISO}}');
|
||||||
let lookback = 30d;
|
let endtime = todatetime('{{EndTimeISO}}');
|
||||||
|
let lookback = starttime - 14d;
|
||||||
let count_threshold = 100;
|
let count_threshold = 100;
|
||||||
let perc_threshold = 0.01;
|
let perc_threshold = 0.01;
|
||||||
let host_threshold = 14;
|
let host_threshold = 14;
|
||||||
let basic=materialize(
|
let basic=materialize(
|
||||||
Syslog
|
Syslog
|
||||||
| where TimeGenerated >= ago(lookback)
|
| where TimeGenerated >= lookback
|
||||||
| summarize FullCount = count()
|
| summarize FullCount = count()
|
||||||
, Count= countif(TimeGenerated between (ago(starttime) .. ago(endtime)))
|
, Count= countif(TimeGenerated between (starttime .. endtime))
|
||||||
, min_TimeGenerated=min(TimeGenerated)
|
, min_TimeGenerated=min(TimeGenerated)
|
||||||
, max_TimeGenerated=max(TimeGenerated)
|
, max_TimeGenerated=max(TimeGenerated)
|
||||||
by Computer, ProcessName
|
by Computer, ProcessName
|
||||||
| where Count > 0 and Count < count_threshold);
|
| where Count > 0 and Count < count_threshold);
|
||||||
let basic_avg = basic
|
let basic_avg = basic
|
||||||
| summarize Avg = avg(FullCount) by ProcessName;
|
| summarize Avg = avg(FullCount) by ProcessName;
|
||||||
basic | project-away FullCount
|
basic | project-away FullCount
|
||||||
| join kind=inner
|
| join kind=inner
|
||||||
basic_avg
|
basic_avg
|
||||||
on ProcessName | project-away ProcessName1
|
on ProcessName | project-away ProcessName1
|
||||||
| where Count < host_threshold or (Count <= Avg*perc_threshold and Count < count_threshold)
|
| where Count < host_threshold or (Count <= Avg*perc_threshold and Count < count_threshold)
|
||||||
| extend HostCustomEntity=Computer
|
| extend HostCustomEntity=Computer
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
id: 959fe0f0-7ac0-467c-944f-5b8c6fdc9e72
|
id: 959fe0f0-7ac0-467c-944f-5b8c6fdc9e72
|
||||||
name: Disabled accounts using Squid proxy
|
name: Disabled accounts using Squid proxy
|
||||||
description: |
|
description: |
|
||||||
'Look for accounts that have a been recorded as disabled by AD in the previous week but are still using the proxy during
|
'Look for accounts that have a been recorded as disabled by AD in the previous time period but are still using the proxy during
|
||||||
the current week. This query presumes the default squid log format is being used. http://www.squid-cache.org/Doc/config/access_log/'
|
the current time period. This query presumes the default squid log format is being used. http://www.squid-cache.org/Doc/config/access_log/'
|
||||||
requiredDataConnectors:
|
requiredDataConnectors:
|
||||||
- connectorId: Syslog
|
- connectorId: Syslog
|
||||||
dataTypes:
|
dataTypes:
|
||||||
|
@ -13,17 +13,18 @@ relevantTechniques:
|
||||||
- T1110
|
- T1110
|
||||||
query: |
|
query: |
|
||||||
|
|
||||||
let starttime = 14d;
|
let starttime = todatetime('{{StartTimeISO}}');
|
||||||
let endtime = 7d;
|
let endtime = todatetime('{{EndTimeISO}}');
|
||||||
|
let lookback = startime - 14d;
|
||||||
let disabledAccounts = (){
|
let disabledAccounts = (){
|
||||||
SigninLogs
|
SigninLogs
|
||||||
| where TimeGenerated between(ago(starttime) .. ago(endtime))
|
| where TimeGenerated between(lookback..starttime))
|
||||||
| where ResultType == 50057
|
| where ResultType == 50057
|
||||||
| where ResultDescription =~ "User account is disabled. The account has been disabled by an administrator."
|
| where ResultDescription =~ "User account is disabled. The account has been disabled by an administrator."
|
||||||
};
|
};
|
||||||
let proxyEvents = (){
|
let proxyEvents = (){
|
||||||
Syslog
|
Syslog
|
||||||
| where TimeGenerated > ago(endtime)
|
| where TimeGenerated between(starttime..endtime)
|
||||||
| where ProcessName contains "squid"
|
| where ProcessName contains "squid"
|
||||||
| extend URL = extract("(([A-Z]+ [a-z]{4,5}:\\/\\/)|[A-Z]+ )([^ :]*)",3,SyslogMessage),
|
| extend URL = extract("(([A-Z]+ [a-z]{4,5}:\\/\\/)|[A-Z]+ )([^ :]*)",3,SyslogMessage),
|
||||||
SourceIP = extract("([0-9]+ )(([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3}))",2,SyslogMessage),
|
SourceIP = extract("([0-9]+ )(([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3}))",2,SyslogMessage),
|
||||||
|
|
|
@ -2,11 +2,11 @@ id: e472c490-4792-4f12-8b6b-6ab3e0404d35
|
||||||
name: Squid data volume timeseries anomalies
|
name: Squid data volume timeseries anomalies
|
||||||
description: |
|
description: |
|
||||||
'Malware infections or data exfiltration activity often leads to anomalies in network data volume
|
'Malware infections or data exfiltration activity often leads to anomalies in network data volume
|
||||||
this hunting query looks for anomalies in the volume of bytes traversing a squid proxy. Anomalies require further
|
this hunting query looks for anomalies in the volume of bytes traversing a squid proxy. Anomalies require further
|
||||||
investigation to determine cause. This query presumes the default squid log format is being used.'
|
investigation to determine cause. This query presumes the default squid log format is being used.'
|
||||||
requiredDataConnectors:
|
requiredDataConnectors:
|
||||||
- connectorId: Syslog
|
- connectorId: Syslog
|
||||||
dataTypes:
|
dataTypes:
|
||||||
- Syslog
|
- Syslog
|
||||||
tactics:
|
tactics:
|
||||||
- CommandAndControl
|
- CommandAndControl
|
||||||
|
@ -16,16 +16,12 @@ relevantTechniques:
|
||||||
- T1030
|
- T1030
|
||||||
query: |
|
query: |
|
||||||
|
|
||||||
let starttime = 14d;
|
let TimeSeriesData =
|
||||||
let endtime = 1d;
|
|
||||||
let timeframe = 1h;
|
|
||||||
let TimeSeriesData =
|
|
||||||
Syslog
|
Syslog
|
||||||
| where TimeGenerated between (startofday(ago(starttime))..startofday(ago(endtime)))
|
|
||||||
| where ProcessName contains "squid"
|
| where ProcessName contains "squid"
|
||||||
| extend URL = extract("(([A-Z]+ [a-z]{4,5}:\\/\\/)|[A-Z]+ )([^ :]*)",3,SyslogMessage),
|
| extend URL = extract("(([A-Z]+ [a-z]{4,5}:\\/\\/)|[A-Z]+ )([^ :]*)",3,SyslogMessage),
|
||||||
SourceIP = extract("([0-9]+ )(([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3}))",2,SyslogMessage),
|
SourceIP = extract("([0-9]+ )(([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3}))",2,SyslogMessage),
|
||||||
Status = extract("(TCP_(([A-Z]+)(_[A-Z]+)*)|UDP_(([A-Z]+)(_[A-Z]+)*))",1,SyslogMessage),
|
Status = extract("(TCP_(([A-Z]+)(_[A-Z]+)*)|UDP_(([A-Z]+)(_[A-Z]+)*))",1,SyslogMessage),
|
||||||
HTTP_Status_Code = extract("(TCP_(([A-Z]+)(_[A-Z]+)*)|UDP_(([A-Z]+)(_[A-Z]+)*))/([0-9]{3})",8,SyslogMessage),
|
HTTP_Status_Code = extract("(TCP_(([A-Z]+)(_[A-Z]+)*)|UDP_(([A-Z]+)(_[A-Z]+)*))/([0-9]{3})",8,SyslogMessage),
|
||||||
User = extract("(CONNECT |GET )([^ ]* )([^ ]+)",3,SyslogMessage),
|
User = extract("(CONNECT |GET )([^ ]* )([^ ]+)",3,SyslogMessage),
|
||||||
RemotePort = extract("(CONNECT |GET )([^ ]*)(:)([0-9]*)",4,SyslogMessage),
|
RemotePort = extract("(CONNECT |GET )([^ ]*)(:)([0-9]*)",4,SyslogMessage),
|
||||||
|
@ -39,4 +35,3 @@ query: |
|
||||||
| extend (anomalies, score, baseline) = series_decompose_anomalies(TotalBytesSent,3, -1, 'linefit')
|
| extend (anomalies, score, baseline) = series_decompose_anomalies(TotalBytesSent,3, -1, 'linefit')
|
||||||
| extend timestamp = TimeGenerated
|
| extend timestamp = TimeGenerated
|
||||||
| render timechart with (title="Squid Time Series anomalies")
|
| render timechart with (title="Squid Time Series anomalies")
|
||||||
|
|
|
@ -17,14 +17,15 @@ tactics:
|
||||||
- Impact
|
- Impact
|
||||||
query: |
|
query: |
|
||||||
|
|
||||||
let dt_lookBack = 1h;
|
let starttime = todatetime('{{StartTimeISO}}');
|
||||||
|
let endtime = todatetime('{{EndTimeISO}}');
|
||||||
let ioc_lookBack = 14d;
|
let ioc_lookBack = 14d;
|
||||||
ThreatIntelligenceIndicator
|
ThreatIntelligenceIndicator
|
||||||
| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()
|
| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()
|
||||||
| where Active == true
|
| where Active == true
|
||||||
| where isnotempty(FileName)
|
| where isnotempty(FileName)
|
||||||
| join (
|
| join (
|
||||||
OfficeActivity| where TimeGenerated >= ago(dt_lookBack)
|
OfficeActivity| where TimeGenerated between(starttime..endtime)
|
||||||
| where isnotempty(SourceFileName)
|
| where isnotempty(SourceFileName)
|
||||||
| extend OfficeActivity_TimeGenerated = TimeGenerated
|
| extend OfficeActivity_TimeGenerated = TimeGenerated
|
||||||
)
|
)
|
||||||
|
|
|
@ -17,14 +17,15 @@ tactics:
|
||||||
- Impact
|
- Impact
|
||||||
query: |
|
query: |
|
||||||
|
|
||||||
let dt_lookBack = 1h;
|
let starttime = todatetime('{{StartTimeISO}}');
|
||||||
|
let endtime = todatetime('{{EndTimeISO}}');
|
||||||
let ioc_lookBack = 14d;
|
let ioc_lookBack = 14d;
|
||||||
ThreatIntelligenceIndicator
|
ThreatIntelligenceIndicator
|
||||||
| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()
|
| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()
|
||||||
| where Active == true
|
| where Active == true
|
||||||
| where isnotempty(FileName)
|
| where isnotempty(FileName)
|
||||||
| join (
|
| join (
|
||||||
SecurityEvent | where TimeGenerated >= ago(dt_lookBack)
|
SecurityEvent | where TimeGenerated between(starttime..endtime)
|
||||||
| where EventID in ("4688","8002","4648","4673")
|
| where EventID in ("4688","8002","4648","4673")
|
||||||
| where isnotempty(Process)
|
| where isnotempty(Process)
|
||||||
| extend SecurityEvent_TimeGenerated = TimeGenerated, Event = EventID
|
| extend SecurityEvent_TimeGenerated = TimeGenerated, Event = EventID
|
||||||
|
|
|
@ -17,7 +17,8 @@ tactics:
|
||||||
- Impact
|
- Impact
|
||||||
query: |
|
query: |
|
||||||
|
|
||||||
let dt_lookBack = 1h;
|
let starttime = todatetime('{{StartTimeISO}}');
|
||||||
|
let endtime = todatetime('{{EndTimeISO}}');
|
||||||
let ioc_lookBack = 14d;
|
let ioc_lookBack = 14d;
|
||||||
ThreatIntelligenceIndicator
|
ThreatIntelligenceIndicator
|
||||||
| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()
|
| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()
|
||||||
|
@ -25,7 +26,7 @@ query: |
|
||||||
| where isnotempty(FileName)
|
| where isnotempty(FileName)
|
||||||
| extend TI_ProcessEntity = tostring(split(FileName, ".")[-2])
|
| extend TI_ProcessEntity = tostring(split(FileName, ".")[-2])
|
||||||
| join (
|
| join (
|
||||||
Syslog | where TimeGenerated >= ago(dt_lookBack)
|
Syslog | where TimeGenerated between(starttime..endtime)
|
||||||
| where isnotempty(ProcessName)
|
| where isnotempty(ProcessName)
|
||||||
| extend Syslog_TimeGenerated = TimeGenerated
|
| extend Syslog_TimeGenerated = TimeGenerated
|
||||||
)
|
)
|
||||||
|
|
|
@ -17,7 +17,8 @@ tactics:
|
||||||
- Impact
|
- Impact
|
||||||
query: |
|
query: |
|
||||||
|
|
||||||
let dt_lookBack = 1h;
|
let starttime = todatetime('{{StartTimeISO}}');
|
||||||
|
let endtime = todatetime('{{EndTimeISO}}');
|
||||||
let ioc_lookBack = 14d;
|
let ioc_lookBack = 14d;
|
||||||
ThreatIntelligenceIndicator
|
ThreatIntelligenceIndicator
|
||||||
| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()
|
| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()
|
||||||
|
@ -25,7 +26,7 @@ query: |
|
||||||
| where isnotempty(FileName)
|
| where isnotempty(FileName)
|
||||||
| extend TI_ProcessEntity = tostring(split(FileName, ".")[-2])
|
| extend TI_ProcessEntity = tostring(split(FileName, ".")[-2])
|
||||||
| join (
|
| join (
|
||||||
VMConnection | where TimeGenerated >= ago(dt_lookBack)
|
VMConnection | where TimeGenerated between(starttime..endtime)
|
||||||
| where isnotempty(ProcessName)
|
| where isnotempty(ProcessName)
|
||||||
| extend VMConnection_TimeGenerated = TimeGenerated
|
| extend VMConnection_TimeGenerated = TimeGenerated
|
||||||
)
|
)
|
||||||
|
|
|
@ -17,14 +17,15 @@ tactics:
|
||||||
- Impact
|
- Impact
|
||||||
query: |
|
query: |
|
||||||
|
|
||||||
let dt_lookBack = 1h;
|
let starttime = todatetime('{{StartTimeISO}}');
|
||||||
|
let endtime = todatetime('{{EndTimeISO}}');
|
||||||
let ioc_lookBack = 14d;
|
let ioc_lookBack = 14d;
|
||||||
ThreatIntelligenceIndicator
|
ThreatIntelligenceIndicator
|
||||||
| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()
|
| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()
|
||||||
| where Active == true
|
| where Active == true
|
||||||
| where isnotempty(FileName)
|
| where isnotempty(FileName)
|
||||||
| join (
|
| join (
|
||||||
WireData | where TimeGenerated >= ago(dt_lookBack)
|
WireData | where TimeGenerated between(starttime..endtime)
|
||||||
| where isnotempty(ProcessName)
|
| where isnotempty(ProcessName)
|
||||||
| extend Process =reverse(substring(reverse(ProcessName), 0, indexof(reverse(ProcessName), "\\")))
|
| extend Process =reverse(substring(reverse(ProcessName), 0, indexof(reverse(ProcessName), "\\")))
|
||||||
| extend WireData_TimeGenerated = TimeGenerated
|
| extend WireData_TimeGenerated = TimeGenerated
|
||||||
|
|
|
@ -2,8 +2,8 @@ id: e0c947c3-fe83-46ff-bbda-a43224a785fd
|
||||||
name: Web Shell Activity
|
name: Web Shell Activity
|
||||||
description: |
|
description: |
|
||||||
'Web shells are scripts that, when uploaded to a web server, can be used to provide a backdoor to a compromised network.
|
'Web shells are scripts that, when uploaded to a web server, can be used to provide a backdoor to a compromised network.
|
||||||
Attackers can use this entry point to leave malicious implants, such as obtaining unauthorized access, escalating privilege, and further compromising the environment.
|
Attackers can use this entry point to leave malicious implants, such as obtaining unauthorized access, escalating privilege, and further compromising the environment.
|
||||||
|
|
||||||
This query hunts for web shells by analysing the distribution of commonly-used web shell scripts against regular scripts for those public client IPs which have not observed any W3CIIS activity in a fixed lookback period.
|
This query hunts for web shells by analysing the distribution of commonly-used web shell scripts against regular scripts for those public client IPs which have not observed any W3CIIS activity in a fixed lookback period.
|
||||||
The results obtained summarise the public client IPs, user agents, and the distribution of the above scripts between the start and end time.'
|
The results obtained summarise the public client IPs, user agents, and the distribution of the above scripts between the start and end time.'
|
||||||
requiredDataConnectors:
|
requiredDataConnectors:
|
||||||
|
@ -15,25 +15,25 @@ tactics:
|
||||||
- InitialAccess
|
- InitialAccess
|
||||||
relevantTechniques:
|
relevantTechniques:
|
||||||
- T1100
|
- T1100
|
||||||
query: |
|
query: |
|
||||||
|
|
||||||
let end_time = now();
|
let starttime = todatetime('{{StartTimeISO}}');
|
||||||
let start_time = end_time - timespan(1d);
|
let endtime = todatetime('{{EndTimeISO}}');
|
||||||
let lookback_time_from_start_time = timespan(3d);
|
let lookback = starttime - (3d);
|
||||||
let script_extensions = dynamic([".asp", ".aspx", ".armx", ".asax", ".ashz", ".asmx", ".axd", ".cshtml", ".php", ".phps", ".php3", ".php4", ".php5", ".php7", ".jsp", ".jspx", ".cfm", ".cfml", ".phtml"]);
|
let script_extensions = dynamic([".asp", ".aspx", ".armx", ".asax", ".ashz", ".asmx", ".axd", ".cshtml", ".php", ".phps", ".php3", ".php4", ".php5", ".php7", ".jsp", ".jspx", ".cfm", ".cfml", ".phtml"]);
|
||||||
let ignore_uristems = dynamic(["/ews/exchange.asmx"]);
|
let ignore_uristems = dynamic(["/ews/exchange.asmx"]);
|
||||||
let lookback_period = (
|
let lookback_period = (
|
||||||
W3CIISLog
|
W3CIISLog
|
||||||
| where TimeGenerated between ((start_time - lookback_time_from_start_time).. start_time)
|
| where TimeGenerated between (lookback .. starttime)
|
||||||
| where not(ipv4_is_private(cIP)) and cIP != "127.0.0.1"
|
| where not(ipv4_is_private(cIP)) and cIP != "127.0.0.1"
|
||||||
| summarize count() by cIP, csUserAgent
|
| summarize count() by cIP, csUserAgent
|
||||||
| project cIP, csUserAgent
|
| project cIP, csUserAgent
|
||||||
);
|
);
|
||||||
let potential_webshell_activity = (W3CIISLog
|
let potential_webshell_activity = (W3CIISLog
|
||||||
| where TimeGenerated between (start_time .. end_time)
|
| where TimeGenerated between (starttime .. endtime)
|
||||||
| extend csUriStem = tolower(csUriStem)
|
| extend csUriStem = tolower(csUriStem)
|
||||||
| where csUriStem matches regex "\\.[a-zA-Z][a-zA-Z0-9]+$"
|
| where csUriStem matches regex "\\.[a-zA-Z][a-zA-Z0-9]+$"
|
||||||
| where csUriStem !in~ (ignore_uristems) // Remove noisy uri stems in the final results by editing the ignore_uristems variable
|
| where csUriStem !in~ (ignore_uristems) // Remove noisy uri stems in the final results by editing the ignore_uristems variable
|
||||||
| extend suffix = strcat(".", split(split(csUriStem, "/")[-1], ".")[-1])
|
| extend suffix = strcat(".", split(split(csUriStem, "/")[-1], ".")[-1])
|
||||||
| extend is_script = iff(suffix in (script_extensions), 1, 0)
|
| extend is_script = iff(suffix in (script_extensions), 1, 0)
|
||||||
| where not(ipv4_is_private(cIP)) and cIP != "127.0.0.1"
|
| where not(ipv4_is_private(cIP)) and cIP != "127.0.0.1"
|
||||||
|
|
|
@ -2,10 +2,10 @@ id: 33aa0e01-87e2-43ea-87f9-2f7e3ff1d532
|
||||||
name: Detect beacon like pattern based on repetitive time intervals in Wire Data Traffic
|
name: Detect beacon like pattern based on repetitive time intervals in Wire Data Traffic
|
||||||
description: |
|
description: |
|
||||||
'This query will identify beaconing patterns from Wire Data logs based on timedelta patterns. The query leverages various KQL functions
|
'This query will identify beaconing patterns from Wire Data logs based on timedelta patterns. The query leverages various KQL functions
|
||||||
to calculate time delta and then compare it with total events observed in a day to find percentage of beaconing.
|
to calculate time delta and then compare it with total events observed in a day to find percentage of beaconing.
|
||||||
Results of such beaconing patterns to untrusted public networks can be a good starting point for investigation.
|
Results of such beaconing patterns to untrusted public networks can be a good starting point for investigation.
|
||||||
References: Blog about creating dataset to identify network beaconing via repetitive time intervals seen against total traffic
|
References: Blog about creating dataset to identify network beaconing via repetitive time intervals seen against total traffic
|
||||||
between same source-destination pair.
|
between same source-destination pair.
|
||||||
http://www.austintaylor.io/detect/beaconing/intrusion/detection/system/command/control/flare/elastic/stack/2017/06/10/detect-beaconing-with-flare-elasticsearch-and-intrusion-detection-systems/'
|
http://www.austintaylor.io/detect/beaconing/intrusion/detection/system/command/control/flare/elastic/stack/2017/06/10/detect-beaconing-with-flare-elasticsearch-and-intrusion-detection-systems/'
|
||||||
requiredDataConnectors:
|
requiredDataConnectors:
|
||||||
- connectorId: AzureMonitor(WireData)
|
- connectorId: AzureMonitor(WireData)
|
||||||
|
@ -18,30 +18,28 @@ relevantTechniques:
|
||||||
- T1065
|
- T1065
|
||||||
query: |
|
query: |
|
||||||
|
|
||||||
let starttime = 7d;
|
let lookback = 1d;
|
||||||
let endtime = 1d;
|
let TimeDeltaThreshold = 10;
|
||||||
let TimeDeltaThreshold = 10;
|
let TotalEventsThreshold = 15;
|
||||||
let TotalEventsThreshold = 15;
|
let PercentBeaconThreshold = 95;
|
||||||
let PercentBeaconThreshold = 95;
|
let PrivateIPregex = @'^127\.|^10\.|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-1]\.|^192\.168\.';
|
||||||
let PrivateIPregex = @'^127\.|^10\.|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-1]\.|^192\.168\.';
|
|
||||||
WireData
|
WireData
|
||||||
| where TimeGenerated between (ago(starttime)..ago(endtime))
|
| where TimeGenerated > lookback
|
||||||
| extend RemoteIPType = iff(RemoteIP matches regex PrivateIPregex,"private" ,"public" )
|
| extend RemoteIPType = iff(RemoteIP matches regex PrivateIPregex,"private" ,"public" )
|
||||||
| where RemoteIPType =="public"
|
| where RemoteIPType =="public"
|
||||||
| project TimeGenerated , LocalIP , LocalPortNumber , RemoteIP, RemotePortNumber, ReceivedBytes, SentBytes
|
| project TimeGenerated , LocalIP , LocalPortNumber , RemoteIP, RemotePortNumber, ReceivedBytes, SentBytes
|
||||||
| sort by LocalIP asc,TimeGenerated asc, RemoteIP asc, RemotePortNumber asc
|
| sort by LocalIP asc,TimeGenerated asc, RemoteIP asc, RemotePortNumber asc
|
||||||
| serialize
|
| serialize
|
||||||
| extend nextTimeGenerated = next(TimeGenerated, 1), nextLocalIP = next(LocalIP, 1)
|
| extend nextTimeGenerated = next(TimeGenerated, 1), nextLocalIP = next(LocalIP, 1)
|
||||||
| extend TimeDeltainSeconds = datetime_diff('second',nextTimeGenerated,TimeGenerated)
|
| extend TimeDeltainSeconds = datetime_diff('second',nextTimeGenerated,TimeGenerated)
|
||||||
| where LocalIP == nextLocalIP
|
| where LocalIP == nextLocalIP
|
||||||
//Whitelisting criteria/ threshold criteria
|
//Whitelisting criteria/ threshold criteria
|
||||||
| where TimeDeltainSeconds > TimeDeltaThreshold
|
| where TimeDeltainSeconds > TimeDeltaThreshold
|
||||||
| where RemotePortNumber != "0"
|
| where RemotePortNumber != "0"
|
||||||
| project TimeGenerated, TimeDeltainSeconds, LocalIP, LocalPortNumber,RemoteIP,RemotePortNumber, ReceivedBytes, SentBytes
|
| project TimeGenerated, TimeDeltainSeconds, LocalIP, LocalPortNumber,RemoteIP,RemotePortNumber, ReceivedBytes, SentBytes
|
||||||
| summarize count(), sum(ReceivedBytes), sum(SentBytes), make_list(TimeDeltainSeconds) by TimeDeltainSeconds, bin(TimeGenerated, 1h), LocalIP, RemoteIP, RemotePortNumber
|
| summarize count(), sum(ReceivedBytes), sum(SentBytes), make_list(TimeDeltainSeconds) by TimeDeltainSeconds, bin(TimeGenerated, 1h), LocalIP, RemoteIP, RemotePortNumber
|
||||||
| summarize (MostFrequentTimeDeltaCount, MostFrequentTimeDeltainSeconds)=arg_max(count_, TimeDeltainSeconds), TotalEvents=sum(count_), TotalSentBytes=sum(sum_SentBytes),TotalReceivedBytes=sum(sum_ReceivedBytes) by bin(TimeGenerated, 1h), LocalIP, RemoteIP, RemotePortNumber
|
| summarize (MostFrequentTimeDeltaCount, MostFrequentTimeDeltainSeconds)=arg_max(count_, TimeDeltainSeconds), TotalEvents=sum(count_), TotalSentBytes=sum(sum_SentBytes),TotalReceivedBytes=sum(sum_ReceivedBytes) by bin(TimeGenerated, 1h), LocalIP, RemoteIP, RemotePortNumber
|
||||||
| where TotalEvents > TotalEventsThreshold
|
| where TotalEvents > TotalEventsThreshold
|
||||||
| extend BeaconPercent = MostFrequentTimeDeltaCount/toreal(TotalEvents) * 100
|
| extend BeaconPercent = MostFrequentTimeDeltaCount/toreal(TotalEvents) * 100
|
||||||
| where BeaconPercent > PercentBeaconThreshold
|
| where BeaconPercent > PercentBeaconThreshold
|
||||||
| extend timestamp = TimeGenerated, IPCustomEntity = RemoteIP
|
| extend timestamp = TimeGenerated, IPCustomEntity = RemoteIP
|
||||||
|
|
|
@ -9,14 +9,13 @@ relevantTechniques:
|
||||||
- T1078
|
- T1078
|
||||||
query: |
|
query: |
|
||||||
|
|
||||||
let hunt_time = 1d;
|
|
||||||
let previous_tz = (
|
let previous_tz = (
|
||||||
ZoomLogs
|
ZoomLogs
|
||||||
| where Event =~ "meeting.participant_joined"
|
| where Event =~ "meeting.participant_joined"
|
||||||
| extend TimeZone = columnifexists('payload_object_timezone_s', "")
|
| extend TimeZone = columnifexists('payload_object_timezone_s', "")
|
||||||
| summarize by TimeZone
|
| summarize by TimeZone
|
||||||
);
|
);
|
||||||
ZoomLogs
|
ZoomLogs
|
||||||
| where Event =~ "meeting.participant_joined"
|
| where Event =~ "meeting.participant_joined"
|
||||||
| extend TimeZone = columnifexists('payload_object_timezone_s', "")
|
| extend TimeZone = columnifexists('payload_object_timezone_s', "")
|
||||||
| where isnotempty(TimeZone) and TimeZone in (previous_tz)
|
| where isnotempty(TimeZone) and TimeZone in (previous_tz)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче