Основы переполнения буфера
Основы переполнения буфера
Буфер переполняется, когда в него пытаются записать слишком много данных. Предположим, что буфер – это стакан воды. Можно наполнять стакан, пока он не станет полным, но потом вода начнет переливаться через край. Буферы похожи на стакан воды, а язык С (и производные от него, подобно С++) предлагает множество способов записи в буфер лишних, невмещающихся данных.
В этом случае при записи в стек данных появляются проблемы. Ранее были приведены примеры размещения в стеке локальных переменных (см. 16-байтный буфер данных в программах на рис. 8.1 и 8.4). Эти примеры показывают, что буфер фиксированного размера может быть размещен в стеке где угодно. Что произойдет при записи в буфер важной информации большего размера, чем может вместить размещенный в стеке буфер? Подобно стакану с водой, буфер переполнится!
При записи 16 байт в область буфера программы, представленной на рис. 8.1, он становится полным. При записи 17 байт один байт записывается в область стека, предназначенную для хранения переменной int2. Произошло искажение, или порча, данных (data corruption). При всех последующих обращениях к переменной int2 будет получено ее неверное значение. Продолжая в том же духе, при записи в буфер 28 байт будет затерто ранее сохраненное в стеке значение регистра EBP, а при записи 32 байт – значение регистра EIP. В результате при выполнении команды возврата из функции ret в регистр EIP будет записано значение из стека (затертое при записи в буфер) и, интерпретируя записанное значение как адрес следующей выполняемой команды, будет передано управление по содержимому регистра EIP. Если в регистр EIP будет помещен указатель на программу, то она будет выполнена.
Языку С может быть приписано следующее высказывание: «Мы предлагаем достаточно веревки, чтобы повеситься». Другими словами, язык С предлагает мощные средства управления компьютером, которыми программист должен разумно пользоваться, избегая потенциальных проблем. C – язык, в котором чрезмерно строго не контролируются типы обрабатываемых данных (loosely typed language), поэтому в нем не предусмотрено каких-либо мер безопасности при обработке разнотипных данных. Часто в написанных на языке C программах происходит переполнение буфера из-за допущенных ошибок при обработке строк. В таблице 8.1 приведены некоторые из небезопасных функций обработки строк языка C. Эта таблица ни в коем случае не претендует на полное освещение всех проблематичных функций, но дает хорошее представление относительно наиболее часто используемых.
Таблица 8.1.
Примеры проблематичных функций языка С
В следующей секции приведен пример программы, в которой при обработке входных данных большого размера происходит переполнение буфера. Позднее будут внимательно рассмотрены варианты использования уязвимых к переполнению буфера программ для выполнения нужного программного кода.
Простое неуправляемое переполнение: программа-пример
На рисунке 8.10 приведен простой пример неуправляемого переполнения. Он не годится для использования на практике, но полезен для изучения. Программа демонстрирует наиболее типичную ошибку программирования, которая отражается на работоспособности программы. В программе вызывается специально написанная для примера функция bof(), которая записывает двадцатисимвольную строку в буфер, предназначенный для хранения 8 байт. В результате происходит переполнение буфера. Заметьте, что в главной функции main функция printf() никогда не будет вызвана, поскольку в результате переполнения буфера при завершении функции bof () управление будет передано по неверному адресу возврата. Приведенная на рис. 8.10 программа была скомпилирована как консольное приложение Windows в режиме построения окончательной версии Release.
Рис. 8.10. Простое неуправляемое переполнение в стеке
Дизассемблирование
Хорошо раскрывают суть предыдущей программы результаты ее дизассемблирования, приведенные на рис. 8.11. Обратите внимание на то, что в функции main() стековые переменные не создаются, а переменная буфера buffer в функции bof() используется без предварительной инициализации. Определение переменной без инициализации уже может стать источником проблем и потенциальной возможности переполнения буфера. Это целиком зависит от состояния стека в момент создания переменной и ее использования в дальнейшем. Для инициализации переменных рекомендуется использовать функции memset() или bzero().
Рис. 8.11. Дизассемблированный вид программы-примера неуправляемого переполнения
Дампы стека
Приведенные дампы стека прослеживают изменения в стеке программы вплоть до возникновения переполнения буфера. Хотя в этой секции не рассматривается вопрос использования содержимого регистра EIP в личных целях, представленной на рис. 8.12 информации достаточно для того, чтобы позднее выполнить его.
Перед началом работы программы main() в стеке сохранены только значения регистров EBP и EIP, поскольку в программе main() нет локальных переменных.
На рисунке 8.13 показан дамп стека после начала работы функции bof(), но до инициализации переменной buffer функцией strcpy(). Поскольку буфер еще не проинициализирован, то в отведенной для него области памяти находятся случайные значения, которые ранее хранились в стеке. Дамп стека функции bof() после обращения к функции strcpy(), но до инициализации переменной buffer показан на рис. 8.14.
Рис. 8.14. Дамп стека функции bof() после обращения к функции strcpy(), но до инициализации переменной buffer
Теперь в дампе стека видны два параметра функции strcpy. Первый параметр указывает на область буфера, размещенного в стеке, а второй – на статический буфер, вмещающий 20 символов «А».
Из дампа стека видно, что функция strcpy(), проинициализировав буфер, уничтожила ранее записанные в стеке данные. В эпилоге функции bof() программа, попытавшись восстановить из стека содержимое регистра EBP, загрузит в регистр значение 0x414141. После этого команда ret восстановит из стека содержимое регистра EIP и попытается передать управление по восстановленному адресу. В результате возникнет ошибка нарушения доступа при попытке выполнить неразрешенную операцию с памятью, поскольку команда ret загрузит в регистр EIP значение 0x41414141, указывающее на недействительную область памяти (см. рис. 8.16).
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКДанный текст является ознакомительным фрагментом.
Читайте также
Параметры переполнения. Контейнеры с прокруткой
Параметры переполнения. Контейнеры с прокруткой Ни у одного из контейнеров, формирующих дизайн нашей Web-страницы, мы не задали явную высоту. Web-обозреватель сам установит для контейнеров такие значения высоты, чтобы они вместили свое содержимое полностью.Но что случится,
3.1 ЗАГОЛОВКИ БУФЕРА
3.1 ЗАГОЛОВКИ БУФЕРА Во время инициализации системы ядро выделяет место под совокупность буферов, потребность в которых определяется в зависимости от размера памяти и производительности системы. Каждый буфер состоит из двух частей: области памяти, в которой хранится
12.3.3.1 Выделение буфера
12.3.3.1 Выделение буфера Обратимся еще раз к алгоритму getblk, рассмотренному нами в главе 3. Алгоритм работает с тремя структурами данных: заголовком буфера, хеш-очередью буферов и списком свободных буферов. Ядро связывает семафор со всеми экземплярами каждой структуры.
14.2. Переполнение буфера
14.2. Переполнение буфера Это одна из самых популярных и в то же время наиболее сложная в использовании уязвимость. Для начала определимся, почему программисты допускают такие ошибки, при которых возможно выполнить переполнение буфера?В таких языках, как С++, для работы с
Параметры переполнения. Контейнеры с прокруткой
Параметры переполнения. Контейнеры с прокруткой Ни у одного из контейнеров, формирующих дизайн нашей Web-страницы, мы не задали явную высоту. Web-обозреватель сам установит для контейнеров такие значения высоты, чтобы они вместили свое содержимое полностью.Но что случится,
6.20.2 Использование буфера
6.20.2 Использование буфера Протокол IP, производящий пересылку датаграммы, несет ответственность за ее доставку. Для тех случаев, когда датаграмма по тем или иным причинам не попала в точку назначения, предусмотрен буфер датаграмм, позволяющий произвести операцию
3.6. Менеджеры буфера обмена
3.6. Менеджеры буфера обмена Во время работы с текстом вы наверняка что-то копируете в буфер обмена. Текстовый редактор Word умеет хранить несколько таких фрагментов. Однако такие данные находятся там недолго – стоит выключить компьютер или просто скопировать другой текст,
Переполнение буфера
Переполнение буфера Некоторые вирусы и атаки достигают цели без участия пользователя. Несмотря на усилия, интенсивность удаленных атак не снижается, а отражать их становится все труднее. Как это получается? Ведь чтобы программа, пусть и зловредная, что-то сделала, она
10.6.1. Переполнение буфера
10.6.1. Переполнение буфера Почти псе основные Internet-демоны, включая демоны таких программ, как sendmail, finger, talk и др., подвержены атакам типа переполнение буфера. О них следует обязательно помнить при написании программ, которые должны выполняться с правами пользователя root, а
Просмотр буфера обмена
Просмотр буфера обмена Пример на основе простого модуля-класса, осуществляющего просмотр буфера обмена.unit ClipboardViewer;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;type TForm1 = class(tform) procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject);private FNextViewerHandle : THandle; procedure WMDrawClipboard(var message: TMessage);
8.2. Использование буфера обмена
8.2. Использование буфера обмена Буфер обмена представляет собой область оперативной памяти, которая используется операционной системой для временного хранения данных. Он выступает в роли общего хранилища данных для всех приложений системы, фактически любая программа
Глава 8 Переполнение буфера
Глава 8 Переполнение буфера В этой главе обсуждаются следующие темы: • Стек • Стековый фрейм функции • Основы переполнения буфера • Пример программы, уязвимой к переполнению буфера • Современные способы переполнения буфера • Новаторские принципы построения
Современные способы переполнения буфера
Современные способы переполнения буфера После изучения обязательного минимума пришло время познакомиться с современными способами переполнения буфера. Одни из них применимы повсеместно, другие – в частных случаях. С течением времени злоумышленники узнают о
Использование буфера обмена
Использование буфера обмена Последовательность копирования ячеек с помощью буфера обмена следующая.1. Сделайте активной нужную ячейку или выделите их диапазон.2. Щелкните на кнопке Копировать, которая находится в группе Буфер обмена вкладки Главная. Выбранные ячейки