Поделиться через


Перенос правил обнаружения Splunk в Microsoft Sentinel

Правила обнаружения Splunk — это компоненты безопасности и управления событиями (SIEM), которые сравниваются с правилами аналитики в Microsoft Sentinel. В этой статье описываются основные понятия для определения, сравнения и переноса их в Microsoft Sentinel. Лучший способ — начать с интерфейса миграции SIEM, который определяет правила аналитики вне поля (OOTB) для автоматического перевода.

Если вы хотите перенести развертывание Splunk Observability, узнайте больше о том, как выполнить миграцию из Splunk в журналы Azure Monitor.

Правила аудита

Microsoft Sentinel использует аналитику машинного обучения для создания высокоуровневых и практических инцидентов. Некоторые из существующих обнаружений Splunk могут быть избыточными в Microsoft Sentinel, поэтому не переносите их все вслепую. При определении существующих правил обнаружения необходимо учитывать следующие рекомендации.

  • Обязательно выберите варианты использования, которые позволят согласовать перенос правил, учитывая приоритетность и эффективность для бизнеса.
  • Убедитесь, что вы понимаете типы правил Microsoft Sentinel.
  • Убедитесь, что вы понимаете терминологию правил.
  • Просмотрите устаревшие правила, которые не имеют оповещений за последние 6-12 месяцев, и определите, имеют ли они все еще релевантные.
  • Устраните низкоуровневые угрозы или оповещения, которые обычно игнорируются.
  • Убедитесь, что источники данных подключены, и проверьте методы подключения к данным. Microsoft Sentinel Analytics требует, чтобы тип данных присутствовал в рабочей области Log Analytics перед включением правила. Повторно рассмотрите сбор данных, чтобы обеспечить глубину и обширность данных в различных вариантах использования, которые планируется обнаруживать. Затем используйте интерфейс миграции SIEM, чтобы убедиться, что источники данных сопоставляются соответствующим образом.

Миграция правил

После идентификации обнаружения Splunk для миграции просмотрите следующие рекомендации по процессу миграции:

  • Сравните существующие функции правил аналитики OOTB Microsoft Sentinel с текущими вариантами использования. Используйте интерфейс миграции SIEM, чтобы узнать, какие обнаружения Splunk автоматически преобразуются в шаблоны OOTB.
  • Перевод обнаружения, которые не соответствуют правилам аналитики OOTB. Лучший способ автоматического перевода обнаружения Splunk — с помощью интерфейса миграции SIEM.
  • Узнайте больше алгоритмов для вариантов использования, изучая ресурсы сообщества, такие как SOC Prime Threat Detection Marketplace.
  • Автоматически переводить обнаружения, если встроенные правила недоступны или не переведены автоматически. Создайте новые запросы KQL и просмотрите сопоставление правил.

Дополнительные сведения см . в рекомендациях по переносу правил обнаружения.

Действия по миграции правил

  1. Убедитесь в наличии системы тестирования для каждого правила, которое необходимо перенести.

    1. Подготовьте процесс проверки перенесенных правил, включая скрипты и сценарии полного тестирования.

    2. Убедитесь, что у вашей команды есть полезные ресурсы для тестирования перенесенных правил.

    3. Убедитесь, что у вас есть необходимые источники данных, и проверьте методы подключения к данным.

  2. Проверьте, доступны ли обнаружения как шаблоны OOTB в Microsoft Sentinel:

    • Используйте интерфейс миграции SIEM для автоматизации перевода и установки шаблонов OOTB.

      Дополнительные сведения см. в разделе "Использование интерфейса миграции SIEM".

    • Если варианты использования не отражены в обнаружении, создайте правила для собственной рабочей области с помощью шаблонов правил OOTB.

      В Microsoft Sentinel перейдите в центр содержимого.

      Фильтруйте тип контента для шаблонов правил Аналитики.

      Найдите и обновите каждое соответствующее решение концентратора контента или шаблон правила автономной аналитики.

      Дополнительные сведения см. в разделе Встроенное обнаружение угроз.

    • Если у вас есть обнаружения, которые не охватываются правилами OOTB Microsoft Sentinel, сначала попробуйте выполнить миграцию SIEM для автоматического перевода.

    • Если ни правила OOTB, ни миграция SIEM полностью не преобразуют обнаружение, создайте правило вручную. В таких случаях выполните следующие действия, чтобы создать правило:

      1. Определите источники данных, которые будут использоваться в правиле. Определите таблицы Microsoft Sentinel, которые нужно запросить, создав таблицу сопоставления между источниками данных и таблицами данных.

      2. Определите все атрибуты, поля или сущности в данных, которые будут использоваться в правилах.

      3. Определите критерии и логику правила. На этом этапе рекомендуется найти шаблоны правил в качестве примеров для создания запросов KQL.

        Рассмотрите фильтры, правила корреляции, активные списки, эталонные наборы, списки видео к просмотру, аномалии обнаружения, агрегаты и т. д. Вы можете использовать справочные материалы, предоставляемые устаревшим решением SIEM, чтобы понять, как лучше сопоставить синтаксис запросов.

      4. Определите условие триггера и действие правила, а затем создайте и просмотрите запрос KQL. При просмотре запроса учтите рекомендации по оптимизации KQL.

  3. Протестируйте правило для каждого соответствующего ему варианта использования. Если он не предоставляет ожидаемые результаты, просмотрите и измените KQL и проверьте его еще раз.

  4. Когда вы удовлетворены, рассмотрите правило, перенесенное. При необходимости создайте сборник схем для действия правила. Дополнительные сведения см. в разделе Автоматизация реагирования на угрозы с помощью сборников схем в Microsoft Sentinel.

См. правила аналитики:

Сравнение терминологии правил

Эта таблица помогает уточнить концепцию правила на основе язык запросов Kusto (KQL) в Microsoft Sentinel по сравнению с обнаружением Splunk на основе языка обработки поиска (SPL).

Splunk Microsoft Sentinel
Тип правила • Запланировано
• В режиме реального времени
• Запланированный запрос
• Слияние
• Безопасность Microsoft
• Аналитика поведения для машинного обучения (ML)
Критерии Определение в SPL Определение в KQL
Условие активации • Число результатов
• Число узлов
• Количество источников
• Пользовательское
Порог: количество результатов запроса
Действие • Добавление в активированные оповещения
• Регистрация события в журнале
• Выходные результаты для поиска
• И прочее
• Создание оповещения или инцидента
• Интеграция с Logic Apps

Сопоставление и сравнение примеров правил

Используйте эти примеры для сравнения и сопоставления правил из Splunk с Microsoft Sentinel в различных сценариях.

Распространенные команды поиска

Команда SPL Description Оператор KQL Пример KQL
chart/ timechart Возвращает результаты в виде таблицы для диаграмм временных рядов. Оператор отрисовки … | render timechart
dedup Удаляет последующие результаты, соответствующие указанному критерию. • distinct
• summarize
… | summarize by Computer, EventID
eval Вычисляет выражение. Узнайте о распространенных eval командах. extend T | extend duration = endTime - startTime
fields Удаляет поля из результатов поиска. • project
• project-away
T | project cost=price*quantity, price
head/tail Возвращает первые или последние N результатов. top T | top 5 by Name desc nulls last
lookup Добавляет значения полей из внешнего источника. • externaldata
• lookup
Пример KQL
rename Переименовывает поле. Используйте подстановочные знаки для указания нескольких полей. project-rename T | project-rename new_column_name = column_name
rex Задает имена групп с помощью регулярных выражений для извлечения полей. совпадения регулярных выражений … | where field matches regex "^addr.*"
search Отфильтровывает результаты до результатов, соответствующих выражению поиска. search search "X"
sort Сортирует результаты поиска по указанным полям. sort T | sort by strlen(country) asc, price desc
stats Предоставляет статистику, при необходимости сгруппированную по полям. Подробнее о распространенных командах stats. summarize Пример KQL
mstats Аналогична команде stats, используется для метрик вместо событий. summarize Пример KQL
table Указывает поля, которые следует сохранить в результирующем наборе, и сохраняет данные в табличном формате. project T | project columnA, columnB
top/rare Отображает наиболее или наименее распространенные значения поля. top T | top 5 by Name desc nulls last
transaction Группирует результаты поиска в транзакции.

Пример SPL
Пример: row_window_session Пример KQL
eventstats Создает сводную статистику на основе полей в событиях и сохраняет эту статистику в новом поле.

Пример SPL
Примеры:
• соединение
make_list
• mv-expand
Пример KQL
streamstats Найдите совокупную сумму поля.

Пример SPL:
... | streamstats sum(bytes) as bytes _ total \| timechart
row_cumsum ...\| serialize cs=row_cumsum(bytes)
anomalydetection Найдите аномалии в указанном поле.

Пример SPL
series_decompose_anomalies() Пример KQL
where Отфильтровывает результаты поиска с помощью выражений eval. Используется для сравнения двух разных полей. where 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 Description Пример SPL Команда KQL Пример KQL
abs(X) Возвращает абсолютное значение X. abs(number) abs() abs(X)
case(X,"Y",…) Принимает пары X и Y аргументы, где 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")
iif() Пример KQL
isbool(X) Возвращает значение TRUE, если X — логическое значение. isbool(field) iif()
gettype
iif(gettype(X) =="bool","TRUE","FALSE")
isint(X) Возвращает TRUE, если X является целым числом. isint(field) iif()
gettype
Пример KQL
isnull(X) Возвращает TRUE, если X равно NULL. isnull(field) isnull() isnull(field)
isstr(X) Возвращает TRUE, если X является строкой. isstr(field) iif()
gettype
Пример KQL
len(X) Эта функция возвращает количество символов в строке X. len(field) strlen() strlen(field)
like(X,"y") Возвращает значение TRUE в том и только в том случае, если X аналогично шаблону SQLite в Y. like(field, "addr%") has
contains
startswith
• matches 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 с символами в параметре Y, обрезанными слева. Выходные данные Y по умолчанию — пробелы и отступы. ltrim(" ZZZabcZZ ", " Z") trim_start() trim_start(“ ZZZabcZZ”,” ZZZ”)
match(X,Y) Возвращает значение, если X совпадает с шаблоном регулярного выражения 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) Возвращает хэш MD5 строкового значения X. 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 с начальной позиции (от нуля) Y до Z (необязательно). 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 null
nullif(X,Y) Включает два аргумента X и Y и возвращает X, если аргументы отличаются. В противном случае возвращается NULL. nullif(fieldA, fieldB) iif iif(fieldA==fieldB, null, fieldA)
random() Возвращает псевдослучайное число между 0 и 2147483647. random() rand() rand()
relative_ time(X,Y) Принимает время эпохи X и относительный описатель времени Y, возвращает значение времени эпохи Y, примененное к X. relative_time(now(),"-1d@d") unix time Пример 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") iif() iif(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, отображаемое с использованием формата, заданного параметром 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) Возвращает поле подстроки X с начальной позиции (на основе единицы) Y для 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) Description Пример 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 переформатируется в TRUE или FALSE.
  • Если 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 Description Команда 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 variance(X)

Следующие шаги

Из этой статьи вы узнали, как сопоставить правила переноса из Splunk с Microsoft Sentinel.