litceysel.ru
добавить свой файл
1 2 ... 10 11

часть I

ошибки переполнения


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




Картинка 1 переполнение и его последствия

глава 1
зоопарк переполняющихся буферов
переулок монстров


ошибок переполнения не удалось избежать ни одной серьезной программе и они с завидной регулярностью обнаруживаются как в продукции Microsoft, так и в открытых исходниках. сколько ошибок до сих пор не выявлено – остается только гадать. это клад, настоящий клад! переполняющиеся буфера — это ключ к управлению миром! но чтобы ими воспользоваться требуется проделать очень длинный путь, многому научиться и многое познать. будда всем нам в помощь!




Картинка 2 переполняющиеся буфера, живущие своей жизнью

Подавляющее большинство удаленных атак осуществляется путем переполнения буфера (buffer overfull/overrun/overflow), частным случаем которого является затирание адреса возврата из функции (срыв стека). Тот, кто владеет техникой переполнения буферов, управляет миром, а кто не владеет – тем владеет мир. Вот забросят вам TCP/IP пакетик на компьютер, сорвут стек и отмотают жесткий диск к чертовой матери.

Что представляют собой переполняющиеся буфера? Попробуем разобраться! Прежде всего выпьем пива и забудем весь тот shit, которым нас пичкали на уроках информатики. Забудем слово "оперативная память" – здесь мы будем говорить исключительно об адресном пространстве уязвимого процесса (не путать с процессором). Упрощенно его можно представить в виде строительной рулетки, вытянутой на всю длину. Вдоль этой рулетки раскладываются различные предметы обихода (пиво, сигареты, обнаженные красавицы и т. д.), изображающие из себя буфера и переменные. Каждый единичный отрезок соответствует одной ячейке памяти, но различные предметы занимают неодинаковое количество ячеек. Так, например, переменная типа BYTE занимает одну ячейку, WORD – две, а DWORD – все четыре.


Совокупность переменных одного типа, объединенная в массив, может занимать до хрена ячеек. Причем, ячейка не имеет никакого представления ни о типе переменной к которой она принадлежит, ни о ее границах. Две переменных типа WORD, можно интерпретировать как BYTE + WORD + BYTE, и никого не будет смущать, что голова WORD'а лежит в одной переменной, а хвост – в другой! С контролем границ массивов дела обстоят еще хуже. На аппаратном уровне такой тип переменных вообще не поддерживается и процессор не в состоянии отличить массив от бессвязного набора нескольких переменных. Поэтому, забота о суверенитете последнего ложится на плечи программиста и компилятора. Но первые – люди (а, значит, им свойственно ошибаться), вторые – машины (и, значит, они выполняют то, что приказал им человек, а не то, что он хотел приказать).

Рассмотрим простейшую программу типа "здравствуй Вася", которая спрашивает человека "как тебя зовут", а затем радостно сообщает "привет, как-тебя-там". Очевидно, что для хранения вводимой строки необходимо заблаговременно выделить буфер достаточно размера. А какой размер считать достаточным? Десять, сто, тысяча букв? Не суть важно! Главное не забыть вставить в программу контролирующий код, ограничивающий длину ввода размером выделенного буфера, в противном случае, если длина имени окажется слишком велика, оно вылезет из буфера и перезапишет посторонние переменные, расположенные за его концом. А переменные – это рычаги управления программой и перезаписывая их строго дозированным образом, мы можем вытворять с компьютером все, что угодно. Наиболее соблазнительная цель всех атакующих – командный интерпретатор, в кругах юнисоидов называемый шеллом (от английского shell – оболочка). Если хакер сумеет его запустить, судьба машины окажется предрешена.



Рисунок 1 количество обнаруженных дыр за каждый год по данным CERT или на ближайшее время хакеры без работы не останутся


следующая страница >>