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 
 Интервью 
 Kernel
 HOW-TO 1
 Ptrace
 Kernel-Rebuild-HOWTO
 Runlevel
 Linux daemons
 FAQ
NEWS
Последние статьи :
  Rust 07.11   
  Go 25.12   
  EXT4 10.11   
  FS benchmark 15.09   
  Сетунь 23.07   
  Trees 25.06   
  Apache 03.02   
  SQL 30.07   
  JFS 10.06   
  B-trees 01.06   
 
TOP 20
 Rubni-Corbet -> Глав...1125 
 Go Web ...516 
 Trees...240 
 2.0-> Linux IP Networking...211 
 Rubni-Corbet -> Глав...199 
 Cluster 3...195 
 TCP 4...192 
 Rubni-Corbet -> Глав...187 
 Steve Pate 3...180 
 Stein-MacEachern-> Час...177 
 Ethreal 1...174 
 Rubni-Corbet -> Глав...170 
 Bauer-> Appendix C...168 
 Gary V.Vaughan-> Autotoll...168 
 Part 3...168 
 Стивенс 9...167 
 Rodriguez 6...167 
 TCP 1...165 
 Secure Programming for Li...164 
 Ethreal 4...163 
 
  01.10.2017 : 2303965 посещений 

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) 
и сравнить полученные результаты . По идее результаты должны совпасть .
Оставьте свой комментарий !

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

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