共用方式為


將 Splunk 偵測規則移轉至 Microsoft Sentinel

Splunk 偵測規則是安全性資訊和事件管理 (SIEM) 元件,與 Sentinel Microsoft 中的分析規則相比較。 本文說明識別、比較和遷移至 Sentinel Microsoft的概念。 最佳方式是從 SIEM 遷移經驗開始,其會識別現成可用的(OOTB)分析規則,以自動轉譯這些規則。

如果您想要移轉 Splunk 可檢視性部署,請深入瞭解如何 從 Splunk 移轉至 Azure 監視器記錄

稽核規則

Microsoft Sentinel 會使用機器學習分析來建立高精確度且可採取動作的事件。 某些現有的 Splunk 偵測在Microsoft Sentinel 中可能是多餘的,因此不要盲目移轉它們。 當您識別現有的偵測規則時,請檢閱這些考量事項。

  • 請務必選取可證明規則移轉的使用案例,考慮商務優先順序和效率。
  • 請確認您 了解 Microsoft Sentinel 規則類型
  • 請檢查您了解 規則術語
  • 檢閱過去 6-12 個月沒有警示的過時規則,並判斷它們是否仍然相關。
  • 消除您定期忽略的低階威脅或警示。
  • 確認已連線的資料來源,並檢閱資料連線方法。 Microsoft Sentinel Analytics 要求在啟用規則之前,數據類型會出現在 Log Analytics 工作區中。 回顧覽資料收集交談,以確認您打算在使用案例上偵測的資料深度和廣度。 然後使用 SIEM 移轉體驗 來確保數據源已適當對應。

移轉規則

識別要移轉的 Splunk 偵測之後,請檢閱移轉程式的下列考慮:

  • 比較Microsoft Sentinel 的 OOTB 分析規則與目前使用案例的現有功能。 使用 SIEM 移轉體驗 來查看哪些 Splunk 偵測會自動轉換成 OOTB 範本。
  • 轉譯不符合 OOTB 分析規則的偵測。 自動轉譯 Splunk 偵測的最佳方式是 搭配 SIEM 移轉體驗
  • 探索 SOC Prime Threat Detection Marketplace 等社群資源,以探索更多使用案例的演算法。
  • 如果無法使用或未自動翻譯內建規則,請手動轉譯偵測。 建立新的 KQL 查詢,並檢閱 規則對應

如需詳細資訊,請參閱 移轉偵測規則的最佳做法

規則移轉步驟

  1. 請確認已備妥測試系統來處理您要移轉的每個規則。

    1. 準備移轉規則的驗證程式,包括完整的測試案例和腳本。

    2. 請確定您的小組有實用的資源 來測試已移轉的規則。

    3. 確認您已連線必要的數據源, 並檢閱您的數據連線方法。

  2. 確認您的偵測是否在 Microsoft Sentinel 中以 OOTB 範本的形式提供:

    • 使用 SIEM 移轉體驗 ,將 OOTB 範本的翻譯和安裝自動化。

      如需詳細資訊,請參閱 使用 SIEM 移轉體驗

    • 如果您有未反映在偵測中的使用案例,請使用 OOTB 規則範本為您自己的工作區建立規則。

      在 Microsoft Sentinel 中,前往 內容中樞

      篩選分析規則範本的內容類型

      尋找並 安裝/更新 每個對應的內容中樞解決方案或獨立分析規則範本。

      如需詳細資訊,請參閱 開箱即用的威脅偵測功能

    • 如果您有Microsoft Sentinel 的 OOTB 規則未涵蓋的偵測,請先嘗試 SIEM 移轉體驗 進行自動轉譯。

    • 如果 OOTB 規則和 SIEM 移轉都無法完全轉譯偵測,請手動建立規則。 在這種情況下,請使用下列步驟來建立規則:

      1. 識別您想要在規則中使用的數據來源。 藉由建立數據源與數據表之間的對應數據表,來識別您想要查詢的Microsoft Sentinel 數據表。

      2. 識別您想要在規則中使用的數據中的任何屬性、欄位或實體

      3. 識別您的規則準則和邏輯。 在這個階段,請考慮尋找規則範本作為如何建構 KQL 查詢的範例。

        請考慮篩選、相互關聯規則、作用中清單、參考集、關注清單、偵測異常、彙總等等。 您可以使用舊版 SIEM 所提供的參考,瞭解如何最好地映射查詢語法

      4. 識別觸發條件和規則動作,然後建構並檢閱您的 KQL 查詢。 檢閱查詢時,請考慮 KQL 最佳化指引資源。

  3. 使用每個相關使用案例測試規則。 如果它未提供預期的結果,請檢閱並編輯 KQL 並再次進行測試。

  4. 當您滿意時,請考慮移轉的規則。 視需要為您的規則動作建立劇本。 如需詳細資訊,請參閱 在 Microsoft sentinel 中使用劇本將威脅回應自動化

深入了解分析規則:

比較規則術語

相較於以搜尋處理語言 (SPL) 為基礎的 Splunk 偵測,下表可協助您釐清Microsoft Sentinel 中以 Kusto 查詢語言 (KQL) 為基礎的規則概念。

Splunk (英语) Microsoft Sentinel
規則類型 • 已排程
• 即時
• 排程的查詢
• 融合
• Microsoft 安全性
• Machine Learning (ML) 行為分析
標準 在 SPL 中定義 在 KQL 中定義
觸發條件 • 結果數目
• 主機數目
• 來源數目
• 自訂
閾值:查詢結果數目
行動 • 新增至觸發的警示
• 記錄事件
• 要查閱的輸出結果
• 及其他
• 建立警示或事件
• 與 Logic Apps 整合

對應和比較規則範例

使用這些範例,在各種案例中從 Splunk 到 Microsoft Sentinel 比較和對應規則。

常見的搜尋命令

SPL 命令 描述 KQL 運算子 KQL 範例
chart/ timechart 以表格式輸出傳回結果來繪製時間序列圖表。 render 運算子 … | render timechart
dedup 移除符合指定準則的後續結果。 不同
匯總
… | summarize by Computer, EventID
eval 計算運算式。 瞭解 一般 eval 命令 擴展 T | extend duration = endTime - startTime
fields 從搜尋結果中移除欄位。 專案
項目離開
T | project cost=price*quantity, price
head/tail 傳回前 N 個或最後 N 個結果。 返回頁首 T | top 5 by Name desc nulls last
lookup 從外部來源新增欄位值。 外部數據
查閱
KQL 範例
rename 重新命名欄位。 使用萬用字元來指定多個欄位。 專案重新命名 T | project-rename new_column_name = column_name
rex 使用規則運算式指定群組名稱來擷取欄位。 符合 regex … | where field matches regex "^addr.*"
search 將結果篩選為符合搜尋運算式的結果。 搜索 search "X"
sort 依指定的欄位排序搜尋結果。 排序 T | sort by strlen(country) asc, price desc
stats 提供統計資料,可選擇依欄位分組。 深入瞭解 常見的統計數據命令 總結 KQL 範例
mstats 類似於 stats,用於計量而非事件。 總結 KQL 範例
table 指定要保留在結果集的欄位,並以表格式格式保留資料。 專案 T | project columnA, columnB
top/rare 顯示欄位最常見或最不常見的值。 返回頁首 T | top 5 by Name desc nulls last
transaction 將搜尋結果分組成交易。

SPL 範例
範例: row_window_session KQL 範例
eventstats 從事件中的欄位產生摘要統計資料,並將這些統計資料儲存在新欄位中。

SPL 範例
範例:
聯結
make_list
MV 擴展
KQL 範例
streamstats 尋找欄位的累計總和。

SPL 範例:
... | streamstats sum(bytes) as bytes _ total \| timechart
行累加和 ...\| serialize cs=row_cumsum(bytes)
anomalydetection 在指定的欄位中尋找異常。

SPL 範例
series_decompose_anomalies() KQL 範例
where 使用 eval 運算式篩選搜尋結果。 用來比較兩個不同的欄位。 哪裡 T | where fruit=="apple"

lookup 命令:KQL 範例

Users 
| where UserID in ((externaldata (UserID:string) [
@"https://storageaccount.blob.core.windows.net/storagecontainer/users.txt" 
h@"?...SAS..." // Secret token to access the blob 
])) | ... 

stats 命令:KQL 範例

Sales 
| summarize NumTransactions=count(), 
Total=sum(UnitPrice * NumUnits) by Fruit, 
StartOfMonth=startofmonth(SellDateTime) 

mstats 命令:KQL 範例

T | summarize count() by price_range=bin(price, 10.0) 

transaction 命令:SPL 範例

sourcetype=MyLogTable type=Event
| transaction ActivityId startswith="Start" endswith="Stop"
| Rename timestamp as StartTime
| Table City, ActivityId, StartTime, Duration

transaction 命令:KQL 範例

let Events = MyLogTable | where type=="Event";
Events
| where Name == "Start"
| project Name, City, ActivityId, StartTime=timestamp
| join (Events
| where Name == "Stop"
| project StopTime=timestamp, ActivityId)
on ActivityId
| project City, ActivityId, StartTime, 
Duration = StopTime – StartTime

用來 row_window_session() 計算串行化數據列集中數據行的會話開始值。

...| extend SessionStarted = row_window_session(
Timestamp, 1h, 5m, ID != prev(ID))

eventstats 命令:SPL 範例

… | bin span=1m _time
|stats count AS count_i by _time, category
| eventstats sum(count_i) as count_total by _time

eventstats 命令:KQL 範例

以下是 join 陳述式的範例:

let binSize = 1h;
let detail = SecurityEvent 
| summarize detail_count = count() by EventID,
tbin = bin(TimeGenerated, binSize);
let summary = SecurityEvent
| summarize sum_count = count() by 
tbin = bin(TimeGenerated, binSize);
detail 
| join kind=leftouter (summary) on tbin 
| project-away tbin1

以下是 make_list 陳述式的範例:

let binSize = 1m;
SecurityEvent
| where TimeGenerated >= ago(24h)
| summarize TotalEvents = count() by EventID, 
groupBin =bin(TimeGenerated, binSize)
|summarize make_list(EventID), make_list(TotalEvents), 
sum(TotalEvents) by groupBin
| mvexpand list_EventID, list_TotalEvents

anomalydetection 命令:SPL 範例

sourcetype=nasdaq earliest=-10y
| anomalydetection Close _ Price

anomalydetection 命令:KQL 範例

let LookBackPeriod= 7d;
let disableAccountLogon=SignIn
| where ResultType == "50057"
| where ResultDescription has "account is disabled";
disableAccountLogon
| make-series Trend=count() default=0 on TimeGenerated 
in range(startofday(ago(LookBackPeriod)), now(), 1d)
| extend (RSquare,Slope,Variance,RVariance,Interception,
LineFit)=series_fit_line(Trend)
| extend (anomalies,score) = 
series_decompose_anomalies(Trend)

一般 eval 命令

SPL 命令 描述 SPL 範例 KQL 命令 KQL 範例
abs(X) 傳回 X 的絕對值。 abs(number) abs() abs(X)
case(X,"Y",…) 接受 XY 引數的配對,其中 X 引數是布林運算式。 評估為 TRUE 時,引數會傳回對應的 Y 引數。 SPL 範例 case KQL 範例
ceil(X) 數字 X 的上限。 ceil(1.9) ceiling() ceiling(1.9)
cidrmatch("X",Y) 識別屬於特定子網路的 IP 位址。 cidrmatch
("123.132.32.0/25",ip)
ipv4_is_match()
ipv6_is_match()
ipv4_is_match('192.168.1.1', '192.168.1.255')
== false
coalesce(X,…) 傳回不是 null 的第一個值。 coalesce(null(), "Returned val", null()) coalesce() coalesce(tolong("not a number"),
tolong("42"), 33) == 42
cos(X) 計算 X 的餘弦。 n=cos(0) cos() cos(X)
exact(X) 使用雙精確度浮點算術評估運算式 X。 exact(3.14*num) todecimal() todecimal(3.14*2)
exp(X) 傳回 eX。 exp(3) exp() exp(3)
if(X,Y,Z) 如果 X 評估為 TRUE,則結果為第二個引數 Y。 如果 X 評估為 FALSE,則結果會評估為第三個引數 Z if(error==200,
"OK", "Error")
iff() KQL 範例
isbool(X) 如果 TRUE 為布林值,則傳回 X isbool(field) iff()
gettype
iff(gettype(X) =="bool","TRUE","FALSE")
isint(X) 如果 TRUE 是整數,則傳回 X isint(field) iff()
gettype
KQL 範例
isnull(X) 如果 TRUE 為 null,則傳回 X isnull(field) isnull() isnull(field)
isstr(X) 如果 TRUE 為字串,則會傳回 X isstr(field) iff()
gettype
KQL 範例
len(X) 此函式傳回字串 X 的字元長度。 len(field) strlen() strlen(field)
like(X,"y") 只有在 TRUE 類似 X 中的 SQLite 模式時,才會傳回 Y like(field, "addr%") has
contains
startswith
符合 regex
KQL 範例
log(X,Y) 使用第二個引數 X 作為底數,傳回第一個引數 Y 的對數。 Y 的預設值為 10 log(number,2) log
log2
log10
log(X)

log2(X)

log10(X)
lower(X) 傳回 X 的小寫值。 lower(username) tolower tolower(username)
ltrim(X,Y) 傳回從左側修剪參數 X 中的字元後的 YY 的預設輸出是空格和定位字元。 ltrim(" ZZZabcZZ ", " Z") trim_start() trim_start(“ ZZZabcZZ”,” ZZZ”)
match(X,Y) 如果 X 符合 RegEx 模式 Y,則傳回。 match(field, "^\d{1,3}.\d$") matches regex … | where field matches regex @"^\d{1,3}.\d$")
max(X,…) 傳回資料行中的最大值。 max(delay, mydelay) max()
arg_max()
… | summarize max(field)
md5(X) 傳回字串值 X 的 MD5 雜湊。 md5(field) hash_md5 hash_md5("X")
min(X,…) 傳回資料行中的最小值。 min(delay, mydelay) min_of()
min()
arg_min
KQL 範例
mvcount(X) 傳回 X 值的數目 (總數)。 mvcount(multifield) dcount …| summarize dcount(X) by Y
mvfilter(X) 根據布林 X 運算式篩選多重值欄位。 mvfilter(match(email, "net$")) mv-apply KQL 範例
mvindex(X,Y,Z) 傳回多重值 X 引數從開始位置 (從零開始) YZ (選擇性) 的子集。 mvindex( multifield, 2) array_slice array_slice(arr, 1, 2)
mvjoin(X,Y) 已知多重值欄位 X 和字串分隔符號 Y,使用 X 聯結 Y 的個別值。 mvjoin(address, ";") strcat_array KQL 範例
now() 傳回以 Unix 時間表示的目前時間。 now() now() now()

now(-2d)
null() 不接受引數並傳回 NULL null() null
nullif(X,Y) 包含兩個引數 XY,如果引數不同,則傳回 X。 否則傳回 NULL nullif(fieldA, fieldB) iff iff(fieldA==fieldB, null, fieldA)
random() 傳回 02147483647 之間的虛擬隨機數。 random() rand() rand()
relative_ time(X,Y) 已知 Epoch 時間 X 和相對時間規範 Y,傳回將 Y 套用至 X 後的 Epoch 時間值。 relative_time(now(),"-1d@d") UNIX 時間 KQL 範例
replace(X,Y,Z) 傳回以字串 Z 取代 Y 字串中出現的每個規則運算式字串 X 而形成的字串。 傳回月份和日期數字交換後的日期。
例如,以 4/30/2015 為例,輸出為 30/4/2009

replace(date, "^(\d{1,2})/ (\d{1,2})/", "\2/\1/")
replace() KQL 範例
round(X,Y) 傳回以 X 指定的小數位數四捨五入的 Y。 預設是四捨五入為整數。 round(3.5) round round(3.5)
rtrim(X,Y) 傳回從右側修剪字元 X 後的 Y。 如果未指定 Y,則會修剪空格和定位字元。 rtrim(" ZZZZabcZZ ", " Z") trim_end() trim_end(@"[ Z]+",A)
searchmatch(X) 如果事件符合搜尋字串 TRUE,則傳回 X searchmatch("foo AND bar") iff() iff(field has "X","Yes","No")
split(X,"Y") 以多重值欄位的形式傳回 X,並以分隔符號 Y 分割。 split(address, ";") split() split(address, ";")
sqrt(X) 傳回 X 的平方根。 sqrt(9) sqrt() sqrt(9)
strftime(X,Y) 傳回使用 X 指定的格式轉譯的 Epoch 時間值 Y strftime(_time, "%H:%M") format_datetime() format_datetime(time,'HH:mm')
strptime(X,Y) 已知字串 X 代表的時間,傳回從格式 Y 剖析的值。 strptime(timeStr, "%H:%M") format_datetime() KQL 範例
substr(X,Y,Z) 傳回從開始位置 (從零開始) XY 個 (選擇性) 字元的子字串欄位 Z substr("string", 1, 3) substring() substring("string", 0, 3)
time() 傳回精確至微秒的時鐘時間。 time() format_datetime() KQL 範例
tonumber(X,Y) 將輸入字串 X 轉換成數字,其中 Y (選擇性,預設值為 10) 定義要轉換成的數字底數。 tonumber("0A4",16) toint() toint("123")
tostring(X,Y) 描述 SPL 範例 tostring() tostring(123)
typeof(X) 傳回欄位型別的字串表示法。 typeof(12) gettype() gettype(12)
urldecode(X) 傳回已解碼的 URL X SPL 範例 url_decode KQL 範例

case(X,"Y",…) SPL 範例

case(error == 404, "Not found",
error == 500,"Internal Server Error",
error == 200, "OK")

case(X,"Y",…) KQL 範例

T
| extend Message = case(error == 404, "Not found", 
error == 500,"Internal Server Error", "OK") 

if(X,Y,Z) KQL 範例

iif(floor(Timestamp, 1d)==floor(now(), 1d), 
"today", "anotherday")

isint(X) KQL 範例

iif(gettype(X) =="long","TRUE","FALSE")

isstr(X) KQL 範例

iif(gettype(X) =="string","TRUE","FALSE")

like(X,"y")

… | where field has "addr"

… | where field contains "addr"

… | where field startswith "addr"

… | where field matches regex "^addr.*"

min(X,…) KQL 範例

min_of (expr_1, expr_2 ...)

…|summarize min(expr)

…| summarize arg_min(Price,*) by Product

mvfilter(X) KQL 範例

T | mv-apply Metric to typeof(real) on 
(
 top 2 by Metric desc
)

mvjoin(X,Y) KQL 範例

strcat_array(dynamic([1, 2, 3]), "->")

relative time(X,Y) KQL 範例

let toUnixTime = (dt:datetime)
{
(dt - datetime(1970-01-01))/1s 
};

replace(X,Y,Z) KQL 範例

replace( @'^(\d{1,2})/(\d{1,2})/', @'\2/\1/',date)

strptime(X,Y) KQL 範例

format_datetime(datetime('2017-08-16 11:25:10'),
'HH:mm')

time() KQL 範例

format_datetime(datetime(2015-12-14 02:03:04),
'h:m:s')

tostring(X,Y)

以字串形式傳回 X 的欄位值。

  • 如果 X 的值是數字,則 X 重新格式化為字串值。
  • 如果 X 是布林值, 則 X 重新格式化為 TRUEFALSE
  • 如果 X 是數字,則第二個引數 Y 是選擇性,可以是 hex (將 X 轉換成十六進位)、commas (以逗號和兩個小數位數來格式化 X),或 duration (將 X 從以秒為單位的時間格式轉換成看得懂的時間格式:HH:MM:SS)。
tostring(X,Y) SPL 範例

此範例傳回:

foo=615 and foo2=00:10:15:

… | eval foo=615 | eval foo2 = tostring(
foo, "duration")

urldecode(X) SPL 範例

urldecode("http%3A%2F%2Fwww.splunk.com%2Fdownload%3Fr%3Dheader")

常見的 stats 命令 KQL 範例

SPL 命令 描述 KQL 命令 KQL 範例
avg(X) 傳回欄位 X 的平均值。 avg() avg(X)
count(X) 傳回欄位 X 的出現次數。 若要指出要比對的特定欄位值,請將 X 格式化為 eval(field="value") count() summarize count()
dc(X) 傳回欄位 X 的相異值計數。 dcount() …\| summarize countries=dcount(country) by continent
earliest(X) 傳回 X 的最早時序值。 arg_min() … \| summarize arg_min(TimeGenerated, *) by X
latest(X) 傳回 X 的最晚時序值。 arg_max() … \| summarize arg_max(TimeGenerated, *) by X
max(X) 傳回欄位 X 的最大值。 如果 X 的值不是數值,則透過字母順序找到最大值。 max() …\| summarize max(X)
median(X) 傳回欄位 X 的最中間值。 percentile() …\| summarize percentile(X, 50)
min(X) 傳回欄位 X 的最小值。 如果 X 的值不是數值,則透過字母順序找到最小值。 min() …\| summarize min(X)
mode(X) 傳回欄位 X 中最常出現的值。 top-hitters() …\| top-hitters 1 of Y by X
perc(Y) 傳回 X 欄位的第 Y 個百分位值。 例如,perc5(total) 傳回欄位 total 的第五個百分位值。 percentile() …\| summarize percentile(Y, 5)
range(X) 傳回欄位 X 的最大值和最小值之間的差異。 range() range(1, 3)
stdev(X) 傳回欄位 X 的樣本標準差。 stdev stdev()
stdevp(X) 取得欄位 X 的母體標準差。 stdevp() stdevp()
sum(X) 傳回欄位 X 的值總和。 sum() sum(X)
sumsq(X) 傳回欄位 X 的平方值總和。
values(X) 以多重值項目傳回欄位 X 的所有相異值清單。 值依字母順序排列。 make_set() …\| summarize r = make_set(X)
var(X) 傳回欄位 X 的樣本變異數。 方差 variance(X)

下一步

在本文中,您已了解如何將移轉規則從 Splunk 對應至 Microsoft Sentinel。