На главную | Содержание | Назад | Вперёд
Наши друзья

 

 

Переполнение буфера

Переполнение буфера было и остается очень важной проблемой в аспекте безопасности программного обеспечения. Именно с возможностью использования атак на переполнение буфера для удаленного внедрения вредоносного кода связаны непрекращающиеся дискуссии и шумиха вокруг атак этого класса. Хотя методы проведения атак на переполнение буфера получили широкую огласку и рассмотрены во многих статьях и книгах, но мы не сомневаемся в необходимости этой главы. Проблема переполнения буфера с годами только усложнялась, появлялись другие типы атак, и в результате были разработаны принципиально новые атаки на переполнение буфера. Эта глава, по меньшей мере, может послужить в качестве основы для понимания хитроумных технологий атак на переполнение буфера.
Переполнение буфера
Атаки на переполнение буфера остаются в наборе наиболее мощных средств хакеров, и, похоже, такое положение дел сохранится еще несколько лет. Частично это объясняется широким распространением уязвимых мест, которые приводят к возможности проведения атак на переполнение буфера. Если существуют бреши в системе защиты, то рано или поздно ими воспользуются. В программах, созданных с помощью языков программирования, в которых заложены устаревшие возможности управления памятью, например в программах на С и C+ + , ошибки, связанные с возможностью проведения атак на переполнение буфера, к сожалению, возникают чаще, чем следует1. До тех пор, пока разработчики не начнут учитывать проблемы безопасности при использовании определенных библиотечных функций и систем­ных вызовов, атаки на переполнение буфера останутся в арсенале излюбленных средств хакеров.
Существует масса различных вариантов уязвимых мест, связанных с ошибками при управлении и "утечками" памяти. Поиск в системе Google по словосочетанию "buffer overflow" дает более 176000 ссылок. Очевидно, что ранее тайная и тщательно скрываемая методика проведения атак стала общеизвестной. Тем не менее, большинство злоумышленников (и специалистов по обеспечению защиты) имеют только поверхностное представление о технологии атак на переполнение буфера и о том ущербе, который эти атаки способны причинить. Большинство людей, интересующихся проблемами безопасности (те, кто читает статьи по безопасности, посещает конференции и присутствует на презентациях программ для обеспечения безопасности), хорошо знают, что атаки на переполнение буфера позволяют удаленно внедрить вредоносный код в чужую систему и запустить этот код. В результате появляется возможность добавления вирусов и другого переносимого кода для атаки на систему, а также установки потайных ходов, например, с помощью наборов средств для взлома (rootkit). К тому же, как правило, все эти действия вовсе не сопряжены со сверхчеловеческими усилиями.
Ошибки переполнения буфера относятся к тому виду ошибок, которые характерны для работы с памятью. Они уже вошли в историю компьютерных технологий. Когда-то память была "точным" ресурсом и управление памятью имело критически важное значение. В некоторых из систем того времени, например в системе исследовательского спутника "Вояджер", работа с памятью была организована настолько точно, что как только определенные части машинного кода больше не требовались, код навсегда стирался с модуля памяти, освобождая место для других данных. Это позволило создать саморазрушающуюся программу, которая могла быть выполнена только однажды. Яркий контраст с такой технологией представляют собой современные системы, в которых память расходуется огромными мегабайтовыми областями и практически никогда не освобождается. В большинстве современных компьютерных систем существуют серьезные проблемы при работе с памятью, особенно когда эти системы подключены к потенциально опасным средам взаимодействия, например Internet. Модули памяти достаточно дешевы, но последствия некорректного управления памятью могут стоить очень дорого. Неправильное управление памятью может привести к внутреннему искажению данных программы (особенно относительно потока управляющих команд), проблемам отказа в обслуживании и даже к возможности проведения удаленных атак на переполнение буфера.
Как ни странно, хотя уже давно нет никакого секрета в том, как избежать проблем с переполнением буфера, однако, несмотря на доступность решений в течение многих лет, но практически ничего не сделано для устранения проблем с переполнением буфера в программном коде для сетевых программ. На самом деле не так сложно решить эти проблемы с технической точки зрения, как с социальной. Основное затруднение заключается в том, что разработчики остаются весьма беспечными в отношении этой проблемы2. Похоже, что следующие пять-десять лет различные варианты атак на переполнение буфера будут оставаться весьма актуальными.
Программисты умеют без особых затруднений устранять ошибки на переполнение буфера самой распространенной формы, а именно ошибки на переполнение буфера в стеке (stack overflow). Устранить более замысловатые разновидности искажения данных в памяти, включая переполнение буфера в куче (heap overflow), значительно сложнее. В общем, уязвимые места, связанные с переполнением буфера, продолжают оставаться продуктивным средством для взлома программного обеспечения, что обусловлено широким применением современных схем управления памятью.
Переполнение буфера в стеке для забавы и с пользой
Мысленно возвращаясь во времена создания первых систем UNIX, вполне логично было бы предположить, что хорошо бы добавить процедуры обработки строки в язык программирования С. Большинство из этих процедур предназначены для работы со строками, которые завершаются символом NULL (так как символ NULL является нулевым байтом). Для эффективности и простоты в этих процедурах поиск символа NULL выполнялся в полуавтоматическом режиме таким образом, что программист не должен был непосредственно задавать размер строки. Предполагалось, что такой метод будет нормально работать, поэтому он и получил повсеместное распространение. К сожалению, поскольку основополагающая идея была очень и очень неудачной, теперь всем известна "всемирная болезнь" под названием переполнение буфера.
Очень часто процедуры обработки строки в программах на языке С без всякой проверки рассчитывают на то, что пользователь предоставил символ NULL. Когда этот символ отсутствует, программа буквально "взрывается". Этот взрыв может иметь необычные побочные эффекты, которыми может воспользоваться хакер для внедрения вредоносного машинного кода, исполняемого на атакуемом компьютере. В отличие от атак на анализаторы или вызовы функций API, атаки на переполнение буфера можно назвать структурными атаками, в которых используются недостатки архитектуры процесса выполнения программы. В каком-то смысле эти атаки просто разрушают стены нашего метафорического дома программного обеспечения, что приводит к разрушению всего дома.
Переполнение буфера возникает в результате очень прюстой, но постоянно повторяющейся ошибки при программировании (которой легко избежать). Самое серьезное затруднение состоит в том, что ошибки переполнения буфера стали настолько распространенными, что потребуются многие годы на окончательное решение этой проблемы. Но это только одна из причин, по которой переполнение буфера стали называть "атомной бомбой всех уязвимых мест программного обеспечения".
Искажение данных в памяти
Одно из возможных последствий ошибки при управлении памятью — это распределение искаженных данных поблизости определенной критичной области памяти. Выполняя контролируемое внедрение данных при переполнении буфера и наблюдая за изменениями в памяти с помощью отладчика, хакер вполне способен найти точки, в которых можно разрушить данные в памяти. В некоторых случаях, при искажении данных в областях памяти, в которых хранятся критически важные данные или информация о состоянии программы, злоумышленник может заставить программу снять все механизмы защиты или выполнить другое нужное хакеру действие.
Во многих программах информация о глобальном состоянии программы хранится в памяти в виде переменных, значений и двоичных флагов. В случае использования двоичных флагов, значения одного бита бывает достаточно для принятия важных решений. Например, решения о праве пользователя на доступ к файлу. Если такое решение основано на значении бита флага в памяти, то в программе точно есть интересная точка для атаки. Если (даже случайно) значение этого флага будет изменено на противоположное, то в работе программы произойдет сбой (который приведет к переходу в уязвимое состояние)4.
Во время подробного исследования ядра системы Windows NT один из авторов этой книги (Хогланд) обнаружил ситуацию, при которой внешне безобидное изменение значения одного бита устраняет все настройки безопасности для всей сети компьютеров под управлением Windows. Мы подробно рассмотрим эту ошибку в главе 8, "Наборы средств для взлома".

 

На главную | Содержание | Назад | Вперёд
 
Яндекс.Метрика