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...5164 
 Trees...935 
 Максвелл 3...861 
 Go Web ...814 
 William Gropp...795 
 Ethreal 3...779 
 Ethreal 4...766 
 Gary V.Vaughan-> Libtool...764 
 Rodriguez 6...755 
 Steve Pate 1...748 
 Clickhouse...748 
 Ext4 FS...748 
 Ethreal 1...736 
 Secure Programming for Li...720 
 C++ Patterns 3...711 
 Ulrich Drepper...693 
 Assembler...687 
 DevFS...655 
 Стивенс 9...644 
 MySQL & PosgreSQL...621 
 
  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) 
и сравнить полученные результаты . По идее результаты должны совпасть .
Оставьте свой комментарий !

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

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