Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #69, АВГУСТ 2006 г.

ядро — на вилы

КРИС КАСПЕРСКИ АКА МЫЩЪХ

Спецвыпуск: Хакер, номер #069, стр. 069-032-6


Jun 22 14:00:44 /kernel: syshack unloadedd

; модуль выгрузил себя из памяти,

; восстановив оригинальный mkdir

# mkdir TEST-DIR ; пытаемся создать TEST-DIR еще раз

; теперь на экран не выводится никаких сообщений

# ls ; проверяем успешность создания TEST-DIR

Makefile TEST-DIR syshack.c syshack.ko syshack.o

; каталог TEST-DIR действительно создан!

; значит, mkdir был восстановлен правильно!

# kldstat ; просматриваем список модулей

Id Refs Address Size Name

1 3 0xc0100000 394090 kernel ; ядро

2 1 0xc0cac000 3000 daemon_saver.ko ; хранитель экрана

3 1 0xc0caf000 14000 linux.ko ; эмулятор LINUX'а

; модуля syshack в этом списке нет,

; значит, его выгрузка прошла успешно

[работа с libkmv, когда модули недоступны.]

Все операционные системы семейства BSD поддерживают библиотеку libkvm (Kernel Virtual Memory), предоставляющую унифицированный доступ к памяти ядра, как KLM-модули, но в отличие от них, сохранившую полную обратную совместимость. Другими словами, программа, написанная для FreeBSD, при переносе на OpenBSD или NetBSD не потребует никаких изменений!

Фактически, библиотека libkvm представляет собой высокоуровневую обертку вокруг псевдоустройства /dev/mem, изображающего из себя физическую оперативную память (псевдоустройство /dev/kmem включает в себя лишь виртуальную память ядра после трансляции адресов). Аналогичное псевдоустройство имеется и в LINUX'е, но соответствующей библиотеки для него нет, что жутко напрягает. Тем не менее, с псевдоустройством /dev/[k]mem на всех системах можно работать и напрямую, через обычный ввод/вывод, для обеспечения полной переносимости. Однако, целесообразность этого решения весьма сомнительна, поэтому сосредоточимся исключительно на библиотеке libkvm, а остальные способы доступа к ядерной памяти оставим за кадром.

Прежде чем работать с виртуальной памятью ядра, ее необходимо открыть, вызвав функцию kvm_open («man kvm_open») и передав ей в качестве имени файла NULL. Тогда, при успешном завершении операции, обеспеченная правами root'а, она вернет дескриптор. Если вместо NULL указать имя файла-образа ядра или кору, то открыты будут они, а не «живое» ядро в памяти, но нам это не нужно.

Передавая полученный дескриптор функциям kvm_read и kvm_write, мы сможем читать/писать память по заданным виртуальным адресам. Но какие именно адреса мы хотим читать? Вернее, как найти среди множества адресов полезную информацию, например, таблицу системных вызовов? В этом поможет функция kvm_nlist, разбирающая таблицу символов и возвращающая адрес элемента по его имени. Единственным ее аргументом (не считая дескриптора памяти ядра) является указатель на массив структур nlist, описанных в одноименном включаемом файле. В поле n_name заносится имя интересующего элемента и, если этот элемент действительно присутствует в таблице символов, то после завершения функции в поле n_value возвращается его виртуальный адрес.

Приведенная ниже программа (любезно позаимствованная из статьи «Playing Games With Kernel Memory... FreeBSD Style», опубликованной в #63 PHACK'е) определяет адрес таблицы системных вызов, адрес «нашего» системного вызова и адрес функции, по которой данный вызов располагается в памяти. Программа требует два аргумента — имя системного вызова (например, mkdir) и его номер (в случае mkdir равный 1), рекомендуя обратиться к файлу /usr/src/sys/sys/syscall.h, если номер вызова не известен (вообще-то данный файл располагается в каталоге /usr/include/sys/, но это неважно). На самом деле, имя системного вызова используется только для того, чтобы контролировать его существование, то есть никак не используется и для вычисления адреса используется номер syscall'а, который преобразуется в индекс таблицы системных вызовов. Это грубая недоработка! Если мы успешно определи адрес syscall'а по имени, то зачем нам его номер?! Если же мы можем (а мы можем) определять адреса syscall'ов по номеру через индекс в таблице системных вызовов, зачем нам нужно имя?!

Назад на стр. 069-032-5  Содержание  Вперед на стр. 069-032-7