Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
 iakovlev.org 
 Kernels
 Boot 
 Memory 
 File system
 0.01
 1.0 
 2.0 
 2.4 
 2.6 
 3.x 
 4.x 
 5.x 
 6.x 
 Интервью 
 Kernel
 HOW-TO 1
 Ptrace
 Kernel-Rebuild-HOWTO
 Runlevel
 Linux daemons
 FAQ
NEWS
Последние статьи :
  Тренажёр 16.01   
  Эльбрус 05.12   
  Алгоритмы 12.04   
  Rust 07.11   
  Go 25.12   
  EXT4 10.11   
  FS benchmark 15.09   
  Сетунь 23.07   
  Trees 25.06   
  Apache 03.02   
 
TOP 20
 Linux Kernel 2.6...5170 
 Trees...940 
 Максвелл 3...870 
 Go Web ...823 
 William Gropp...803 
 Ethreal 3...787 
 Gary V.Vaughan-> Libtool...773 
 Ethreal 4...771 
 Rodriguez 6...763 
 Ext4 FS...755 
 Steve Pate 1...754 
 Clickhouse...753 
 Ethreal 1...742 
 Secure Programming for Li...731 
 C++ Patterns 3...716 
 Ulrich Drepper...696 
 Assembler...695 
 DevFS...661 
 Стивенс 9...649 
 MySQL & PosgreSQL...631 
 
  01.01.2024 : 3621733 посещений 

iakovlev.org

Detecting Kernel-level Compromises With gdb

Mariusz Burdach
Трояны в инсталлируемых прогаммах могут изменять функции системных утилит . Например команда ls должна показывать содержимое директорий . Модифицированная команда ls может скрывать заданные файлы . Подобные модификации распознаются с помощью средств , называемых
 integrity checkers.
Трояны могут модифицировать как отдельные программы , так и фрагменты ядра . Утилита ls при работе использует системный вызов ядра sys_getdents , который в свою очередь может быть модифицирован . Системные вызовы представляют интерес с точки зрения контроля над машиной , поскольку обладают мощным потенциалом . Системные вызовы предоставляют доступ к файлам , устройствам , запускают исполняемые файлы и т.д.
В ядре 2.4.27 230 системных вызовов . В ядре 2.6.9 их уже 290 . Полный их список доступен в файле /usr/include/asm/unistd.h . Вот список основных системных вызовов ( 2.4.18-3.) :
 	sys_read
 	sys_write
 	sys_open
 	sys_getdents/sys_getdents64
 	sys_socketcall
 	sys_query_module
 	sys_setuid/sys_getuid
 	sys_execve
 	sys_chdir
 	sys_fork/sys_clone
 	sys_ioctl
 	sys_kill
Адрес системного вызова хранится в таблице , которая находится в памяти в пространстве ядра . У каждого имеется свой ID .
Рассмотрим sys_write . При его вызове ID-шник , равный 4 , помещается в региистр eax и вызывается прерывание 0х80 . Номер прерывания при этом помещается в специальную таблицу прерываний . Затем срабатывает system_call , который в нужной таблице по нужному ID-шнику вызывает нужный адрес . Основной метод троянского вторжения заключается в том , чтобы подсунуть вместо нужного адреса другой . Отследить вызываемый адрес можно с помощью gdb . Необходимо также убедиться и в том , что и сама таблица системных вызовов с адресами не подверглась модификации . Адрес памяти таблицы системных вызовов статический и формируется на этапе компиляции ядра . Для 7-го редхата и его клонов этот адрес во время компиляции пишется по крайней мере в 2 местах на диске - в файлах System.map и vmlinux-2.4.x , которые обычно лежат в каталоге /boot . Иногда доступен оказывается только компрессионный файл vmlinuz-2.4.x , Мы можем сравнить адреса системной таблицы в памяти и на диске .
Можно использовать для этих целей также простой модуль , который может быть откомпилирован так :
 	gcc -c scprint.c -I/usr/src/linux/include/
После загрузки этого модуля текущие системные адреса из памяти пишутся в сислог .
В линуксе трояны загружаются обычно с помощью модулей или добавлением кода в обьект /dev/kmem . Память операционной системы представлена обьектом kcore в каталоге /proc .
Итак , для начала найдем "первозданный" адрес талицы системных вызовов :
 	cat System.map-2.4.18-13 | grep sys_call_table c0302c30 D sys_call_table
Теперь распечатаем саму таблицу
 	nm vmlinux-2.4.18-13 | grep sys_call_table
Вывод
 	c0302c30 D sys_call_table
То же самое можно сделать с помощью команды gdb :
 	gdb /boot/vmlinux-2.4.* 
После появления приглашения набираем :
 	(gdb) 	x/255 0xc0302c30
Вывод
 	0xc0302c30 :     0xc01261a0 0xc011e1d0 0xc01078a0 0xc013fb70
         ...
Можно распечатать адрес конкретно для каждой функции :
 	(gdb) x/x sys_ni_syscall 
 	0xc01261a0 :     0xffffdab8 
Адреса должны соответствовать тому , что прописано в entry.S. Текущие адреса системных функций ядра можно распечатать с помощью команды
 	gdb /boot/vmlinux-2.4.* /proc/kcore
Остается сравнить 2 полученных дампа .
Можно отдизассемблировать актуальный системный вызов из памяти следующим образом :
 	gdb /boot/vmlinux* /proc/kcore 
         (gdb) disass sys_read 
То же самое можно сделать с образом на диске
 	gdb /boot/vmlinux* /proc/kcore 
         (gdb) disass sys_read 
 	0xc013fb70 :          	sub     $0x28,%esp 
 	0xc013fb73 :              mov     0x2c(%esp,1),%eax 
 	0xc013fb77 :              mov     %esi,0x1c(%esp,1) 
 	0xc013fb7b :             mov     %edi,0x20(%esp,1) 
и сравнить полученные результаты . По идее результаты должны совпасть .
Оставьте свой комментарий !

Ваше имя:
Комментарий:
Оба поля являются обязательными

 Автор  Комментарий к данной статье