Доброго времени суток, уважаемые читатели.
Хочу поделиться с Вами своими экспериментами по сбору журналов событий Windows в OSSIM без использования агентов, т.е. с помощью WMI плагинов.
Эти плагины используют интерфейс WMI и, соответственно, клиента wmi для сбора журналов событий. Использование этих плагинов не является рекомендуемым, а точнее является НЕ рекомендуемым самим вендором (Alienvault) методом сбора журналов событий целевых систем. Аргументируют это тем, что данный метод использует гораздо больше системных ресурсов, чем сбор журналов событий с помощью агента OSSEC. Это действительно так, а кроме этого при использовании WMI события могут просто пропадать, или запаздывать минут на 20 – 30, что, естественно, не приемлемо.
Кроме этого, штатные плагины WMI сделаны таким образом, что из журналов Windows они не получают практически никакой полезной информации. Получают только идентификатор события Windows (числовой и его перевод на человеческий язык, например: 4624 — An account was successfully logged on), наименование лога (Security, System, Application… ), временную метку и огромное сообщение поля message (в которое попадает вся полезная информация – IP адреса, имена пользователей, настройки UAC и т.д.). Поэтому, чтобы получить какую-то полезную информацию, поле message необходимо подвергать дополнительному парсингу, т.е. штатные плагины WMI необходимо дополнительно настраивать. Без этой настройки штатный плагин WMI практически бесполезен.
Если все-таки ситуация вынуждает Вас использовать не агент OSSEC, а плагины WMI, я расскажу как можно снизить количество и уменьшить размер граблей, которые встретятся Вам на этом пути, а именно:
- Как настроить получение дополнительных данных из журналов событий, собираемых по WMI;
- Как диагностировать и устранять неполадки в работе плагина WMI.
1. Получение дополнительных данных из журналов событий, собираемых по WMI
Эту задачу я рассмотрю на примере получения имени пользователя. Алгоритм настройки для получения любых других данных будет аналогичен.
Для получения дополнительных данных используется функционал «custom functions», позволяющий применять к любому полю, получаемому по WMI самописную функцию. Эта функция и будет выполнять парсинг поля message лога Windows и помещать полученное значение (имя пользователя) в поле username события, отображаемого в OSSIM.
Сперва взглянем на штатный плагин wmi-security-logger. Как видно из его конфигурационного файла, располагающегося в /etc/ossim/agent/plugins/wmi-security-logger.cfg, он выполняет два WQL (SQL for WMI) запроса, первый из которых (поле cmd в разделе start_cmd), получает номер события, начиная с которого ведется вычитывание лога, а второй (поле cmd в разделе cmd) уже читает лог. Вот пример второго запроса, читающего лог:
Select ComputerName,EventCode,Logfile,Message,RecordNumber,SourceName,TimeWritten,User from Win32_NTLogEvent Where Logfile = 'Security' and RecordNumber > OSS_COUNTER
Вот эти поля из лога Windows читает плагин:
ComputerName,EventCode,Logfile,Message,RecordNumber,SourceName,TimeWritten,User
Не стоит строить надежд по-поводу поля “User”, в Windows 2008R2 и свежее в него попадает значение “null”.
Таким образом, самое информативное поле — это “message”. Из него с помощью функции будем получать имя пользователя.
Если посмотреть в примеры лога Windows, то увидим, что есть две конструкции, содержащие имя пользователя:
1) Logon Account: <имя пользователя>
Пример «сырого» события, как его видит OSSIM:
nsrv_WinSRV-DC.domain.test|4776|Security|The computer attempted to validate the credentials for an account.rnrnAuthentication
Package:tMICROSOFT_AUTHENTICATION_PACKAGE_V1_0rnLogon Account:tAdministratorrnSource Workstation:tALIENVAULTrnError
Code:t0x0|17507786|Microsoft-Windows-Security-Auditing|20170410111356.914996-000|(null)
2) Account Name: <имя пользователя>
Пример «сырого» события, как его видит OSSIM:
nsrv_WinSRV-DC.domain.test|4672|Security|Special privileges assigned to new logon.rnrnSubject:rntSecurity
ID:ttS-1-5-21-2827692199-2880599349-568663292-500rntAccount Name:ttAdministratorrntAccount Domain:ttDOMAINrntLogon
ID:tt0x2B9EB90DrnrnPrivileges:ttSeSecurityPrivilegerntttSeBackupPrivilegerntttSeRestorePrivilegerntttSeTakeOwnershipPrivilegerntttSeDebugPrivilegerntttSeSystemEnvironmentPrivilegerntttSeLoadDriverPrivilegerntttSeImpersonatePrivilegerntttSeEnableDelegationPrivilege|17507787|Microsoft-Windows-Security-Auditing|20170410111356.914996-000|(null)
Таким образом, нужна функция, которая сможет получать имя пользователя из обеих этих конструкций. Функции, которые используются в плагинах должны быть написаны на python 2.7 и храниться в отдельном файле, путь к которому будет прописан в специальной переменной в конфигурации плагина.
Обратите внимание, что в «сыром» логе r, t, n – это все спецсимволы, т.е. возврат каретки, новая строка и символ табуляции.
Для файлов, в которых хранятся функции есть специальная папочка — /etc/ossim/agent/plugins/custom_functions. Файл с функциями для получения дополнительной информации из WMI лога назван «wmi_funcs.cfg».
Вот его содержимое:
Start Function win_account
import re
def win_account(self, input=''):
try:
try:
res = re.search( 'Logon Account:[^w]t(S+)[^w]r[^w]', input ).group(1)
return res
except:
res = re.findall( 'Account Name:[^w]t[^w]t(S+)[^w]r[^w]', input )
if len(res) > 1:
return res[1]
else:
return res[0]
except:
return None
End Function
Тело функции обязательно должно быть заключено в теги «Start Function» и «End Function». Также, если необходимо импортировать дополнительные модули python, как в моем случае, import нужно также прописывать перед самим телом функции.
Здесь особенно стоит обратить внимание на тот момент, что для обозначения спецсимволов из “сырого” лога “r”, ”n”, ”t” нужно использовать конструкцию [^w]r, [^w]n и [^w]t соответственно. Т.е. символ «» из «сырого» сообщения в нашем регулярном выражении (а именно с помощью регулярных выражений получаем данные этой функцией) представляется как «[^w]». Это решение было найдено методом проб и ошибок. Никакие другие конструкции, включая “.*”, “S+”, экранирование слешей и прочие не смогли справиться с “” в сыром логе.
Как видно из функции, в случае наличия нескольких конструкций «Account Name» в одном сообщении (а такое бывает, например в событиях изменения одной УЗ пользователя другой УЗ), она (функция) берет в качестве имени пользователя второе значение. Потому что первое – это как раз имя пользователя, изменившего целевую УЗ.
Далее в конец раздела [config] конфигурационного файла плагина «/etc/ossim/agent/plugins/wmi-security-logger.cfg» дописываем параметр, ссылающийся на файл функций:
custom_functions_file=/etc/ossim/agent/plugins/custom_functions/wmi_funcs.cfg
А в секцию [cmd] добавляем параметр, использующий кастомную функцию для получения данных об УЗ пользователя. В общем случае это выглядит так:
<имя поля в OSSIM>={:<имя функции>($<номер поля, получаемого запросом WQL>)}
А в моем, частном случае это выглядит так:
username={:win_account($3)}
В итоге, конфигурационный файл плагина будет выглядеть следующим образом:
[DEFAULT]
plugin_id=1518
[config]
type=detector
enable=yes
source=wmi
credentials_file=/etc/ossim/agent/wmi_credentials.csv
sleep=10
process=
start=no
stop=no
custom_functions_file=/etc/ossim/agent/plugins/custom_functions/wmi_funcs.cfg
[start_cmd]
cmd=wmic -U OSS_WMI_USER%OSS_WMI_PASS //OSS_WMI_HOST "Select LogFile,RecordNumber from Win32_NTLogEvent Where Logfile = 'Security'" | head -n 3 | tail -n 1 | cut -f 2 -d |
regexp=
[cmd]
cmd = wmic -U OSS_WMI_USER%OSS_WMI_PASS //OSS_WMI_HOST "Select ComputerName,EventCode,Logfile,Message,RecordNumber,SourceName,TimeWritten,User from Win32_NTLogEvent Where Logfile = 'Security' and RecordNumber > OSS_COUNTER" | cat
start_regexp=^([^|]+)|(d+)|([^|]+)|
regexp="^(?P<system_name>[^|]+)|(?P<plugin_sid>d+)|(?P<logfile>[^|]+)|(?P<message>[^|]+)|(?P<recordnumber>[^|]+)|(?P<sourcename>[^|]+)|(?P<timewritten>[^|]+)|(?P<username>.*)$"
src_ip={resolv($0)}
plugin_sid={$1}
userdata2={$2}
userdata3={$3}
userdata4={$4}
userdata5={$5}
userdata6={$6}
username={:win_account($3)}
2. Диагностика и устранение неполадок WMI плагина
Для диагностики работы плагина нужно выполнить следующие действия:
1) Проверить работу WMI запустив клиента wmic из консоли сервера OSSIM.
Аргументы, с которыми нужно запускать wmic, можно взять из того же самого конфигурационного файла плагина.
Например, так:
wmic -U domainAdministrator%Passw0rd //server.example.com "Select LogFile,RecordNumber from Win32_NTLogEvent Where Logfile = 'Security'"
Результатом успешного выполнения данной команды должен быть список числовых идентификаторов событий из журнала Windows.
Если же появляются ошибки, то необходимо проверить, что данная УЗ настроена правильным образом и обладает всеми необходимыми правами для получения журналов событий целевой системы. Если между сервером OSSIM и целевой системой есть межсетевой экран, также надо убедиться, чтобы он пропускал трафик OSSIM → Windows и в обратном направлении.
2) Перезапустить плагин OSSIM.
Сперва остановить плагин:
/etc/init.d/ossim-agent stop
Затем убить все процессы wmi клиента, которые еще висят:
ps –ef |grep wmi
И по-очереди:
kill -9 “номер процесса”
После этого запустить агента:
/etc/init.d/ossim-agent start
3) Почистить лог целевой системы.
На высоко-нагруженных серверах, например контроллерах доменов с большим количеством пользователей, журнал событий может сильно разрастаться, занимая сотни мегабайт. На своей практике столкнулся с тем, что на таких объемах журналов событий WMI плагин начинает получать события с существенными задержками во времени. Здесь единственная рекомендация – настроить ограничение размера журнала на целевой системе. Желательно, если это будет не более 30 Мб.
В лабораторных условиях зачастую плагин WMI начинал работать только после полного опустошения большого лога security.
Автор: Дмитрий Шулинин