Простые LKM
Привет^3
Примерно год назад я увлекся темой руткитов под Linux. Это оказалось достаточно интересным и увлекательным приключением. Я даже реализовал модуль по их обнаружению.
Вы можете сопротивляться, жаловаться или бежать, но я все равно расскажу вам про руткиты. Снова… Я пытался ранее… Ну да ладно.
В этой статье мы с тобой разберем, что это за модули, напишем hello, world. Без этого про руткиты не рассказать. Так что вперед.
Loadable Kernel Module, LKM
Это код, который может быть загружен в адресное пространство ядра без перезагрузки системы. Они позволяют расширять функциональность ядра динамически.
Классический пример такого модуля - драйвер устройства.
Команды для работы с модулями
lsmod- показать список загруженных модулей;modinfo module.ko- показать информацию о модуле;insmod module.ko- загрузка модуля в ядро;rmmod module_name- удаление модуля из ядра;sudo journalctl --since "1 hour ago" | grep kernel- просмотр сообщений ядра.
Установка окружения
Пакеты
sudo apt-get update
Заголовочные файлы ядра
Для Ubuntu / Debian:
apt-cache search linux-headers-$(uname -r)
sudo apt-get install kmod linux-headers-$(uname -r)
Структура LKM-модуля
Базовая модель
Модуль ядра должен иметь как минимум две точки входа.
До версии ядра 2.3.13:
init_module()- вызывается при загрузке модуля;cleanup_module()- вызывается перед выгрузкой модуля.
В современных ядрах используются макросы module_init() и module_exit(), которые позволяют указать произвольные функции инициализации и завершения.
Hello, world на руткитском
hello-1.c:
#include <linux/kernel.h>
#include <linux/module.h>
int init_module(void) {
pr_info("Hello, world\n");
return 0;
}
void cleanup_module(void) {
pr_info("Goodbye, world.\n");
}
MODULE_LICENSE("GPL");
Makefile:
obj-m += hello-1.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean
Сборка и загрузка:
make
sudo insmod hello-1.ko
Проверяем:
lsmod | grep hello_1
sudo dmesg | tail -n 3
Удаление модуля:
sudo rmmod hello_1
sudo dmesg | tail -n 3
module_init() и module_exit()
Аналогичный пример с макросами:
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
static int __init hello_init(void) {
pr_info("Hello, world\n");
return 0;
}
static void __exit hello_exit(void) {
pr_info("Goodbye, world.\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
Макросы:
__init- позволяет освободить память, занятую кодом инициализации, после её выполнения;__exit- указывает, что функция завершения не используется для встроенных в ядро модулей.
Вывод
Мы написали и загрузили простой модуль ядра. Это минимальный строительный блок, без которого невозможно говорить о LKM-руткитах.
В следующем посте мы начнём смотреть, как LKM могут скрываться от lsmod.