В этой статье мы рас­смот­рим инс­тру­мент монито­рин­га Sysmon, к которо­му так при­вык­ли в вин­де, и гля­нем, нас­коль­ко его вер­сия для Linux хорошо себя покажет. Так­же соберем основные зна­ния о Sysmon для Linux.

Мы час­то нас­тра­иваем аудит в Linux (auditd, eBPF) — и сами, и вмес­те с кол­легами. Потом при­ходят джу­ны, и выяс­няет­ся, что им... слож­но. Ну лад­но, подума­ли мы. Нем­ного извра­та — и хотя бы базовое логиро­вание в Linux всег­да мож­но нас­тро­ить, поч­ти без зат­рат.

Ос­новная цель статьи — рас­ска­зать об инс­тру­мен­те, показать его воз­можнос­ти и попол­нить копил­ку зна­ний «Хакера» еще одной занят­ной тех­нологи­ей, о которой в комь­юни­ти безопас­ников пока мало говорят.

 

Установка

С уста­нов­кой муд­рить не нуж­но: офи­циаль­ная инс­трук­ция прос­та и понят­на — все­го четыре коман­ды, и все готово.

Да и ребуты не нуж­ны. Что­бы запус­тить служ­бу, выпол­няем sysmon -i -n.

Мож­но про­верить, что по умол­чанию уже фик­сиру­ются какие‑то XML‑подоб­ные логи: sudo tail -f /var/log/syslog. В некото­рых дис­три­бути­вах их мож­но уви­деть через journalctl | grep sysmon. Ну и не забудь убе­дить­ся, что служ­ба вооб­ще запус­тилась: systemctl status sysmon.

Окей, health check про­шел. Базовые коман­ды похожи на вин­ду (есть хо­роший гайд по ним). Вве­дем sysmon и уви­дим минималь­ную справ­ку.

В целом на этом обзор мож­но было бы и закон­чить, но мы будем дотош­ны и пос­ледова­тель­ны. Зачем нам инс­тру­мент, который нель­зя пощупать?!

 

Ожидание: типы событий

Да­вай пос­мотрим, какие события может ловить Sysmon for Linux по срав­нению с его вин­довым соб­ратом. Оче­вид­но, что вин­довый может все.

Event ID Наз­вание Встре­тишь в Linux При­меча­ние
1 Соз­дание про­цес­са +
2 Из­менение вре­мен­ных меток фай­ла
3 Се­тевое соеди­нение + TCP + UDP
4 Из­менено сос­тояние служ­бы Sysmon +
5 Про­цесс завер­шен +
6 Драй­вер заг­ружен
7 Об­раз заг­ружен
8 Соз­дание уда­лен­ного потока Ис­поль­зует про­цеду­ру из Win32 API
9 Пря­мое чте­ние +
10 Дос­туп к про­цес­су +
11 Файл соз­дан + Час­тично опи­рает­ся на WinAPI
12 Соз­дание/уда­ление объ­екта в реес­тре Ну какой тебе реестр!
13 Ус­танов­лено зна­чение парамет­ра реес­тра
14 Пе­реиме­нова­ние объ­екта реес­тра
15 Соз­дан фай­ловый поток
16 Из­менение кон­фигура­ции Sysmon +
17 Име­нован­ный канал соз­дан
18 Под­клю­чение к име­нован­ному каналу
19 WMI-филь­тр Соз­дан, изме­нен, уда­лен (WMI в Linux нет)
20 Пот­ребитель WMI Соз­дан, изме­нен, уда­лен
21 Филь­тр WMI свя­зан с пот­ребите­лем
22 DNS-зап­рос Ос­нован на обра­щени­ях к dnsapi.dll
23 Файл уда­лен с соз­дани­ем копии +
24 Об­новлен буфер обме­на Ра­бота­ет для тек­ста
25 Из­менен образ про­цес­са
26 Файл уда­лен WinAPI
27 Бло­киров­ка исполня­емо­го фай­ла Опи­рает­ся на WinAPI
28 Бло­киров­ка поб­лочно­го уда­ления фай­ла Опи­рает­ся на WinAPI
29 Ис­полня­емый файл уда­лен
255 Ошиб­ка

Да, инс­тру­мент огра­ничен­ный, но иног­да и не нуж­но боль­шего — глав­ное, что­бы быс­тро!

Ес­ли чуть серь­езнее, то боль­шая часть воз­можнос­тей Sysmon завяза­на на проп­риетар­ные вин­довые фичи — WinAPI, WMI, осо­бен­ности NTFS, которых в Linux, оче­вид­но, мало или они вов­се отсутс­тву­ют, как, нап­ример, реестр.

В су­хом остатке мы дол­жны уви­деть хорошо струк­туриро­ван­ные базовые события: соз­дание и завер­шение про­цес­са, сетевые соеди­нения, соз­дание и уда­ление фай­лов, пря­мое чте­ние с дис­ка, получе­ние дос­тупа к про­цес­су. Есть собс­твен­ный аудит (изме­нение кон­фигура­ции Sysmon).

 

Настройка

Что ж, давай нас­тро­им инс­тру­мент, научим его логиро­вать что‑то полез­ное и про­верим Sysmon for Linux в дей­ствии.

Нас­трой­ка дела­ется через заг­рузку кон­фигура­ции. По умол­чанию никаких пра­вил нет — в основном пишут­ся события соз­дания и завер­шения про­цес­са. Испра­вим это. Кон­фигура­цию в общем слу­чае мож­но заг­рузить как вин­довую (обоб­щенную — понят­но, что филь­тры работать не будут), так и соз­данную спе­циаль­но для Linux. Для экспе­римен­та ска­чаем кон­фиг для всех ивен­тов и пос­мотрим, на что он спо­собен.

almost_all_hunt-naked.xml
<Sysmon schemaversion="4.81">
<HashAlgorithms>*</HashAlgorithms>
<DnsLookup>True</DnsLookup>
<EventFiltering>
<!--Event ID 1: Process creation-->
<ProcessCreate onmatch="exclude"></ProcessCreate>
<!--Event ID 2: A process changed a file creation time-->
<FileCreateTime onmatch="exclude"></FileCreateTime>
<!--Event ID 3: Network connection-->
<NetworkConnect onmatch="exclude"></NetworkConnect>
<!--Event ID 5: Process terminated-->
<ProcessTerminate onmatch="exclude"></ProcessTerminate>
<!--Event ID 6: Driver loaded-->
<DriverLoad onmatch="exclude"></DriverLoad>
<!--Event ID 7: Image loaded-->
<ImageLoad onmatch="exclude"></ImageLoad>
<!--Event ID 8: CreateRemoteThread-->
<CreateRemoteThread onmatch="exclude"></CreateRemoteThread>
<!--Event ID 9: RawAccessRead-->
<RawAccessRead onmatch="exclude"></RawAccessRead>
<!--Event ID 10: ProcessAccess-->
<ProcessAccess onmatch="exclude"></ProcessAccess>
<!--Event ID 11: FileCreate-->
<FileCreate onmatch="exclude"></FileCreate>
<!--Event ID 12: RegistryEvent (Object create and delete)-->
<!--Event ID 13: RegistryEvent (Value Set)-->
<!--Event ID 14: RegistryEvent (Key and Value Rename)-->
<RegistryEvent onmatch="exclude"></RegistryEvent>
<!--Event ID 15: FileCreateStreamHash-->
<FileCreateStreamHash onmatch="exclude"></FileCreateStreamHash>
<!--Event ID 16: ServiceConfigurationChange-->
<!--Event ID 17: PipeEvent (Pipe Created)-->
<!--Event ID 18: PipeEvent (Pipe Connected)-->
<PipeEvent onmatch="exclude"></PipeEvent>
<!--Event ID 19: WmiEvent (WmiEventFilter activity detected)-->
<!--Event ID 20: WmiEvent (WmiEventConsumer activity detected)-->
<!--Event ID 21: WmiEvent (WmiEventConsumerToFilter activity detected)-->
<WmiEvent onmatch="exclude"></WmiEvent>
<!--Event ID 22: DNSEvent (DNS query)-->
<DnsQuery onmatch="exclude"></DnsQuery>
<!--Event ID 23: FileDelete (A file delete was detected)-->
<FileDelete onmatch="exclude"></FileDelete>
<!--Event ID 24: ClipboardChange (New content in the clipboard)-->
<ClipboardChange onmatch="exclude"></ClipboardChange>
<!--Event ID 25: ProcessTampering-->
<ProcessTampering onmatch="exclude"></ProcessTampering>
<!--Event ID 26: FileDeleteDetected-->
<FileDeleteDetected onmatch="exclude"></FileDeleteDetected>
</EventFiltering>
</Sysmon>

При­меним этот кон­фиг.

sysmon -c almost_all_hunt-naked.xml

Про­верить, что пра­вила заг­рузились, мож­но коман­дой sysmon -c.

 

Эксперименты

В вин­де для про­вер­ки мож­но исполь­зовать SysmonSimulator, что­бы сге­нери­ровать все ти­пы событий и убе­дить­ся, что они пишут­ся в логи. В Linux нам такой приб­луды не завез­ли, поэто­му все руками.

В чис­том XML-пред­став­лении вывод выг­лядел бы вот так:

Sep 06 11:46:02 PADMIN sysmon[2602]: <Event><System><Provider Name="Linux-Sysmon" Guid="{ff032593-a8d3-4f13-b0d6-01fc615a0f97}"/><EventID>1</EventID><Version>5</Version><Level>4</Level><Task>1</Task><Opcode>0</Opcode><Keywords>0x8000000000000000</Keywords><TimeCreated SystemTime="2025-09-06T08:46:02.829056000Z"/><EventRecordID>2288796</EventRecordID><Correlation/><Execution ProcessID="2602" ThreadID="2602"/><Channel>Linux-Sysmon/Operational</Channel><Computer>PADMIN</Computer><Security UserId="0"/></System><EventData><Data Name="RuleName">-</Data><Data Name="UtcTime">2025-09-06 08:46:06.529</Data><Data Name="ProcessGuid">{218d9a1a-f4ce-68bb-7db7-d9e08a550000}</Data><Data Name="ProcessId">3235</Data><Data Name="Image">/usr/bin/systemctl</Data><Data Name="FileVersion">-</Data><Data Name="Description">-</Data><Data Name="Product">-</Data><Data Name="Company">-</Data><Data Name="OriginalFileName">-</Data><Data Name="CommandLine">systemctl status sysmon</Data><Data Name="CurrentDirectory">/root</Data><Data Name="User">root</Data><Data Name="LogonGuid">{218d9a1a-0000-0000-0000-000000000000}</Data><Data Name="LogonId">0</Data><Data Name="TerminalSessionId">4294967295</Data><Data Name="IntegrityLevel">no level</Data><Data Name="Hashes">SHA256=c3f60225cf89f20c2f870fd738a6452da820eff730a7e5f05ae03fde1aaa876a</Data><Data Name="ParentProcessGuid">{00000000-0000-0000-0000-000000000000}</Data><Data Name="ParentProcessId">2095</Data><Data Name="ParentImage">-</Data><Data Name="ParentCommandLine">-</Data><Data Name="ParentUser">-</Data></EventData></Event>

Но луч­ше почис­тить его:

sudo tail -f /var/log/syslog | sudo /opt/sysmon/sysmonLogView

Эта коман­да оста­вит толь­ко важ­ную информа­цию о событии.

Event SYSMONEVENT_CREATE_PROCESS
RuleName: -
UtcTime: 2025-09-06 08:46:06.529
ProcessGuid: {218d9a1a-f4ce-68bb-7db7-d9e08a550000}
ProcessId: 3235
Image: /usr/bin/systemctl
FileVersion: -
Description: -
Product: -
Company: -
OriginalFileName: -
CommandLine: systemctl status sysmon
CurrentDirectory: /root
User: root
LogonGuid: {218d9a1a-0000-0000-0000-000000000000}
LogonId: 0
TerminalSessionId: 4294967295
IntegrityLevel: no level
Hashes: SHA256=c3f60225cf89f20c2f870fd738a6452da820eff730a7e5f05ae03fde1aaa876a
ParentProcessGuid: {00000000-0000-0000-0000-000000000000}
ParentProcessId: 2095
ParentImage: -
ParentCommandLine: -
ParentUser: -

У ути­литы SysmonLogView есть нес­коль­ко полез­ных клю­чей.

# Отображать только sysmon Event ID 1
sysmonLogView -e 1
# Отображать только Event ID 2–5
sysmonLogView -r 2,5
# Отобразить события во временном интервале
sysmonLogView -t 2025-09-09 00:00,2025-09-09 15:00
# Фильтр событий по значению поля (но у нас очень часто выводило ошибки парсинга, на заметку)
sysmonLogView -f Image=/usr/bin/systemctl

Для экспе­римен­тов мы будем исполь­зовать филь­тра­цию такого вида:

sudo tail -f /var/log/syslog | sudo /opt/sysmon/sysmonLogView -e 1

Пос­мотрим, как Sysmon себя покажет.

 

Создание процесса — Event ID 1

За­пус­тим прос­лушку пор­та коман­дой nc -l 9999 и выведем сге­нери­рован­ное событие.

Event SYSMONEVENT_CREATE_PROCESS
RuleName: -
UtcTime: 2025-04-01 16:35:43.668
ProcessGuid: {218d9a1a-15df-67ec-7979-350909560000}
ProcessId: 9345
Image: /usr/bin/nc.openbsd
FileVersion: -
Description: -
Product: -
Company: -
OriginalFileName: -
CommandLine: nc -l 9999
CurrentDirectory: /root/
User: root
LogonGuid: {218d9a1a-0000-0000-0000-000000000000}
LogonId: 0
TerminalSessionId: 4294967295
IntegrityLevel: no level
Hashes: SHA1=4d82414a45e1559c6b06b675bb416c7a6b570430,MD5=aaade8e2a921e9ac40178a263ebb67e3,SHA256=2a6fac3d98e090468962ef18003cb8b89fbffa7219917ca12567d5e42b156948
ParentProcessGuid: {00000000-0000-0000-0000-000000000000}
ParentProcessId: 1555
ParentImage: -
ParentCommandLine: -
ParentUser: -

В событии есть мет­ка вре­мени (сра­зу в UTC, что нем­ного меша­ет хан­тингу при работе на хос­те), PID про­цес­са, коман­дная стро­ка, дирек­тория, поль­зователь, хеши (чего в auditd не уви­деть) и PID родите­ля. В целом информа­ции не так мно­го (вот бы сра­зу брать имя родитель­ско­го про­цес­са, нап­ример), зато все струк­туриро­вано.

Из инте­рес­ного: коман­да history не залоги­рова­лась, что печаль­но.

 

Изменение временной метки файла — Event ID 2

Поп­робу­ем изме­нить вре­мен­ную мет­ку фай­ла:

echo > fileName.txt && touch -a -m -t 201512180130.09 fileName.txt

И на вся­кий слу­чай еще так:

echo > future_file && touch -d 3333120102 future_file

Sysmon ничего не зафик­сировал. Пред­ска­зуемо, но по‑сво­ему обид­но.

 

Сетевое соединение — Event ID 3

Сде­лаем прос­тей­ший зап­рос:

curl -v https://google.com

И пос­мотрим резуль­тат:

Event SYSMONEVENT_NETWORK_CONNECT
RuleName: -
UtcTime: 2025-04-01 16:39:30.522
ProcessGuid: {218d9a1a-16c2-67ec-8dbe-804b34560000}
ProcessId: 9521
Image: /usr/bin/curl
User: root
Protocol: tcp
Initiated: true
SourceIsIpv6: false
SourceIp: 192.168.135.3
SourceHostname: -
SourcePort: 32796
SourcePortName: -
DestinationIsIpv6: false
DestinationIp: 74.125.71.100
DestinationHostname: -
DestinationPort: 443
DestinationPortName: -

В логах мно­го сетевых соеди­нений, вклю­чая локаль­ные — их мы поп­робу­ем отфиль­тро­вать на сле­дующем эта­пе экспе­римен­та. Видим бинар­ник, IP-адре­са источни­ка и наз­начения и их пор­ты. Из минусов — коман­дную стро­ку все рав­но при­дет­ся искать в свя­зан­ном событии соз­дания про­цес­са. В auditd, нап­ример, событие запус­ка про­цес­са и сетево­го под­клю­чения фор­миру­ется под одним иден­тифика­тором ауди­та.

Так­же для ряда событий про­цесс (Image) получал имя <unknown process>, что печаль­но для под­систе­мы ауди­та — тол­ку от таких логов мало.

 

Изменение Sysmon — Event ID 4

За­косим под дурач­ка и поп­робу­ем наг­ло вклю­чить и отклю­чить автостарт служ­бы Sysmon:

systemctl enable sysmon
systemctl disable sysmon

Нет реак­ции. Лад­но, поп­робу­ем прос­то менять кон­фигура­цию через sysmon -i.

Event SYSMONEVENT_SERVICE_STATE_CHANGE
UtcTime: 2025-04-03 16:45:26.270
State: Started
Version: 1.3.5
SchemaVersion: 4.81

В ито­ге уста­нов­ка и уда­ление сер­виса через sysmon -i и sysmon -u детек­тиру­ется, но манипу­ляции со служ­бой через systemctl, увы, нет.

 

Процесс завершен — Event ID 5

Те­перь прер­вем запущен­ный ранее про­цесс — прос­то жмем Ctrl-C в окне с nc -l 9999.

Event SYSMONEVENT_PROCESS_TERMINATE
RuleName: -
UtcTime: 2025-04-01 16:37:02.636
ProcessGuid: {218d9a1a-15df-67ec-7979-350909560000}
ProcessId: 9345
Image: /usr/bin/nc.openbsd
User: root

Мы получи­ли имя бинар­ника и PID уби­того про­цес­са. Нем­ного, но чес­тная работа.

 

Пустышки Event ID 6–8

Эти типы событий в Linux (заг­рузка драй­вера, заг­рузка обра­за и соз­дание уда­лен­ного потока) работа­ют ина­че, чем в род­ной для Sysmon Windows, поэто­му и не детек­тиру­ются. В Linux обыч­но драй­вер — это модуль ядра, который мож­но заг­ружать и выг­ружать. Спи­сок модулей и заг­рузку и выг­рузку любого из них мож­но получить, нап­ример, так:

# Драйвер загружен Event ID 6
lsmod
modbrobe -rv snd_seq_dummy
modbrobe snd_seq_dummy
rmod snd_seq_dummy
 

Образ загружен — Event ID 7

Заг­рузка обра­за в тер­миноло­гии Windows — это под­груз­ка допол­нитель­ных биб­лиотек про­цес­сом.

 

Создание удаленного потока — Event ID 8

Этот тип события отве­чает за выяв­ление попыток process injection через WinAPI. Во всех трех слу­чаях — пред­ска­зуемо никакой реак­ции от Sysmon.

 

Прямое чтение с диска — Event ID 9

С этим уже инте­рес­нее. Пря­мое чте­ние с блоч­ных устрой­ств в обход прог­рам­мных изо­ляций — одна из популяр­ных тех­ник зло­умыш­ленни­ков. Пос­мотрим, какие дис­ки у нас есть, через lsblk и поп­робу­ем про­читать пер­вый попав­ший­ся через open /dev/sda.

Event SYSMONEVENT_RAWACCESS_READ
RuleName: -
UtcTime: 2025-04-03 17:23:05.024
ProcessGuid: {218d9a1a-c3f9-67ee-211f-58d5a0550000}
ProcessId: 14447
Image: /usr/bin/lynx
Device: /dev/sda
User: -

И куда же без ста­рой доб­рой dd:

dd if=/dev/sda | hexdump -C
Event SYSMONEVENT_RAWACCESS_READ
RuleName: -
UtcTime: 2025-04-03 18:19:15.760
ProcessGuid: {218d9a1a-d123-67ee-210e-2a1c73550000}
ProcessId: 25942
Image: /usr/bin/dd
Device: /dev/sda
User: -

Опять же без события соз­дания про­цес­са мы фик­сиру­ем толь­ко факт пря­мого обра­щения к дис­ку, но без при­вяз­ки к какой‑либо кон­кре­тике.

 

Получен доступ к процессу — Event ID 10

Са­мый прос­той спо­соб про­верить это — запус­тить трас­сиров­ку, нап­ример так: strace cat /etc/passwd.

Event SYSMONEVENT_ACCESS_PROCESS
RuleName: -
UtcTime: 2025-04-03 17:33:33.500
SourceProcessGUID: {218d9a1a-c66d-67ee-5d11-1e7eb4550000}
SourceProcessId: 17313
SourceThreadId: 17313
SourceImage: /usr/bin/strace
TargetProcessGUID: {00000000-0000-0000-0000-000000000000}
TargetProcessId: 16412
TargetImage: -
GrantedAccess: 0x0
CallTrace: -
SourceUser: -
TargetUser: -
Event SYSMONEVENT_ACCESS_PROCESS
RuleName: -
UtcTime: 2025-04-03 17:33:33.502
SourceProcessGUID: {218d9a1a-c66d-67ee-5d11-1e7eb4550000}
SourceProcessId: 17313
SourceThreadId: 17313
SourceImage: /usr/bin/strace
TargetProcessGUID: {218d9a1a-c66d-67ee-b1c4-df6db4550000}
TargetProcessId: 16414
TargetImage: /usr/bin/cat
GrantedAccess: 0x0
CallTrace: -
SourceUser: root
TargetUser: root

В зарегис­три­рован­ных событи­ях вид­но, что про­цесс strace дей­стви­тель­но под­клю­чал­ся к cat: факт есть, но что имен­но про­исхо­дило — неяс­но. Так­же этот тип не детек­тировал соз­дание дам­пов памяти про­цес­сов, нап­ример procdump -w chromium.

 

Создание файла — Event ID 11

С отсле­жива­нием соз­дания фай­лов Sysmon справ­ляет­ся. Дела­ем touch xakep, резуль­тат:

Event SYSMONEVENT_FILE_CREATE
RuleName: -
UtcTime: 2025-04-03 17:36:36.721
ProcessGuid: {218d9a1a-c724-67ee-5180-63511f560000}
ProcessId: 17446
Image: /usr/bin/touch
TargetFilename: /root/xakep
CreationUtcTime: 2025-04-03 17:36:36.721
User: -

В целом — при­емле­мо. Но почему не отме­чает­ся root-поль­зователь, непонят­но. При работе от любого дру­гого поль­зовате­ля юзер опре­деля­ется кор­рек­тно.

 

Пустышки — Event ID 12–15

Для событий 12–15 (соз­дание или уда­ление объ­екта в реес­тре — 12, изме­нение зна­чения парамет­ра реес­тра — 13, пере­име­нова­ние объ­екта реес­тра — 14 и соз­дание фай­лового потока — 15) Sysmon в Linux ничего не задетек­тит: в сис­теме нет реес­тра, а исполь­зует­ся фай­ловая сис­тема (ext, XFS и про­чие), отличная от жур­налиру­емой NTFS.

По­это­му едем даль­ше.

 

Изменение конфигурации Sysmon — Event ID 16

Поп­робу­ем очис­тить нас­трой­ки через sysmon -c --:

Event SYSMONEVENT_SERVICE_CONFIGURATION_CHANGE
UtcTime: 2025-04-03 17:44:09.505
Configuration: -
ConfigurationFileHash: -

И уста­новить новые.

Sysmon -i /home/alex/almost_all_hunt-naked.xml
Event SYSMONEVENT_SERVICE_CONFIGURATION_CHANGE
UtcTime: 2025-04-03 17:45:18.987
Configuration: /home/alex/almost_all_hunt-naked.xml
ConfigurationFileHash: -

Хо­тя сброс на парамет­ры по умол­чанию и не был явно отме­чен, по событи­ям соз­дания про­цес­сов мы все еще можем понять при­мер­ный кон­текст изме­нений.

 

Пустышки — Event ID 17–22

Здесь у нас оче­ред­ной набор пус­тышек. Соз­дание име­нован­ного канала (Event ID 17) мож­но вос­про­извести коман­дами mknod xakep_named_pipe p или mkfifo test_pipe. Поп­робу­ем к ним под­клю­чить­ся (Event ID 18):

echo 'SYSMONS DUCKS' > test_pipe &
cat test_pipe

Шум леса, свер­чки, шелест тра­вы.

Для событий, свя­зан­ных с WMI (Event ID 19, 20, 21), пред­ска­зуемо ничего не будет из‑за проп­риетар­ности тех­нологии (ну нет WMI в Linux).

Боль­шие надеж­ды мы воз­лагали на Event ID 22 — DNS-зап­росы: такие арте­фак­ты очень полез­ны при рас­сле­дова­нии киберин­циден­тов. Но реаль­ность пол­на разоча­рова­ний: вмес­то это­го в логе — лишь nslookup opera.com, ping mail.ru, curl -v https://yandex.ru.

Зве­нящая пус­тота, но мы про­дол­жаем дви­гать­ся даль­ше.

 

Файл удален с сохранением копии — Event ID 23

Прос­то уда­лим файл: rm file.

Event SYSMONEVENT_FILE_DELETE
RuleName: -
UtcTime: 2025-04-03 17:58:35.876
ProcessGuid: {218d9a1a-cc4b-67ee-41ea-1e3619560000}
ProcessId: 23224
User: -
Image: /usr/bin/rm
TargetFilename: /root/MSTIC-Sysmon/linux/filed
Hashes: -
IsExecutable: -
Archived: -

Что инте­рес­но, событие 26, которое называ­ется «Уда­ление фай­ла», как раз не регис­три­рует­ся. Но факт уда­ления зафик­сирован — это обна­дежи­вает.

 

Финальные пустоты — Event ID 24–29, 255

Поп­робу­ем обра­тить­ся к буферу обме­на (Event ID 24) — пред­ска­зуемо не фик­сиру­ется (clip, echo lalka | xclip -sel clip).

Из­менение обра­за про­цес­са (Event ID 25). В Linux у нас не получи­лось это вос­про­извести (поп­робуй заменить запущен­ный про­цесс на лету, ага).

И уда­ление фай­ла (Event ID 26) — через touch supahaker && rm supahaker — фик­сиру­ется в событии 23, но почему‑то не в 26.

В акту­аль­ных сбор­ках для Windows у Sysmon есть события 27 (бло­киров­ка исполня­емо­го фай­ла), 28 (бло­киров­ка поб­лочно­го уда­ления фай­ла), 29 (исполня­емый файл уда­лен). Но это каса­ется толь­ко PE-фай­лов в Windows.

Оши­бок (код 255) мы тоже не получа­ли во вре­мя испы­таний.

Воз­можнос­ти оце­нили. Уста­нов­ка и пер­вичная нас­трой­ка выг­лядят прос­то, но, может, есть что‑то пок­руче? Давай поп­робу­ем под­сунуть кон­фигура­ции с наворо­тами — филь­тра­цией событий и обо­гаще­нием, хотя бы по тех­никам мат­рицы ATT&CK.

 

Эксперименты с обогащением конфигов

Ссыл­ки на некото­рые кон­фиги для Linux мож­но най­ти в статье «При­мене­ние ути­литы Sysmon для повыше­ния уров­ня кибер­безопас­ности» Рус­лана Рах­метова.

Не­кото­рые при­емы и фраг­менты кон­фигура­ции можешь под­смот­реть в статье Hunting for Persistence in Linux и шпар­галке.

Для раз­вле­чения уста­новим «прод­винутую кон­фигу» из MSTIC и пос­мотрим, как изме­нит­ся фор­мат вывода.

sysmon -c main.xml

Пос­ле это­го количес­тво генери­руемых ивен­тов рез­ко упа­ло — из‑за кучи филь­тров. А коман­да crontab отве­чает так:

Event SYSMONEVENT_CREATE_PROCESS
RuleName: TechniqueID=T1053.003,TechniqueName=Scheduled Task/Job: Cron
UtcTime: 2025-09-07 13:38:53.801
ProcessGuid: {30ec4589-8aed-68bd-f152-268a64550000}
ProcessId: 65293
Image: /usr/bin/crontab
FileVersion: -
Description: -
Product: -
Company: -
OriginalFileName: -
CommandLine: crontab
CurrentDirectory: /home/alex
User: root
LogonGuid: {30ec4589-0000-0000-0000-000000000000}
LogonId: 0
TerminalSessionId: 4294967295
IntegrityLevel: no level
Hashes: SHA256=11651a4bd5c9605dac9df09bcb1ce16e40e740558766081a784e16db0098c042
ParentProcessGuid: {00000000-0000-0000-0000-000000000000}
ParentProcessId: 22706
ParentImage: -
ParentCommandLine: -
ParentUser: -
Event SYSMONEVENT_FILE_CREATE
RuleName: TechniqueID=T1053.003,TechniqueName=Scheduled Task/Job: Cron
UtcTime: 2025-09-07 13:38:53.821
ProcessGuid: {30ec4589-8aed-68bd-f152-268a64550000}
ProcessId: 65293
Image: /usr/bin/crontab
TargetFilename: /var/spool/cron/crontabs/tmp.l2DA8v
CreationUtcTime: 2025-09-07 13:38:53.821
User: -

Те­перь у нас есть поле RuleName, которое поз­воля­ет быс­трее атри­бути­ровать активность. Но все же, хоть прош­лая кон­фигура­ция и была избы­точ­ной (логиро­вала все и писала в гро­моз­дком Windows-фор­мате), там сох­ранялось мно­го полез­ных событий для рас­сле­дова­ния. Отка­тим нас­трой­ки на дефол­тные: sysmon -c --.

Что­бы не зас­памить событи­ями сетево­го вза­имо­дей­ствия, мож­но отфиль­тро­вать локаль­ные обра­щения — для это­го дос­таточ­но вста­вить в кон­фиг такой блок:

<!--Event ID 3: Network connection-->
<RuleGroup name="" groupRelation="or">
<NetworkConnect onmatch="exclude">
<SourceIp>127.0.0.1</SourceIp>
<DestinationIp>127.0.0.1</DestinationIp>
<DestinationIp>127.0.1.1</DestinationIp>
</NetworkConnect>
</RuleGroup>

Хо­тя потен­циаль­но это может при­вес­ти к потере час­ти локаль­ных соеди­нений (при­вет, Docker и тун­нели!), в типич­ных слу­чаях это­го дос­таточ­но, что­бы не засорять аудит. В качес­тве домаш­него задания можешь по ана­логии отфиль­тро­вать локаль­ные IPv6-адре­са (но мы читеры и прос­то вста­вили в код выше строч­ку вида <SourceIsIpv6>trueSourceIsIpv6>).

 

Немного про eBPF

Как ты понял, Sysmon for Linux осно­ван на eBPF. Если тебе инте­рес­ны детали реали­зации eBPF в Sysmon, мож­но взгля­нуть на ис­ходный код — там перечис­лены, нап­ример, основные сис­темные вызовы, которые исполь­зуют­ся для фор­мирова­ния записи события в Sysmon. В час­тнос­ти, для соз­дания про­цес­са — execve, execveat; соз­дания фай­ла — creat; откры­тия фай­ла — open, openat; уда­ления фай­ла — unlink, unlinkat; TCP‑соеди­нений — accept, accept4; дос­тупа к про­цес­су — ptrace; UDP‑соеди­нений — recvfrom, recvmsg, recvmmsg, read; зак­рытия фай­лового дес­крип­тора — close.

Этот спи­сок сис­темных вызовов ты можешь взять за осно­ву, что­бы реали­зовы­вать пра­вила для auditd или Tetragon.

 

Выводы

С одной сто­роны, при­ятно, что мож­но быс­тро соб­рать базиро­ван­ную базу: прос­то пос­тавить пакет и исполь­зовать один кон­фиг. С дру­гой — инс­тру­мент по пути миг­рации меж­ду опе­раци­онка­ми потерял зна­читель­ную часть сво­ей полез­ности.

Что­бы выжать из Sysmon мак­симум, в кон­фиге нуж­но най­ти баланс: либо тонуть в куче мусор­ных событий, либо отфиль­тро­вать поч­ти всю активность, соз­давая пра­вила для поч­ти каж­дой извес­тной ути­литы — и сис­темной, и той, что может при­годить­ся в качес­тве GTFOBins. Супер­конфи­га (как для Windows) в Linux пока не вид­но, да и вряд ли он появит­ся. Дадим еще пару ссы­лок на раз­ные кон­фиги для Sysmon под Linux:

В ито­ге фик­сиру­ется доволь­но мало информа­ции, и качес­тво тоже не очень; из плю­сов — все в понят­ном виде, минималь­ный набор при­год­ных для рас­сле­дова­ния событий, есть хеши. Но на этом, пожалуй, и все. Так что как игрушка и потен­циаль­ная жер­тва фор­ков — почему нет. Но мы никог­да не видели, что­бы кто‑то исполь­зовал Sysmon for Linux ина­че, чем как упражне­ние. Но кто зна­ет, это может и изме­нить­ся.

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    2 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии