Linux - статьи

Перехват системного вызова


Теперь рассмотрим метод обнаружения перехвата системных выводов. Ни один из элементов таблицы системных вызовов не модифицирован таким способом. Вместо этого, первые несколько команд оригинальной функции перезаписываются безусловным переходом на заменяемую функцию. Давайте представим, что злоумышленник хочет перехватить системный вызов sys_read. Вначале он должен загрузить свою функцию в память, а затем поместить адрес этой функции в первых нескольких битах оригинальной функции. Потом злоумышленник должен переадресовать выполнение оригинальной функции к своей функции. Для этого обычно используются такие ассемблерные команды, как call или jmp.

Чтобы определить, был ли системный вызов перехвачен, нам нужно распечатать все команды целевой функции. Потом мы запускаем gdb с двумя параметрами (образ ядра и объект /proc/kcore). Далее, мы должны дизассемблировать оригинальную функцию, используя внутреннюю команду disass, как показано ниже.

#gdb /boot/vmlinux-2.4.* /proc/kcore (gdb) disass sys_read Dump of assembler code for function sys_read: 0xc013fb70 <sys_read>: mov $0xc88ab0a6,%ecx 0xc013fb73 <sys_read+3>: jmp *%ecx 0xc013fb77 <sys_read+7>: mov %esi,0x1c(%esp,1) 0xc013fb7b <sys_read+11>: mov %edi,0x20(%esp,1) 0xc013fb7f <sys_read+15>: mov $0xfffffff7,%edi ...

В выводе выше мы можем увидеть, что первая команда помещает значение (адрес функции злоумышленника) в регистр ecx. Вторая инструкция выполняет безусловный переход по этому виртуальному адресу - 0xc88ab0a6.

Чтобы удостовериться, что системный вызов sys_red перехвачен, нам нужно дизассемблировать оригинальную функцию. Оригинальная функция находится в образе ядра vmlinux-2.4.x.

#gdb /boot/vmlinx-2.4.* (gdb) disass sys_read Dump of assembler code for function sys_read: 0xc013fb70 <sys_read>: sub $0x28,%esp 0xc013fb73 <sys_read+3>: mov 0x2c(%esp,1),%eax 0xc013fb77 <sys_read+7>: mov %esi,0x1c(%esp,1) 0xc013fb7b <sys_read+11>: mov %edi,0x20(%esp,1) 0xc013fb7f <sys_read+15>: mov $0xfffffff7,%edi ...

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



Содержание раздела