Штурм ядра Linux

Крис Касперски ака мыщъх

Хакер, номер #080, стр. 080-106-1

Секреты кернел хакинга

Ядро — это фундамент всей системы. На бажном ядре хорошего линуха не построишь. Разработчики не отходят от клавиатуры, выявляя все новые и новые ошибки, но баги размножаются быстрее! Далеко не все ошибки опасны, и лишь немногие из них допускают удаленное проникновение в систему. Найти такой баг — большая удача. Как хакеры исследуют ядро? Какие инструменты используют? Вот об этом мы сейчас и поговорим.

[введение]

Линуховое ядро - это довольно сложное инженерное сооружение, исходные тексты которого занимают свыше сотни мегабайт. Чего тут только нет! Драйвера, стек TCP/IP, менеджер виртуальной памяти, планировщик потоков, загрузчик ELF-файлов и многое другое. Все это хозяйство, откровенно говоря, просто кишит ошибками, над поиском которых работают десятки хакерских групп и тысячи независимых кодокопателей по всему миру. Хочешь к ним приобщиться? Что за вопрос! Кто же этого не хочет! Правда, не у всех получается, особенно с первого раза, но лиха беда начало!

[снаружи ядра]

Существуют, по меньшей мере, две методики поиска багов, но обе они порочные и неправильные. Одни хакеры предпочитают просматривать исходные коды ядра, анализируя строку за строкой, другие — дизассемблируют готовое ядро. Вот неполный перечень недостатков первого способа:

1. Вместо фактического значения переменной в Си сплошь и рядом используются макросы, определяемые неизвестно где, причем макрос может переопределяться многократно или, что еще хуже, различные включаемые файлы содержат несколько независимых макросов с одинаковым именем, так что глобальный контекстный поиск, практикуемый многими исследователями, не помогает (можно, правда, прогнать исходный текст через препроцессор "cpp имя_файла.c", но от этого его объем, а, значит, и время анализа только возрастет).

2. Ни одна известная мне IDE не способна отображать перекрестные ссылки на функции/данные, трассировать поток управления и делать множество других полезных вещей, с которыми легко справляется любой приличный дизассемблер.

3. В процессе компиляции могут "маскироваться" одни ошибки и добавляться другие, к тому же никогда нельзя сказать наперед, по каким адресам и в каком порядке компилятор расположит переменные и буферы в памяти, а для написания shell-кода - это критичный момент.

С другой стороны дизассемблерный листинг ядра не просто велик. Он огромен! Это миллионы строк ассемблерного кода, и если на каждую команду потратить хотя бы несколько секунд, даже поверхностный анализ растянется как минимум на сезон. Но ведь нам и не нужно дизассемблировать все ядро целиком! Ошибки не размазаны тонким слоем по машинному коду, а гнездятся во вполне предсказуемых местах. Никто не говорит, что ловить баги просто. Зато интересно! Признайся, разве тебе никогда не хотелось заглянуть в ядро, потрогать машинный код руками и посмотреть, как все это выглядит в живую (т.е. "на самом деле"), а не в исходных текстах, который любой "чиста хакер" может скачать из сети? И эта возможность сейчас представится!

[штурм ядра]

Для штурма ядра нам, во-первых, понадобится само ядро, которое мы собрались штурмовать. Какой дистрибутив выбрать? Лучше взять тот, что поновее, хотя особой разницы между ними нет, ведь ядро разрабатывается независимо от остальной "начинки". Главное, чтобы он был широко распространен, иначе, какой прок от дырки, которая есть только на одной-двух машинах во всем мире?

Содержание  Вперед на стр. 080-106-2
ttfb: 3.5240650177002 ms