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

Завоевание интернета

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

Спецвыпуск: Хакер, номер #059, стр. 059-066-7


К настоящему времени исходные тексты просочились в Сеть, и теперь их можно найти в любом парнокопытном. Полный объем архива составляет 800 Мб, и его перекачка на Dial-Up'е может занять несколько месяцев, однако она стоит того! Впрочем, отсутствие исходных текстов - это еще не преграда. IDA Pro в руки – и поехали.

Где и как искать дыры

Приемы поиска переполняющихся буферов в Cisco IOS мало чем отличаются от приемов для других осей, но в ней есть и свои особенности. Стек используется крайне редко, в основном она налегает на кучу. По сообщениям Cisco, разрушение кучи - наиболее распространенный баг ее маршрутизаторов. Но вот о том, что причиной разрушения являются переполнения динамических буферов, она предпочла умолчать. Так что дыры есть! Методика переполнения кучи подробно описана в моей книге "Hacker shellcoding uncovered" и в статье "Once upon a free()" из 57-го номера Phrack'а. В IOS все блоки памяти объединены в двунаправленный список следующего типа:

foo->prev->next = foo->next;

foo->next->prev = foo->prev;

При освобождении памяти выполняется следующий код, исключающий текущий блок из цепочки занятых блоков:

*prev=*next;

*(next+20) = *prev;

Результатом этой операции становится запись в ячейки *prev и *(next+20) значений *next и *prev. Если в результате переполнения нам удастся подменить поля prev и next, мы сорвем банк, получив возможность писать произвольные данные/код в любое выбранное место. Эта техника (кстати, она разработана хакерами FX и KIMO) получила название "Uncontrolled pointer exchange", но, прежде чем воспользоваться ей, необходимо познакомится со структурой кучи. Она довольно проста:

Вначале идет так называемый магический номер (MAGIC), равный AB1234BCh, а в самом конце - Красная Зона (REDZONE), равная FD1001DFh. Обе выполняют охранную функцию, и нельзя затирать их. Значение указателя prev проверяется перед освобождением, и потому должно быть валидно. В упрощенном виде проверка выглядит так:

if (next_block->prev!=this_block+20) abort();

Еще проверяется значение поля Size + Usage, старший бит которого определяет занятость блока (0 - свободен, 1 - занят), что создает проблемы при строковом переполнении, поскольку мы не можем располагать здесь нули, а минимальное значение, которое мы можем получить, получается слишком большим (7F010101h). Однако тут есть обходной путь. Поскольку переполнение разрядной сетки никем не контролируется, использование значений типа 7FFFFFFFh даст ожидаемый результат.

Остальные поля никак не контролируются и могут содержать любые значения. Короче говоря, написание shell-кода вполне возможно. Операционная система IOS использует статические адреса (а это хорошо!), но они меняются от одного билда к другому – вот это плохо. Поэтому, прежде чем атаковать жертву, необходимо тем или иным способом определить версию IOS (иначе червь сдохнет еще в зародыше), что можно сделать через CDP или SNMP.

Назад на стр. 059-066-6  Содержание  Вперед на стр. 059-066-8