Перейти к основному содержимому
Версия: 6.1

Функции языка условий

Описание

Диалект коррелятора предоставляет около ста функций. Большая их часть совпадает по имени и поведению со стандартным 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смещение зоны

Примеры

Пример №1
strftime(@timestamp, "2006-01-02") == "2026-08-06"

Пустой шаблон или нечисловое время дают пустую строку.

strptime

Разбирает строку со временем и возвращает время Unix. Шаблон записывается так же, как в strftime

Синтаксис

strptime(<строка>, <шаблон>)

Примеры

Пример №1
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 — месяцы. Сдвиг применяется первым, округление — вторым.

Примеры

Пример №1
relative_time(@timestamp, "-1h")
Пример №2
relative_time(@timestamp, "@d")
Пример №3
relative_time(@timestamp, "-1d@d", "Europe/Moscow")

Первое выражение дает момент часом раньше, второе — начало суток по UTC, третье — начало вчерашних суток по московскому времени. Без третьего аргумента границы суток, недель и месяцев отсчитываются по UTC.

to_timezone

Возвращает строку с местным временем указанной зоны, а не сдвинутое время Unix, как в SML. Временная зона обязательна.

Синтаксис

to_timezone(<время>, <временная зона>)

Примеры

Пример №1
to_timezone(@timestamp, "Europe/Moscow") != nil

from_timezone

Обратная операция: читает строку с местным временем указанной зоны и возвращает время Unix. В SML эта функция принимает время Unix, а не строку.

Синтаксис

from_timezone(<строка с местным временем>, <временная зона>)

Примеры

Пример №1
from_timezone("2026-08-03 17:37:12", "Europe/Moscow")

Строка, уже содержащая собственное смещение зоны, не принимается — иначе источников зоны было бы два. Неразобранная строка или неизвестная зона дают null.

tostring

Преобразует значение в строку. Дополнительных форматов HEX, COMMAS, DURATION, BYTES и QUANTITY, доступных в SML, у функции нет — она принимает ровно один аргумент.

Синтаксис

tostring(<значение>)

Примеры

Пример №1
tostring(event.code) == "4625"

substr

Извлекает подстроку. Нумерация с единицы и отрицательное начало от конца строки — как в SML, но второй числовой аргумент задает длину, а не позицию конца.

Синтаксис

substr(<значение>, <начало> [, <длина>])

Примеры

Пример №1
substr(user.name, -4, 4) == "base"
Пример №2
substr(host.name, 1, 3) == "web"

Начало 0 недопустимо в нумерации с единицы и дает пустую строку, как и выход за границы строки. Работа идет по символам, а не по байтам, поэтому кириллица не разрезается посередине.

к сведению

Для нумерации с нуля в диалекте есть отдельная функция substring.


Функции коррелятора

Обращение к событию и контексту

exist

Проверяет, есть ли в событии поле с указанным путем. Отличается от isnotnull тем, что отвечает о наличии самого поля, а не о содержательности его значения.

exist(<путь к полю>)
Пример №1
not exist(process.name)
Пример №2
exist("user.name") or exist(process.parent.name)

source

Проверяет, пришло ли событие из источника, чей псевдоним совпадает с шаблоном. В шаблоне допустим подстановочный знак *, регистр не учитывается.

source(<шаблон псевдонима>)
Пример №1
source("winlog*") and event.code == "4625"

ctx

Возвращает значение поля, сохраненного стадией императивного правила. Работает только для стадий с включенным переключателем Добавить в контекст — см. Императивные правила.

ctx(<стадия>, <поле>)

Оба аргумента можно писать как без кавычек, так и в двойных кавычках; кавычки нужны, если имя содержит пробел или другие символы вне обычного набора.

Пример №1
ctx(stage1, user.name) == "admin"
Пример №2
ctx("stage-1", "user@corp.local") != ""
Пример №3
ctx(stage_a, destination.host.name) == ctx(stage_b, host.name)

Активные списки

alcontains

Проверяет, есть ли в активном списке запись, у которой указанное поле равно указанному значению. Пар «поле — значение» может быть несколько, тогда запись должна совпасть по всем.

alcontains(<список>, <поле> as <значение> [, <поле> as <значение>]...)
Пример №1
alcontains(ti_ip_blacklist, destination.ip as source.address)
Пример №2
alcontains(geo, ip as source.ip, country as source.geo.country_iso_code)

alget

Находит в активном списке запись по значению и возвращает значение одного ее поля.

alget(<список>, <значение>, <поле>)
Пример №1
alget(known_hosts, host.name, status) == "trusted"
Пример №2
alget(known_hosts, lower(user.name), 'user name') != nil

Сравнение и разбор строк

contains

Проверяет вхождение подстроки с учетом регистра. Для многозначного поля отвечает утвердительно, если подстрока найдена хотя бы в одном элементе.

contains(<значение>, <подстрока>)
Пример №1
contains(process.command_line, "-enc")

startswith

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

startswith(<значение>, <префикс>)
Пример №1
startswith(file.path, "C:\\Windows\\Temp")

endswith

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

endswith(<значение>, <суффикс>)
Пример №1
endswith(lower(file.name), ".ps1")
к сведению

contains, startswith и endswith всегда учитывают регистр. Чтобы сравнить без учета регистра, оберните обе стороны в lower.

regex

Проверяет, находится ли в значении совпадение с регулярным выражением.

regex(<значение>, <регулярное выражение>)
Пример №1
regex(process.command_line, "(?i)powershell\\s+-enc")

extract

Возвращает текст первого совпадения с регулярным выражением. Без третьего аргумента возвращается совпадение целиком, с ним — содержимое именованной группы (?P<имя>...).

extract(<значение>, <регулярное выражение> [, <имя группы>])
Пример №1
extract(url.original, "session_id=(?P<sid>[a-z0-9]+)", "sid") != ""

Если выражение пустое или некорректное, совпадения нет либо группа ничего не захватила, возвращается пустая строка.

indexof

Возвращает позицию первого вхождения подстроки или -1, если вхождения нет.

indexof(<значение>, <подстрока>)
Пример №1
indexof(process.command_line, "--password") >= 0

substring

Извлекает подстроку с нумерацией с нуля; второй числовой аргумент — длина. Выход за границы не считается ошибкой: значения приводятся к допустимым.

substring(<значение>, <начало> [, <длина>])
Пример №1
substring(host.name, 0, 3) == "web"

Похожесть и энтропия строк

levenshtein

Возвращает расстояние редактирования между двумя строками: число вставок, удалений и замен символов. Строки длиннее 256 символов усекаются.

levenshtein(<значение>, <значение>)
Пример №1
levenshtein(lower(user.name), "administrator") <= 2

Если обе строки пусты — например, оба поля отсутствуют в событии, — возвращается null, а не 0: сравнивать нечего.

similarity

Возвращает нормализованную меру похожести от 0 до 1, где 1 — полное совпадение.

similarity(<значение>, <значение>)
Пример №1
similarity(dns.question.name, "microsoft.com") > 0.85

Как и levenshtein, при двух пустых строках возвращает null.

entropy

Возвращает энтропию Шеннона строки в битах на символ, примерно от 0 до 8. Высокая энтропия характерна для случайных и закодированных строк — доменов, сгенерированных алгоритмом, закодированной полезной нагрузки.

entropy(<значение>)
Пример №1
entropy(dns.question.name) > 3.5 and len(dns.question.name) > 12
Обратите внимание!

Энтропия зависит от длины строки, поэтому короткие значения дают завышенный результат — используйте вместе с проверкой длины. Пустое значение дает null, а не 0: 0 — это законная энтропия строки из одного повторяющегося символа.

Многозначные поля

mvcontains

Проверяет, есть ли в многозначном поле элемент, точно равный указанному значению. В отличие от contains, ищет не подстроку, а совпадение элемента целиком.

mvcontains(<многозначное поле>, <значение>)
Пример №1
mvcontains(host.ip, "10.0.0.1")

Преобразование типов

tofloat

Преобразует значение в число с плавающей точкой. Значение, которое не разбирается как число, а также бесконечность и «не число» дают null.

tofloat(<значение>)
Пример №1
round(tofloat(risk.score)) >= 10

Кодирование и декодирование

ФункцияСинтаксисЧто делает
base64encodebase64encode(<значение>)кодирует значение в base64
base64decodebase64decode(<значение>)декодирует base64; распознаются как стандартный, так и URL-безопасный алфавиты, с дополняющими символами и без них
hexencodehexencode(<значение>)кодирует значение в шестнадцатеричный вид
hexdecodehexdecode(<значение>)декодирует шестнадцатеричную строку
Пример №1
contains(lower(base64decode(process.args)), "invoke-expression")

Если декодировать значение не удалось, возвращается пустая строка.

Сетевые адреса

ФункцияСинтаксисЧто делает
isipisip(<значение>)значение — корректный адрес IPv4 или IPv6
isipv4isipv4(<значение>)значение — корректный адрес IPv4
isipv6isipv6(<значение>)значение — корректный адрес IPv6
isprivateipisprivateip(<значение>)адрес частный, петлевой или локальный для канала: RFC 1918, ULA, 127.0.0.0/8, ::1, 169.254.0.0/16, fe80::/10
ispublicipispublicip(<значение>)адрес маршрутизируется в глобальной сети
cidr_containscidr_contains(<подсеть>, <адрес>)адрес входит в подсеть; полный синоним cidrmatch
subnetsubnet(<адрес>, <длина префикса>)возвращает подсеть указанной длины, которой принадлежит адрес
iptonumberiptonumber(<адрес>)возвращает числовое значение адреса IPv4 для сравнения диапазонов
Пример №1
isprivateip(source.address) and cidr_contains("10.0.0.0/8", source.address)
Пример №2
subnet(source.ip, 24) == "10.0.5.0/24"

Время

timediff

Возвращает разницу двух моментов времени в секундах.

timediff(<время>, <время>)
Пример №1
timediff(event.end, event.start) > 3600

age

Возвращает, сколько секунд прошло с указанного момента до настоящего времени. Равносильно now() - <время>.

age(<время>)
Пример №1
age(user.last_password_change) > 7776000

hourofday

Возвращает час суток от 0 до 23. Без второго аргумента вычисляется по UTC.

hourofday(<время> [, <временная зона>])
Пример №1
hourofday(@timestamp, "Europe/Moscow") < 6

dayofweek

Возвращает день недели числом, где 0 — воскресенье, 6 — суббота. Без второго аргумента вычисляется по UTC.

dayofweek(<время> [, <временная зона>])
Пример №1
dayofweek(@timestamp, "Europe/Moscow") == 1

isweekend

Проверяет, приходится ли момент на субботу или воскресенье.

isweekend(<время> [, <временная зона>])
Пример №1
isweekend(@timestamp, "Europe/Moscow") and event.code == "4624"

inbusinesshours

Проверяет, попадает ли час момента в промежуток от <час начала> включительно до <час окончания> не включая.

inbusinesshours(<время>, <час начала>, <час окончания> [, <временная зона>])
Пример №1
not inbusinesshours(@timestamp, 9, 19, "Europe/Moscow")
к сведению

Всем четырем функциям временная зона передается именем по базе IANA, например Europe/Moscow. Если зона указана и не распознана, результат — null для hourofday и dayofweek и ложь для isweekend и inbusinesshours. Отсутствие аргумента означает UTC и ошибкой не считается.

Коллекции

join

Склеивает элементы многозначного поля в строку через разделитель. Одиночное значение обрабатывается как коллекция из одного элемента.

join(<многозначное поле>, <разделитель>)
Пример №1
join(user.roles, ",") != ""

sum

Складывает числовые элементы коллекции. Элементы, не являющиеся числами, пропускаются; если складывать нечего, возвращается null.

sum(<коллекция>)
Пример №1
sum(scores) / len(scores) > 5