Майк Вазовски
Продолжаем раскуривать вектор атаки, где мы ранее на учебном стенде через гостевой доступ попали во внутренний периметр и хакнули IPMI контроллер одного из серверов.
Постараюсь уместить все в одну картинку а потом распедалить более детально.
Как я ранее говорил, доступ к веб морде контролера был через VPN (сокрытие своего ip) + корпоративный шлюз Cisco, далее веб морда. Для того чтобы сделать рута нужно во внутренний периметр закинуть LiveCD с линуксом. Самый рабочий и функциональный линукс это 500 мб - 1 гб.
То есть. Де факто дубль ВПН + 1 несчастный контроллер. Когда мы, предположим, используем Vless на хосте и в него заворачиваем CISCO VPN а потом этот трафик пуляем на веб морду по факту линукс контроллера мы получаем полный обсер по скорости передачи/обработки в виде 100 кб/c. По времени это 60+ минут. в несколько окон запустить загрузку Live CD на несколько контроллеров тоже не получится.
Перед нами стоит 3 логические задачи
1) Увеличить скорость загрузки канала (невозможно по той простой причине что админ на канальном уровне режет пропускную способность)
2) Уменьшить объем дистрибутива
3) Автоматизировать создание рут юзера и открытия ssh на белом ip.
В интернете можно погуглить легковесные линухи, но это все для маленьких мальчиков и девочек. И мы создадим свой легковесный линух который:
1) Автоматом определит ядро и версию ОС.
2) Опеределит нужные тома
3) Создаст юзера
4) Перезагрузить ОС
1. Архитектура ISO-образа
ISO строится поверх OneFileLinux — минималистичного Linux, загружаемого как один initramfs-файл. Вся операционная система представляет собой:
Ядро хоста (6.18.12+kali-amd64) со всеми необходимыми модулями.
Initramfs (~7.3 МБ), содержащий:
Главный init-скрипт (~700 строк на shell).
Alpine-minirootfs с BusyBox (306 апплетов: modprobe, ash, mount, chroot и другие).
57 модулей ядра для всех распространённых контроллеров хранения.
Статически скомпилированные утилиты LVM2 и dmsetup (musl).
Каталог /userdb/ с готовыми файлами учётной записи: passwd, shadow, group, username, uid, gid.
Итоговый размер ISO — 34.7 МБ, что позволяет использовать его даже в средах с ограниченным объёмом виртуального носителя.
2. Сборка ISO (build.sh)
Сборка полностью автоматизирована через скрипт build.sh:
Скачивается alpine-minirootfs с BusyBox.
Копируются модули ядра текущей системы в /lib/modules/$(uname -r)/.
Пакуются статические бинарники LVM2 и dmsetup из Alpine 3.22.
Генерируется каталог /userdb/ с хешем пароля (через openssl passwd -6).
Генерируется init-скрипт из heredoc.
Создаётся initramfs через cpio -o -H newc | gzip.
Собирается загрузочный ISO с помощью GRUB (grub-mkrescue или xorriso).
Каталог /userdb/ содержит файлы:
Эти файлы используются как для live-системы (копируются в /etc), так и для целевого диска (дописываются в /etc/passwd, /etc/shadow, /etc/group целевой ОС).
3. Этапы загрузки init-скрипта (7 шагов)
При загрузке ISO выполняется последовательность из семи шагов, полностью логируемых в /tmp/minirescue.log:
Шаг 0: Старт ядра
Выводится сообщение: Rescue kernel is up - starting.
Шаг 1: Загрузка драйверов хранения
Загружаются 57 модулей, покрывающих:
Файловые системы: ext4, xfs, btrfs, vfat, f2fs.
SCSI и SATA: scsi_mod, sd_mod, libata, ahci, ata_piix.
Виртуальные: virtio_blk, virtio_scsi.
NVMe: nvme-core, nvme.
USB-накопители: usb-storage.
Enterprise RAID/SAS: LSI MegaRAID, HPE Smart Array, Adaptec, Areca, 3ware, Intel, IBM и другие.
Статистика: --- Driver summary: 55/57 loaded, 2 skipped --- (пропускаются драйверы aic7xxx и aic79xx из-за отсутствия зависимостей, не критичных для современных серверов).
Шаг 2: Активация LVM
Выполняется:
Вывод: --- LVM summary: 2 logical volume(s) activated ---. Если LVM отсутствует, шаг пропускается за 2 секунды.
Шаг 3: Сканирование всех блочных устройств
Скрипт перебирает устройства в /sys/class/block/, определяет размеры и пытается примонтировать каждый раздел в режиме read-only. Для каждого раздела вычисляется root-score на основе наличия маркеров:
/etc/passwd (1 балл)
/etc/shadow (1)
/etc/group (1)
/home (1)
/bin/bash или /bin/sh (1)
/etc/os-release или /etc/lsb-release (1)
Максимальный score = 6. Раздел с наибольшим score объявляется корневым.
Шаг 4: Выбор корневой ФС
Выводится сводка: например, /dev/sda (ext4, score 5) или /dev/mapper/vg-root (xfs, score 6). При равном score выбирается первый найденный.
Шаг 5: Монтирование корневой ФС в режиме чтения-записи
mount -o rw /dev/selected /mnt
Шаг 6: Детектирование ОС и создание пользователя
Это центральный шаг, включающий многоуровневую логику (описана ниже). По окончании создаётся пользователь user с правами root, и выполняется верификация.
Шаг 7: Верификация и завершение
Считываются изменённые файлы, проверяется наличие записи о пользователе и его права. Выводится сообщение OK: 'user' has root on this system, затем система выключается (или перезагружается, в зависимости от настройки)
4. Детектирование операционной системы
Определение дистрибутива — каскадная система с несколькими уровнями fallback.
Уровень 1: PRETTY_NAME (для логов)
Если не найдено, используется DISTRIB_DESCRIPTION из /etc/lsb-release.
Уровень 2: Полный детект через detect_os()
Парсинг /etc/os-release целевой системы:
Уровень 3: Fallback по маркерным файлам
Если os-release отсутствует или пуст, проверяются файлы:
Уровень 4: Хинты по версиям ядра
Сканируются каталоги /lib/modules и /boot/vmlinuz* для получения дополнительной информации о версии ядра, что может помочь в идентификации ОС.
Уровень 5: Маппинг в семейство и sudo-группу
На основе OSID и OSLIKE определяется семейство (debian, rhel, suse, arch, minimal, unknown) и предпочтительная группа для sudo (sudo или wheel).
Примеры маппинга:
ol → fedora → семейство rhel, группа wheel.
debian, ubuntu → семейство debian, группа sudo.
arch, manjaro → семейство arch, группа wheel.
Уровень 6: Обнаружение бинарников sudo/doas
Проверяется наличие исполняемых файлов:
sudo в /usr/bin/sudo, /bin/sudo, /usr/sbin/sudo.
doas в /usr/bin/doas, /bin/doas.
Это определяет, какой механизм повышения привилегий будет использоваться.
5. Цепочка повышения привилегий (root escalation)
Скрипт пытается предоставить пользователю user права root через четыре последовательных маршрута, от наиболее безопасного к гарантированному.
Маршрут 1: Сканирование существующих грантов в sudoers
Функция scanline() парсит /etc/sudoers и файлы в /etc/sudoers.d/, ища строки вида:
Если найдена группа с полными правами (ALL), то user добавляется в эту группу через ensure_group(). Это позволяет использовать уже существующие настройки без изменений sudoers.
Маршрут 2: Drop-in файл для sudoers (основной)
Функция write_dropin():
Создаёт каталог /etc/sudoers.d/, если его нет.
Проверяет наличие директивы #includedir в /etc/sudoers. Если её нет — добавляет.
Создаёт файл /etc/sudoers.d/onefile-user с содержимым:
user ALL=(ALL:ALL) NOPASSWD: ALL
Выполняет проверку синтаксиса через visudo -c внутри chroot.
Если проверка успешна — готово. Если нет — выполняет rollback (удаляет добавленный файл) и переходит к следующему маршруту.
Маршрут 3: Использование doas (для Alpine, Void)
Если sudo недоступен или не работает, проверяется наличие doas. В /etc/doas.conf дописывается строка:
permit persist user
Маршрут 4: uid=0 fallback (гарантированный)
Если ни один из предыдущих методов не сработал, скрипт выполняет:
Пользователь user становится напрямую root (uid=0, gid=0). Этот метод работает всегда, но считается наименее предпочтительным с точки зрения безопасности (но для восстановления доступа — вполне приемлем).
6. Тестирование и отладка
Для обеспечения надёжности созданы два уровня тестирования.
Уровень 1: test.sh — быстрые фейковые диски
Создаются искусственные файловые системы на хосте, которые затем подставляются QEMU как -hda и -hdb. Четыре сценария:
Уровень 2: docker-test.sh — реальные дистрибутивы через Docker
Скрипт скачивает официальные образы дистрибутивов, создаёт из них raw-диски и запускает QEMU с ISO. Тестируются:
Oracle Linux 9 (через oraclelinux:9)
CentOS 7 (centos:7)
Debian 12 (debian:12)
Ubuntu 22.04 (ubuntu:22.04)
LVM-сценарий (создаётся фейковый LVM)
В каждом случае после загрузки ISO проверяется, что пользователь user создан и имеет права root (uid=0 или наличие в sudoers). Все сценарии проходят успешно.
Особенность: в контейнерах Oracle и CentOS visudo -c внутри chroot может не работать из-за отсутствия системных библиотек, поэтому init-скрипт корректно откатывается на uid=0, что гарантирует доступ.
Unattended (без участия человека): ISO полностью автономен, не требует ввода.
Hardware-agnostic: 57 модулей покрывают большинство серверных конфигураций (HPE, Dell, LSI, Adaptec, Intel, IBM, 3ware, Areca и др.).
Safety: Перед каждым изменением создаются резервные копии (*.bak) файлов passwd, shadow, sudoers, doas.conf.
Fallback: Даже если sudo и doas не работают, uid=0 гарантирует доступ.
Универсальность: Поддерживает все популярные семейства Linux (Debian, Ubuntu, RHEL, CentOS, Oracle, Rocky, Alma, Alpine, SUSE, Arch).
Малый размер: 34.7 МБ — легко помещается на CD-ROM или загружается через IPMI/iLO.
На момент написания статьи прямого аналога (автономного ISO, гарантирующего root-доступ на любом сервере) на GitHub не обнаружено. Большинство решений либо требуют ручного ввода, либо имеют больший размер, либо не покрывают LVM и сложные RAID-контроллеры.
8. Использование
Записать ISO на USB-флешку или загрузить через виртуальный носитель (IPMI, iDRAC, iLO).
Загрузить сервер с полученного ISO. (10-15 минут по схеме дубль ВПН)
Дождаться сообщения RESCUE COMPLETE и автоматического завершения работы (обычно ~30 секунд).
Извлечь ISO и перезагрузить сервер в обычном режиме.
Войти под учётной записью user с паролем, заданным при сборке (по умолчанию user).
После входа пользователь user имеет полные права root (через sudo без пароля или напрямую uid=0).
Представленное решение сочетает в себе минимализм, универсальность и надёжность. Открытая архитектура и модульная структура дают возможность легко адаптировать ISO под специфические нужды (смена пароля, добавление других пользователей, изменение логики детектирования, создание cron планировщиков, прошивку ядра и закреп C2-маяка).
ссылка для скачивания билдера https://duty-files.cc/file/4HjIK1DBcSGcpAjU/JyWxLQjbl1WqfYRM/minirescue.tar.gz
пароль: LIMB
Если статья наберет популярность - пойду дальше - анализ CI/CD инфраструктуры и API токены для управление инфраструктурой через инструменты оркестрации.
Далее исходный код для компиляции ISO
Продолжаем раскуривать вектор атаки, где мы ранее на учебном стенде через гостевой доступ попали во внутренний периметр и хакнули IPMI контроллер одного из серверов.
Постараюсь уместить все в одну картинку а потом распедалить более детально.
Не удалось прогрузить медиа
Как я ранее говорил, доступ к веб морде контролера был через VPN (сокрытие своего ip) + корпоративный шлюз Cisco, далее веб морда. Для того чтобы сделать рута нужно во внутренний периметр закинуть LiveCD с линуксом. Самый рабочий и функциональный линукс это 500 мб - 1 гб.
То есть. Де факто дубль ВПН + 1 несчастный контроллер. Когда мы, предположим, используем Vless на хосте и в него заворачиваем CISCO VPN а потом этот трафик пуляем на веб морду по факту линукс контроллера мы получаем полный обсер по скорости передачи/обработки в виде 100 кб/c. По времени это 60+ минут. в несколько окон запустить загрузку Live CD на несколько контроллеров тоже не получится.
Перед нами стоит 3 логические задачи
1) Увеличить скорость загрузки канала (невозможно по той простой причине что админ на канальном уровне режет пропускную способность)
2) Уменьшить объем дистрибутива
3) Автоматизировать создание рут юзера и открытия ssh на белом ip.
В интернете можно погуглить легковесные линухи, но это все для маленьких мальчиков и девочек. И мы создадим свой легковесный линух который:
1) Автоматом определит ядро и версию ОС.
2) Опеределит нужные тома
3) Создаст юзера
4) Перезагрузить ОС
1. Архитектура ISO-образа
ISO строится поверх OneFileLinux — минималистичного Linux, загружаемого как один initramfs-файл. Вся операционная система представляет собой:
Ядро хоста (6.18.12+kali-amd64) со всеми необходимыми модулями.
Initramfs (~7.3 МБ), содержащий:
Главный init-скрипт (~700 строк на shell).
Alpine-minirootfs с BusyBox (306 апплетов: modprobe, ash, mount, chroot и другие).
57 модулей ядра для всех распространённых контроллеров хранения.
Статически скомпилированные утилиты LVM2 и dmsetup (musl).
Каталог /userdb/ с готовыми файлами учётной записи: passwd, shadow, group, username, uid, gid.
Итоговый размер ISO — 34.7 МБ, что позволяет использовать его даже в средах с ограниченным объёмом виртуального носителя.
2. Сборка ISO (build.sh)
Сборка полностью автоматизирована через скрипт build.sh:
Скачивается alpine-minirootfs с BusyBox.
Копируются модули ядра текущей системы в /lib/modules/$(uname -r)/.
Пакуются статические бинарники LVM2 и dmsetup из Alpine 3.22.
Генерируется каталог /userdb/ с хешем пароля (через openssl passwd -6).
Генерируется init-скрипт из heredoc.
Создаётся initramfs через cpio -o -H newc | gzip.
Собирается загрузочный ISO с помощью GRUB (grub-mkrescue или xorriso).
Каталог /userdb/ содержит файлы:
Bash:
passwd: user:x:1000:1000:user:/home/user:/bin/sh
shadow: user:$6$salt$hash:1:0:99999:7:::
group: user:x:1000:
username, uid, gid
3. Этапы загрузки init-скрипта (7 шагов)
При загрузке ISO выполняется последовательность из семи шагов, полностью логируемых в /tmp/minirescue.log:
Шаг 0: Старт ядра
Выводится сообщение: Rescue kernel is up - starting.
Шаг 1: Загрузка драйверов хранения
Загружаются 57 модулей, покрывающих:
Файловые системы: ext4, xfs, btrfs, vfat, f2fs.
SCSI и SATA: scsi_mod, sd_mod, libata, ahci, ata_piix.
Виртуальные: virtio_blk, virtio_scsi.
NVMe: nvme-core, nvme.
USB-накопители: usb-storage.
Enterprise RAID/SAS: LSI MegaRAID, HPE Smart Array, Adaptec, Areca, 3ware, Intel, IBM и другие.
Статистика: --- Driver summary: 55/57 loaded, 2 skipped --- (пропускаются драйверы aic7xxx и aic79xx из-за отсутствия зависимостей, не критичных для современных серверов).
Шаг 2: Активация LVM
Выполняется:
Bash:
lvm vgscan --mknodes
lvm vgchange -ay
Вывод: --- LVM summary: 2 logical volume(s) activated ---. Если LVM отсутствует, шаг пропускается за 2 секунды.
Шаг 3: Сканирование всех блочных устройств
Скрипт перебирает устройства в /sys/class/block/, определяет размеры и пытается примонтировать каждый раздел в режиме read-only. Для каждого раздела вычисляется root-score на основе наличия маркеров:
/etc/passwd (1 балл)
/etc/shadow (1)
/etc/group (1)
/home (1)
/bin/bash или /bin/sh (1)
/etc/os-release или /etc/lsb-release (1)
Максимальный score = 6. Раздел с наибольшим score объявляется корневым.
Шаг 4: Выбор корневой ФС
Выводится сводка: например, /dev/sda (ext4, score 5) или /dev/mapper/vg-root (xfs, score 6). При равном score выбирается первый найденный.
Шаг 5: Монтирование корневой ФС в режиме чтения-записи
mount -o rw /dev/selected /mnt
Шаг 6: Детектирование ОС и создание пользователя
Это центральный шаг, включающий многоуровневую логику (описана ниже). По окончании создаётся пользователь user с правами root, и выполняется верификация.
Шаг 7: Верификация и завершение
Считываются изменённые файлы, проверяется наличие записи о пользователе и его права. Выводится сообщение OK: 'user' has root on this system, затем система выключается (или перезагружается, в зависимости от настройки)
4. Детектирование операционной системы
Определение дистрибутива — каскадная система с несколькими уровнями fallback.
Уровень 1: PRETTY_NAME (для логов)
Bash:
OSN="$(grep -m1 '^PRETTY_NAME=' /mnt/etc/os-release | cut -d= -f2 | tr -d '"')"
Уровень 2: Полный детект через detect_os()
Парсинг /etc/os-release целевой системы:
Bash:
OSID — ID=ol, debian, ubuntu и т.д.
OSLIKE — ID_LIKE=fedora, debian.
OSVER — VERSION_ID=9.4, 12 и т.д.
OSPRIN — PRETTY_NAME="Oracle Linux Server 9.4".
Если os-release отсутствует или пуст, проверяются файлы:
Bash:
/etc/redhat-release
/etc/centos-release
/etc/debian_version
/etc/alpine-release
/etc/arch-release
/etc/SuSE-release
/etc/oracle-release
Уровень 4: Хинты по версиям ядра
Сканируются каталоги /lib/modules и /boot/vmlinuz* для получения дополнительной информации о версии ядра, что может помочь в идентификации ОС.
Уровень 5: Маппинг в семейство и sudo-группу
На основе OSID и OSLIKE определяется семейство (debian, rhel, suse, arch, minimal, unknown) и предпочтительная группа для sudo (sudo или wheel).
Примеры маппинга:
ol → fedora → семейство rhel, группа wheel.
debian, ubuntu → семейство debian, группа sudo.
arch, manjaro → семейство arch, группа wheel.
Уровень 6: Обнаружение бинарников sudo/doas
Проверяется наличие исполняемых файлов:
sudo в /usr/bin/sudo, /bin/sudo, /usr/sbin/sudo.
doas в /usr/bin/doas, /bin/doas.
Это определяет, какой механизм повышения привилегий будет использоваться.
5. Цепочка повышения привилегий (root escalation)
Скрипт пытается предоставить пользователю user права root через четыре последовательных маршрута, от наиболее безопасного к гарантированному.
Маршрут 1: Сканирование существующих грантов в sudoers
Функция scanline() парсит /etc/sudoers и файлы в /etc/sudoers.d/, ища строки вида:
Bash:
%wheel ALL=(ALL) ALL
user ALL=(ALL:ALL) NOPASSWD: ALL
Если найдена группа с полными правами (ALL), то user добавляется в эту группу через ensure_group(). Это позволяет использовать уже существующие настройки без изменений sudoers.
Маршрут 2: Drop-in файл для sudoers (основной)
Функция write_dropin():
Создаёт каталог /etc/sudoers.d/, если его нет.
Проверяет наличие директивы #includedir в /etc/sudoers. Если её нет — добавляет.
Создаёт файл /etc/sudoers.d/onefile-user с содержимым:
user ALL=(ALL:ALL) NOPASSWD: ALL
Выполняет проверку синтаксиса через visudo -c внутри chroot.
Если проверка успешна — готово. Если нет — выполняет rollback (удаляет добавленный файл) и переходит к следующему маршруту.
Маршрут 3: Использование doas (для Alpine, Void)
Если sudo недоступен или не работает, проверяется наличие doas. В /etc/doas.conf дописывается строка:
permit persist user
Маршрут 4: uid=0 fallback (гарантированный)
Если ни один из предыдущих методов не сработал, скрипт выполняет:
Bash:
sed -i "s/^user:x:[0-9]*:[0-9]*:/user:x:0:0:/" /mnt/etc/passwd
chown -R 0:0 /mnt/home/user
Пользователь user становится напрямую root (uid=0, gid=0). Этот метод работает всегда, но считается наименее предпочтительным с точки зрения безопасности (но для восстановления доступа — вполне приемлем).
6. Тестирование и отладка
Для обеспечения надёжности созданы два уровня тестирования.
Уровень 1: test.sh — быстрые фейковые диски
Создаются искусственные файловые системы на хосте, которые затем подставляются QEMU как -hda и -hdb. Четыре сценария:
СценарийОписаниеdebianФейковый Debian 12 с sudo, wheel-группой и os-releaseminimalОС без sudo, только busybox, проверка uid=0 fallbacknopasswdСценарий с неправильным синтаксисом sudoers для проверки rollbacklvmКорень на LVM-томе, проверка активации LVM
После 45 секунд QEMU автоматически завершается, и скрипт проверяет наличие пользователя user в passwd/shadow и наличие грантов в sudoers. В случае успеха выводится PASS для каждого сценария.Уровень 2: docker-test.sh — реальные дистрибутивы через Docker
Скрипт скачивает официальные образы дистрибутивов, создаёт из них raw-диски и запускает QEMU с ISO. Тестируются:
Oracle Linux 9 (через oraclelinux:9)
CentOS 7 (centos:7)
Debian 12 (debian:12)
Ubuntu 22.04 (ubuntu:22.04)
LVM-сценарий (создаётся фейковый LVM)
В каждом случае после загрузки ISO проверяется, что пользователь user создан и имеет права root (uid=0 или наличие в sudoers). Все сценарии проходят успешно.
Особенность: в контейнерах Oracle и CentOS visudo -c внутри chroot может не работать из-за отсутствия системных библиотек, поэтому init-скрипт корректно откатывается на uid=0, что гарантирует доступ.
7. Безопасность и уникальностьUnattended (без участия человека): ISO полностью автономен, не требует ввода.
Hardware-agnostic: 57 модулей покрывают большинство серверных конфигураций (HPE, Dell, LSI, Adaptec, Intel, IBM, 3ware, Areca и др.).
Safety: Перед каждым изменением создаются резервные копии (*.bak) файлов passwd, shadow, sudoers, doas.conf.
Fallback: Даже если sudo и doas не работают, uid=0 гарантирует доступ.
Универсальность: Поддерживает все популярные семейства Linux (Debian, Ubuntu, RHEL, CentOS, Oracle, Rocky, Alma, Alpine, SUSE, Arch).
Малый размер: 34.7 МБ — легко помещается на CD-ROM или загружается через IPMI/iLO.
На момент написания статьи прямого аналога (автономного ISO, гарантирующего root-доступ на любом сервере) на GitHub не обнаружено. Большинство решений либо требуют ручного ввода, либо имеют больший размер, либо не покрывают LVM и сложные RAID-контроллеры.
8. Использование
Записать ISO на USB-флешку или загрузить через виртуальный носитель (IPMI, iDRAC, iLO).
Загрузить сервер с полученного ISO. (10-15 минут по схеме дубль ВПН)
Дождаться сообщения RESCUE COMPLETE и автоматического завершения работы (обычно ~30 секунд).
Извлечь ISO и перезагрузить сервер в обычном режиме.
Войти под учётной записью user с паролем, заданным при сборке (по умолчанию user).
После входа пользователь user имеет полные права root (через sudo без пароля или напрямую uid=0).
ЗаключениеПредставленное решение сочетает в себе минимализм, универсальность и надёжность. Открытая архитектура и модульная структура дают возможность легко адаптировать ISO под специфические нужды (смена пароля, добавление других пользователей, изменение логики детектирования, создание cron планировщиков, прошивку ядра и закреп C2-маяка).
ссылка для скачивания билдера https://duty-files.cc/file/4HjIK1DBcSGcpAjU/JyWxLQjbl1WqfYRM/minirescue.tar.gz
пароль: LIMB
Если статья наберет популярность - пойду дальше - анализ CI/CD инфраструктуры и API токены для управление инфраструктурой через инструменты оркестрации.
Далее исходный код для компиляции ISO
Майк Вазавски, специально для LIMB
👍18
🔥4
👏6
LIMB