- BrainTools - https://www.braintools.ru -

Атаки на контейнерные системы и композиция данных для их обнаружения

Введение

В последние годы контейнеризация и контейнерные системы стали конкурентной альтернативой виртуализации и виртуальным операционным системам, поскольку контейнерные системы предлагают более рациональный подход к использованию вычислительных ресурсов. Это достигается за счёт упаковки в образ контейнера только необходимых программных компонентов, что позволяет запустить контейнер с минимальным набором библиотек и утилит.

Тут следует отметить несколько ключевых особенностей использования контейнерных систем. Во-первых, поскольку контейнеры совместно используют ядро хостовой операционной системы, тип операционной системы внутри контейнера определяется операционной системой хоста. Во-вторых, такой рациональных подход не только привносит дополнительные риски и угрозы безопасности для контейнеров, запущенных на хосте, но и ставит под удар целевую хостовую операционную систему. Поскольку контейнер, который использует ядро хостовой операционной системы, позволяет злоумышленнику, который находится внутри контейнера, напрямую эксплуатировать уязвимости ядра. В-третьих, изоляция контейнера от остального мира (хоста или других контейнеров на хосте) лежит полностью на плечах DevOps-инженеров (Development and Operations). В таком случае одно неправильное движение может привести к катастрофическим последствиям.

Немного про логи

Существует некая теория (не путать с гипотезой) про обнаружение атак через анализ системных вызовов (syscalls, system calls). Почему же всё-таки анализ syscalls, а не, к примеру, команда docker logs или использование Auditd

Давайте взглянем на результат работы команды docker logs, который представлен в листинге 1.

Листинг 1. Результат мониторинга контейнера с помощью команды docker logs

root@bc708ad65e85:/# nsenter --target 1 --mount --uts --ipc --net --pid -- bash
root@msx:/# cd /home/qwerty/Downloads/xmrig-6.22.2-noble-x64/xmrig-6.22.2/
root@msx:/home/qwerty/Downloads/xmrig-6.22.2-noble-x64/xmrig-6.22.2# ./xmrig 
 * ABOUT        XMRig/6.22.2 gcc/13.2.0 (built for Linux x86-64, 64 bit)
 * LIBS         libuv/1.49.2 OpenSSL/3.0.15 hwloc/2.11.2
 * HUGE PAGES   supported
 * 1GB PAGES    disabled
 * CPU          AMD Ryzen 7 5825U with Radeon Graphics (4) 64-bit AES VM
                L2:4.0 MB L3:64.0 MB 8C/8T NUMA:1
 * MEMORY       3.2/16.7 GB (19%)
                RAM slot #0: 16 GB DRAM @ 0 MHz RAM slot #0
                RAM slot #1: 1 GB DRAM @ 0 MHz RAM slot #1
                RAM slot #2: 0 GB DRAM @ 0 MHz RAM slot #2
                RAM slot #3: 0 GB DRAM @ 0 MHz RAM slot #3
                RAM slot #4: 0 GB DRAM @ 0 MHz RAM slot #4
 * MOTHERBOARD  VMware, Inc. - VMware Virtual Platform
 * DONATE       1%
 * ASSEMBLY     auto:ryzen
 * POOL #1      donate.v2.xmrig.com:3333 algo auto
 * COMMANDS     hashrate, pause, resume, results, connection
 * OPENCL       disabled
 * CUDA         disabled
[2025-04-10 11:19:20.727]  net      use pool donate.v2.xmrig.com:3333  178.128.242.134
[2025-04-10 11:19:20.728]  net      new job from donate.v2.xmrig.com:3333 diff 1000K algo rx/0 height 3386892 (16 tx)
[2025-04-10 11:19:20.728]  cpu      use argon2 implementation AVX2
[2025-04-10 11:19:20.732]  msr      register values for "ryzen_19h" preset have been set successfully (4 ms)
[2025-04-10 11:19:20.732]  randomx  init dataset algo rx/0 (8 threads) seed c088b4cf924533a3...
[2025-04-10 11:19:24.518]  randomx  allocated 2336 MB (2080+256) huge pages 100% 1168/1168 +JIT (3785 ms)
[2025-04-10 11:19:24.743]  net      new job from donate.v2.xmrig.com:3333 diff 1000K algo rx/0 height 3386892 (24 tx)
[2025-04-10 11:19:33.012]  randomx  dataset ready (8494 ms)
[2025-04-10 11:19:33.012]  cpu      use profile  rx  (8 threads) scratchpad 2048 KB
[2025-04-10 11:19:33.193]  cpu      READY threads 8/8 (8) huge pages 100% 8/8 memory 16384 KB (182 ms)
[2025-04-10 11:19:36.242]  net      new job from donate.v2.xmrig.com:3333 diff 1000K algo rx/0 height 3386892 (27 tx)
[2025-04-10 11:19:50.979]  net      new job from donate.v2.xmrig.com:3333 diff 1000K algo rx/0 height 3386892 (30 tx)
[2025-04-10 11:20:03.218]  net      new job from donate.v2.xmrig.com:3333 diff 1000K algo rx/0 height 3386892 (34 tx)
[2025-04-10 11:20:07.661]  net      new job from donate.v2.xmrig.com:3333 diff 1000K algo rx/0 height 3386893 (34 tx)

При использовании docker logs мы получаем банальный результат работы в консоли, что может быть не информативно при условии, что через консоль будет запущен некий скриптовый или бинарный файл.

В случае Auditd тут всё зависит от правил, которые используются для сбора данных. Также следует отметить, что логи, сгенерированные в результате работы Auditd, сложно читаемы, а их парсинг то ещё удовольствие. Давайте взглянем на такие логи, они представлены в листинге 2.

Листинг 2. Логи, сгенерированные в результате работы Auditd

…
node=127.0.1.1 type=USER_AUTH msg=audit(1744275450.358:3894): pid=49994 uid=0 auid=1000 ses=2 subj=unconfined msg='op=PAM:authentication grantors=pam_rootok acct="ro>
node=127.0.1.1 type=SYSCALL msg=audit(1744275450.358:3895): arch=c000003e syscall=257 success=yes exit=3 a0=ffffff9c a1=7baa527cf320 a2=80000 a3=0 items=1 ppid=49993>
node=127.0.1.1 type=CWD msg=audit(1744275450.358:3895): cwd="/etc/audit/rules.d"
node=127.0.1.1 type=PATH msg=audit(1744275450.358:3895): item=0 name="/etc/passwd" inode=4212490 dev=08:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL cap_>
node=127.0.1.1 type=PROCTITLE msg=audit(1744275450.358:3895): proctitle="su"
node=127.0.1.1 type=SYSCALL msg=audit(1744275450.359:3896): arch=c000003e syscall=257 success=yes exit=3 a0=ffffff9c a1=7baa527cf347 a2=80000 a3=0 items=1 ppid=49993>
node=127.0.1.1 type=CWD msg=audit(1744275450.359:3896): cwd="/etc/audit/rules.d"
node=127.0.1.1 type=PATH msg=audit(1744275450.359:3896): item=0 name="/etc/shadow" inode=4212491 dev=08:02 mode=0100640 ouid=0 ogid=42 rdev=00:00 nametype=NORMAL cap>
node=127.0.1.1 type=PROCTITLE msg=audit(1744275450.359:3896): proctitle="su"
node=127.0.1.1 type=SYSCALL msg=audit(1744275450.359:3897): arch=c000003e syscall=257 success=yes exit=3 a0=ffffff9c a1=7baa528ce6b7 a2=0 a3=0 items=1 ppid=49993 pid>
node=127.0.1.1 type=CWD msg=audit(1744275450.359:3897): cwd="/etc/audit/rules.d"
…

Как видно, логи действительно сложно читать. Теперь перейдём непосредственно к самим атакам и их обнаружению на основе syscalls.

Некоторые атаки и способы их обнаружения

1. Монтирование диска хостовой операционной системы из контейнера

Иногда так случается, что инженеры запускают контейнеры с неправильной конфигурацией. К примеру, если запустить контейнер в привилегированном режиме с флагом –privileged (привилегированный режим предоставляет контейнеру почти такой же уровень прав, что и на хостовой системе), то злоумышленник, находясь внутри контейнера, сможет смонтировать диск хостовой операционной системы и совершить «Побег из Шоушенка» или атаку «Побег из контейнера» (Container Escape), как показано в листинге 3.

Листинг 3. Монтирование диска хостовой операционной системы из контейнера

root@msx:/home/qwerty/Desktop# docker run --rm -it --pid=host --privileged ubuntu bash
root@3c7ccb1ff662:/# mkdir -p /mnt/TheShawshankRedemption
root@3c7ccb1ff662:/# mount /dev/sda2 /mnt/TheShawshankRedemption
root@3c7ccb1ff662:/# cd /mnt/TheShawshankRedemption
root@3c7ccb1ff662:/mnt/TheShawshankRedemption# ls -l
total 8388716
lrwxrwxrwx   1 root root          7 Apr 22  2024 bin -> usr/bin
drwxr-xr-x   2 root root       4096 Feb 26  2024 bin.usr-is-merged
drwxr-xr-x   3 root root       4096 Apr  9 05:34 boot
dr-xr-xr-x   2 root root       4096 Apr 24  2024 cdrom
drwxr-xr-x   4 root root       4096 Apr 24  2024 dev
drwxr-xr-x 148 root root      12288 Apr 10 08:41 etc
drwxr-xr-x   3 root root       4096 Feb 13 12:45 home
lrwxrwxrwx   1 root root          7 Apr 22  2024 lib -> usr/lib 
…

В данному случае выполнение команды mount создаст несколько последовательно выполняемых syscalls mount, сопоставив эти syscalls c контейнером и его конфигурацией; можно вполне точно определить, что злоумышленник пытается совершить Container Escape. Конфигурацию контейнера можно посмотреть с помощью команды docker inspect b88e4860ead4, где b88e4860ead4 — идентификатор контейнера, как представлено в листинге 4.

Листинг 4. Результат команды docker inspect

root@msx:/home/qwerty/Desktop# docker inspect b88e4860ead4
[
    {
        "Id": "b88e4860ead431e3ede7a3ce4978be2c2b305f388fff89f7dc39ed746e3fd18d",
        "Created": "2025-04-10T11:30:33.958190701Z",
        "Path": "bash",
        "Args": [],
        "State": {
            "Status": "running",
…

2. Выполнение команд хостовой ОС из контейнера

Использование команды nsenter позволяет выполнять команды внутри пространств имён (Namespace) целевого процесса. В контексте контейнера, запущенного в привилегированном режиме и в Namespace хостовой операционной системы, эта команда предоставляет доступ к Namespace процесса с идентификатором (PID, Process IDentifier) 1; обычно это процесс init или systemd в хостовой операционной системе. Таким образом, nsenter позволяет выполнять команды в окружении хоста, обеспечивая доступ ко всем его ресурсам и процессам, как показано в листинге 5.

Листинг 5. Выполнение команд хостовой ОС из контейнера

root@msx:/home/qwerty/Desktop# docker run --rm -it --pid=host --privileged ubuntu bash
root@00c21effaa0d:/# ping 8.8.8.8
bash: ping: command not found
root@00c21effaa0d:/# nsenter --target 1 --mount --uts --ipc --net --pid -- bash
root@msx:/# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=128 time=8.24 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=128 time=7.26 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=128 time=8.09 ms
…

В данном случае выполнение команды nsenter будет сопровождаться шестью последовательными системными вызовами: setns, setns, open, open, setns, setns. Проанализировав эти системные вызовы, а также системные вызовы, относящие к неудачному и удачному запуску утилиты ping, можно сделать вывод, что злоумышленник успешно выполнил команду nsenter и использует утилиты хоста из контейнера.

3. Назначение привилегий

В Linux привилегия root делится на более мелкие, отдельные единицы (CAP_SYS_CHROOT, CAP_CHOWN, CAP_KILL, CAP_SETUID, CAP_SETPCAP и другие), с помощью механизма возможностей (Capabilities). Это позволяет процессам обладать подмножеством этих привилегий или ограничивать операции, которые могут выполняться независимо от типа пользователя. С помощью команды capsh можно проверить привилегии контейнера и назначить привилегии файлу или процессу с помощью утилиты setcap, как показано в листинге 6.

Листинг 6. Выполнение команд capsh и setcap

root@msx:/home/qwerty/Desktop# docker run --rm -it --privileged python:2.7 bash
root@d014f75a33a1:/# capsh --print
Current: = cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read,38,39,40+ep
Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read,38,39,40
Securebits: 00/0x0/1'b0
 secure-noroot: no (unlocked)
 secure-no-suid-fixup: no (unlocked)
 secure-keep-caps: no (unlocked)
uid=0(root)
gid=0(root)
groups=0(root)
root@d014f75a33a1:/# touch scr.sh 
root@d014f75a33a1:/# setcap cap_net_raw+ep /scr.sh

Использование команды setcap может быть обнаружено благодаря четырём последовательным системным вызовам: capset, capset, capget, capget. Примечательно то, что сначала привилегии с помощью системного вызова capset назначаются, а потом с помощью capget запрашиваются у целевого объекта. Это необходимо для того, чтобы проверить, что привилегии назначены.  

Что дальше?

После понимания того, какие syscalls могут указывать на конкретные атаки, можно применять методы глубокого машинного обучения [1] для создания моделей обнаружения. Тут следует отметить, что у каждого метода есть свои особенности.

К примеру, AE (Autoencoder) основан на ошибке [2] реконструкции, что позволяет обучить модель для реконструкции данных об определённой атаке. В таком случае высокий показатель ошибки реконструкции будет свидетельствовать о том, что модель не была обучена реконструировать эти конкретные данные. MLP (Multilayer perceptron), напротив, являясь простейшей нейронной сетью, прекрасно может подойти для классификации данных и расчёта долей вероятности принадлежности наблюдаемого класса к конкретному типу атаки. В случае с LSTM (Long short-term memory) всё немного иначе. Данная нейронная сеть основана на анализе последовательных данных. К примеру, обучив модель на последовательных данных об атаке, она приобретает возможность предсказывать следующий шаг на основе текущего. Совпадение предсказанного значения и фактического с большей долей вероятности может свидетельствовать об атаке.

Заключение

В заключение важно отметить, что при обучении нейронных сетей потребление вычислительных ресурсов и времени напрямую зависит от объёма данных и сложности архитектуры. Кроме того, учитывая, что в среднем каждый процесс выполняет от 60 до 80 syscalls, а нейронные сети работают исключительно с числовыми признаками, нормализация этих данных может потребовать значительных временных затрат.

Автор: Renzauder

Источник [3]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/16343

URLs in this post:

[1] обучения: http://www.braintools.ru/article/5125

[2] ошибке: http://www.braintools.ru/article/4192

[3] Источник: https://habr.com/ru/companies/gaz-is/articles/919418/?utm_campaign=919418&utm_source=habrahabr&utm_medium=rss

www.BrainTools.ru

Rambler's Top100