Функции языка условий
Описание
Диалект коррелятора предоставляет около ста функций. Большая их часть совпадает по имени и поведению со стандартным SML. Остальные функции существуют только в корреляторе либо ведут себя иначе, чем одноименные функции SML.
Функции, совпадающие со стандартным SML
Условия и сравнение
| Функция | Что делает |
|---|---|
case | возвращает значение первого истинного условия из списка пар |
validate | обратна case: возвращает значение первого ложного условия |
if | возвращает одно из двух значений в зависимости от условия |
coalesce | возвращает первое непустое значение из перечисленных |
nullif | возвращает null, если два значения равны, иначе первое из них |
in | проверяет, входит ли значение поля в перечисленный набор |
like | сопоставляет значение с шаблоном SQL-вида (%, _) |
match | сопоставляет значение с регулярным выражением |
cidrmatch | проверяет, попадает ли IP-адрес в подсеть |
Проверка типа значения
| Функция | Что делает |
|---|---|
isnull | значение отсутствует |
isnotnull | значение присутствует |
isstr | значение — строка |
isnum | значение — число |
isint | значение — целое число |
isbool | значение — логическое |
typeof | возвращает имя типа значения |
Преобразование типов
| Функция | Что делает |
|---|---|
tonumber | преобразует значение в число; вторым аргументом принимает основание системы счисления от 2 до 36 |
tobool | преобразует значение в логическое |
Текст
| Функция | Что делает |
|---|---|
len | длина строки; для многозначного поля — число элементов |
lower | приводит строку к нижнему регистру |
upper | приводит строку к верхнему регистру |
trim | убирает указанные символы с обеих сторон строки; без второго аргумента — пробельные символы |
ltrim | то же слева |
rtrim | то же справа |
replace | заменяет вхождения шаблона; в строке замены доступны группы захвата $1, $2, ${имя} |
urlencode | кодирует строку для использования в URL |
urldecode | обратное преобразование |
Математика
| Функция | Что делает |
|---|---|
abs | модуль числа |
ceil | округление вверх |
floor | округление вниз |
round | округление до заданного числа знаков; по умолчанию — до целого |
exp | экспонента |
ln | натуральный логарифм |
log | логарифм по указанному основанию; с одним аргументом — по основанию 10 |
pow | возведение в степень |
sqrt | квадратный корень |
pi | число «пи» |
max | наибольшее из перечисленных значений или элементов массива |
min | наименьшее из них |
Многозначные поля
| Функция | Что делает |
|---|---|
mvcount | число элементов |
mvindex | элемент по индексу; третьим аргументом задается конец диапазона |
mvfind | индекс первого элемента, совпавшего с регулярным выражением |
mvdedup | убирает повторяющиеся элементы |
mvsort | сортирует элементы |
mvappend | объединяет значения в одно многозначное |
mvjoin | склеивает элементы в строку через разделитель |
mvrange | строит числовой ряд |
mvzip | попарно объединяет элементы двух полей |
split | разбивает строку по разделителю |
Хеширование
| Функция | Что делает |
|---|---|
md5 | хеш MD5 |
sha1 | хеш SHA-1 |
sha256 | хеш SHA-256 |
sha512 | хеш SHA-512 |
Хеш возвращается в нижнем регистре.
Время
| Функция | Что делает |
|---|---|
now | текущее время в формате Unix |
time | то же самое: time — синоним now |
Коррелятор работает со временем в целых секундах Unix и в зоне UTC. Если функции времени не передана временная зона явно, вычисление идет в UTC.
Функции с отличающимся поведением
Функции ниже существуют и в SML, и в корреляторе, но ведут себя по-разному.
strftime
Форматирует время Unix. В отличие от SML, шаблон записывается не в формате Joda Time, а образцом даты Mon Jan 2 15:04:05 MST 2006: каждый элемент шаблона — это соответствующая часть образцовой даты.
Синтаксис
strftime(<время>, <шаблон>)
| Элемент шаблона | Значение | Элемент шаблона | Значение |
|---|---|---|---|
2006 | год, четыре цифры | 15 | часы, 24-часовой формат |
01 | месяц, две цифры | 04 | минуты |
02 | день, две цифры | 05 | секунды |
Jan | месяц сокращенно | Z07:00 | смещение зоны |
Примеры
strftime(@timestamp, "2006-01-02") == "2026-08-06"
Пустой шаблон или нечисловое время дают пустую строку.
strptime
Разбирает строку со временем и возвращает время Unix. Шаблон записывается так же, как в strftime
Синтаксис
strptime(<строка>, <шаблон>)
Примеры
now() - strptime(start_time, "2006-01-02T15:04:05Z07:00") > 300
Если строка или шаблон не позволяют получить момент времени, возвращается null.
relative_time
Сдвигает момент времени и округляет его вниз до границы периода. От SML отличается тремя вещами: смещение записывается строкой в кавычках, за сдвигом может следовать округление через @, и есть третий необязательный аргумент — временная зона, по границам которой выполняется округление.
Синтаксис
relative_time(<время>, "<смещение>" [, <временная зона>])
Смещение имеет вид [(+|-)<целое><единица>][@<единица>], где единица — одна из s, m, h, d, w, M.
| Часть | Назначение |
|---|---|
(+|-)<целое><единица> | сдвиг; знак обязателен |
@<единица> | округление вниз до границы периода |
Регистр единицы значим: m — минуты, M — месяцы. Сдвиг применяется первым, округление — вторым.
Примеры
relative_time(@timestamp, "-1h")
relative_time(@timestamp, "@d")
relative_time(@timestamp, "-1d@d", "Europe/Moscow")
Первое выражение дает момент часом раньше, второе — начало суток по UTC, третье — начало вчерашних суток по московскому времени. Без третьего аргумента границы суток, недель и месяцев отсчитываются по UTC.
to_timezone
Возвращает строку с местным временем указанной зоны, а не сдвинутое время Unix, как в SML. Временная зона обязательна.
Синтаксис
to_timezone(<время>, <временная зона>)
Примеры
to_timezone(@timestamp, "Europe/Moscow") != nil
from_timezone
Обратная операция: читает строку с местным временем указанной зоны и возвращает время Unix. В SML эта функция принимает время Unix, а не строку.
Синтаксис
from_timezone(<строка с местным временем>, <временная зона>)
Примеры
from_timezone("2026-08-03 17:37:12", "Europe/Moscow")
Строка, уже содержащая собственное смещение зоны, не принимается — иначе источников зоны было бы два. Неразобранная строка или неизвестная зона дают null.
tostring
Преобразует значение в строку. Дополнительных форматов HEX, COMMAS, DURATION, BYTES и QUANTITY, доступных в SML, у функции нет — она принимает ровно один аргумент.
Синтаксис
tostring(<значение>)
Примеры
tostring(event.code) == "4625"
substr
Извлекает подстроку. Нумерация с единицы и отрицательное начало от конца строки — как в SML, но второй числовой аргумент задает длину, а не позицию конца.
Синтаксис
substr(<значение>, <начало> [, <длина>])
Примеры
substr(user.name, -4, 4) == "base"
substr(host.name, 1, 3) == "web"
Начало 0 недопустимо в нумерации с единицы и дает пустую строку, как и выход за границы строки. Работа идет по символам, а не по байтам, поэтому кириллица не разрезается посередине.
Для нумерации с нуля в диалекте есть отдельная функция substring.
Функции коррелятора
Обращение к событию и контексту
exist
Проверяет, есть ли в событии поле с указанным путем. Отличается от isnotnull тем, что отвечает о наличии самого поля, а не о содержательности его значения.
exist(<путь к полю>)
not exist(process.name)
exist("user.name") or exist(process.parent.name)
source
Проверяет, пришло ли событие из источника, чей псевдоним совпадает с шаблоном. В шаблоне допустим подстановочный знак *, регистр не учитывается.
source(<шаблон псевдонима>)
source("winlog*") and event.code == "4625"
ctx
Возвращает значение поля, сохраненного стадией императивного правила. Работает только для стадий с включенным переключателем Добавить в контекст — см. Императивные правила.
ctx(<стадия>, <поле>)
Оба аргумента можно писать как без кавычек, так и в двойных кавычках; кавычки нужны, если имя содержит пробел или другие символы вне обычного набора.
ctx(stage1, user.name) == "admin"
ctx("stage-1", "user@corp.local") != ""
ctx(stage_a, destination.host.name) == ctx(stage_b, host.name)
Активные списки
alcontains
Проверяет, есть ли в активном списке запись, у которой указанное поле равно указанному значению. Пар «поле — значение» может быть несколько, тогда запись должна совпасть по всем.
alcontains(<список>, <поле> as <значение> [, <поле> as <значение>]...)
alcontains(ti_ip_blacklist, destination.ip as source.address)
alcontains(geo, ip as source.ip, country as source.geo.country_iso_code)
alget
Находит в активном списке запись по значению и возвращает значение одного ее поля.
alget(<список>, <значение>, <поле>)
alget(known_hosts, host.name, status) == "trusted"
alget(known_hosts, lower(user.name), 'user name') != nil
Сравнение и разбор строк
contains
Проверяет вхождение подстроки с учетом регистра. Для многозначного поля отвечает утвердительно, если подстрока найдена хотя бы в одном элементе.
contains(<значение>, <подстрока>)
contains(process.command_line, "-enc")
startswith
Проверяет, начинается ли значение с указанной подстроки, с учетом регистра.
startswith(<значение>, <префикс>)
startswith(file.path, "C:\\Windows\\Temp")
endswith
Проверяет, заканчивается ли значение указанной подстрокой, с учетом регистра.
endswith(<значение>, <суффикс>)
endswith(lower(file.name), ".ps1")
contains, startswith и endswith всегда учитывают регистр. Чтобы сравнить без учета регистра, оберните обе стороны в lower.
regex
Проверяет, находится ли в значении совпадение с регулярным выражением.
regex(<значение>, <регулярное выражение>)
regex(process.command_line, "(?i)powershell\\s+-enc")
extract
Возвращает текст первого совпадения с регулярным выражением. Без третьего аргумента возвращается совпадение целиком, с ним — содержимое именованной группы (?P<имя>...).
extract(<значение>, <регулярное выражение> [, <имя группы>])
extract(url.original, "session_id=(?P<sid>[a-z0-9]+)", "sid") != ""
Если выражение пустое или некорректное, совпадения нет либо группа ничего не захватила, возвращается пустая строка.
indexof
Возвращает позицию первого вхождения подстроки или -1, если вхождения нет.
indexof(<значение>, <подстрока>)
indexof(process.command_line, "--password") >= 0
substring
Извлекает подстроку с нумерацией с нуля; второй числовой аргумент — длина. Выход за границы не считается ошибкой: значения приводятся к допустимым.
substring(<значение>, <начало> [, <длина>])
substring(host.name, 0, 3) == "web"
Похожесть и энтропия строк
levenshtein
Возвращает расстояние редактирования между двумя строками: число вставок, удалений и замен символов. Строки длиннее 256 символов усекаются.
levenshtein(<значение>, <значение>)
levenshtein(lower(user.name), "administrator") <= 2
Если обе строки пусты — например, оба поля отсутствуют в событии, — возвращается null, а не 0: сравнивать нечего.
similarity
Возвращает нормализованную меру похожести от 0 до 1, где 1 — полное совпадение.
similarity(<значение>, <значение>)
similarity(dns.question.name, "microsoft.com") > 0.85
Как и levenshtein, при двух пустых строках возвращает null.
entropy
Возвращает энтропию Шеннона строки в битах на символ, примерно от 0 до 8. Высокая энтропия характерна для случайных и закодированных строк — доменов, сгенерированных алгоритмом, закодированной полезной нагрузки.
entropy(<значение>)
entropy(dns.question.name) > 3.5 and len(dns.question.name) > 12
Энтропия зависит от длины строки, поэтому короткие значения дают завышенный результат — используйте вместе с проверкой длины. Пустое значение дает null, а не 0: 0 — это законная энтропия строки из одного повторяющегося символа.
Многозначные поля
mvcontains
Проверяет, есть ли в многозначном поле элемент, точно равный указанному значению. В отличие от contains, ищет не подстроку, а совпадение элемента целиком.
mvcontains(<многозначное поле>, <значение>)
mvcontains(host.ip, "10.0.0.1")
Преобразование типов
tofloat
Преобразует значение в число с плавающей точкой. Значение, которое не разбирается как число, а также бесконечность и «не число» дают null.
tofloat(<значение>)
round(tofloat(risk.score)) >= 10
Кодирование и декодирование
| Функция | Синтаксис | Что делает |
|---|---|---|
base64encode | base64encode(<значение>) | кодирует значение в base64 |
base64decode | base64decode(<значение>) | декодирует base64; распознаются как стандартный, так и URL-безопасный алфавиты, с дополняющими символами и без них |
hexencode | hexencode(<значение>) | кодирует значение в шестнадцатеричный вид |
hexdecode | hexdecode(<значение>) | декодирует шестнадцатеричную строку |
contains(lower(base64decode(process.args)), "invoke-expression")
Если декодировать значение не удалось, возвращается пустая строка.
Сетевые адреса
| Функция | Синтаксис | Что делает |
|---|---|---|
isip | isip(<значение>) | значение — корректный адрес IPv4 или IPv6 |
isipv4 | isipv4(<значение>) | значение — корректный адрес IPv4 |
isipv6 | isipv6(<значение>) | значение — корректный адрес IPv6 |
isprivateip | isprivateip(<значение>) | адрес частный, петлевой или локальный для канала: RFC 1918, ULA, 127.0.0.0/8, ::1, 169.254.0.0/16, fe80::/10 |
ispublicip | ispublicip(<значение>) | адрес маршрутизируется в глобальной сети |
cidr_contains | cidr_contains(<подсеть>, <адрес>) | адрес входит в подсеть; полный синоним cidrmatch |
subnet | subnet(<адрес>, <длина префикса>) | возвращает подсеть указанной длины, которой принадлежит адрес |
iptonumber | iptonumber(<адрес>) | возвращает числовое значение адреса IPv4 для сравнения диапазонов |
isprivateip(source.address) and cidr_contains("10.0.0.0/8", source.address)
subnet(source.ip, 24) == "10.0.5.0/24"
Время
timediff
Возвращает разницу двух моментов времени в секундах.
timediff(<время>, <время>)
timediff(event.end, event.start) > 3600
age
Возвращает, сколько секунд прошло с указанного момента до настоящего времени. Равносильно now() - <время>.
age(<время>)
age(user.last_password_change) > 7776000
hourofday
Возвращает час суток от 0 до 23. Без второго аргумента вычисляется по UTC.
hourofday(<время> [, <временная зона>])
hourofday(@timestamp, "Europe/Moscow") < 6
dayofweek
Возвращает день недели числом, где 0 — воскресенье, 6 — суббота. Без второго аргумента вычисляется по UTC.
dayofweek(<время> [, <временная зона>])
dayofweek(@timestamp, "Europe/Moscow") == 1
isweekend
Проверяет, приходится ли момент на субботу или воскресенье.
isweekend(<время> [, <временная зона>])
isweekend(@timestamp, "Europe/Moscow") and event.code == "4624"
inbusinesshours
Проверяет, попадает ли час момента в промежуток от <час начала> включительно до <час окончания> не включая.
inbusinesshours(<время>, <час начала>, <час окончания> [, <временная зона>])
not inbusinesshours(@timestamp, 9, 19, "Europe/Moscow")
Всем четырем функциям временная зона передается именем по базе IANA, например Europe/Moscow. Если зона указана и не распознана, результат — null для hourofday и dayofweek и ложь для isweekend и inbusinesshours. Отсутствие аргумента означает UTC и ошибкой не считается.
Коллекции
join
Склеивает элементы многозначного поля в строку через разделитель. Одиночное значение обрабатывается как коллекция из одного элемента.
join(<многозначное поле>, <разделитель>)
join(user.roles, ",") != ""
sum
Складывает числовые элементы коллекции. Элементы, не являющиеся числами, пропускаются; если складывать нечего, возвращается null.
sum(<коллекция>)
sum(scores) / len(scores) > 5