Привет, Сегодня мы поговорим об атаках переполнения буфера. Эти атаки состоят в том, чтобы использовать ошибки не пользователями, а разработчиками программного обеспечения. Мы выясним, может ли хакер использовать и как предупредить администратора, и мы приведем несколько практических примеров для работы!

Чтобы понять этот предмет, необходимо знать некоторые понятия, чтобы мы могли понять более глубокий предмет. Основной темой этой статьи является память, она на сегментах, благодаря тому, что она аккуратна и разработчик программного обеспечения знает, какие фрагменты он может использовать. Знания о памяти полезны для разработчиков на ассемблере, C и C++, которые полностью оптимизируют и защищают программу.

Память разделена на пять сегментов

  1. Сегмент text здесь размещает написанные разработчиком программы инструкции, которые переведены на машинный язык, поэтому ассемблер ничего не может сохранить в этом сегменте и его размер не может измениться после загрузки программы в память.
  2. Сегмент data содержит глобальные переменные и строки с примерами объявленных констант.
  3. Сегмент bss содержит переменные globals и statics, которым не нужно присваивать значение.
  4. Куча сегментов изменилась и используется с динамическими переменными, которые явно назначаются и отправляются разработчику программного обеспечения.
  5. Стек сегментов используется автоматически для локальных переменных, вызывающих функции, для хранения одного примера аргумента вызова. Подобно куче сегментов, имеет изменяющийся размер.

Обозначение переполнения буфера относится именно к стеку, поэтому мы расскажем об этом сегменте. Стек можно визуализировать как кирпичную башню, которая имеет константу, переменные по очереди выдвигаются в зенит. После пересечения максимального значения башня может упасть и сложиться, чтобы переполнить память. Если мы захотим взять переменную из стека, мы возьмем ту, что находится сверху.

Для работы со стеком нужны две основные команды:

PUSH — для размещения в стеке.

POP – удалить из стека

Система должна знать реальную вершину стека адресов, которая знает, с какого места оперировать с переменными. Процессор использует эту запись, ESP сохраняет индекс верхнего стека.

Стек действий буду представлять простой программой:

У этой программы есть задача только записать аргументы, полученные от пользователя. Чтобы использовать стек, в программе действия мы помещаем простую функцию func, которая вызывает функцию уровня main.

Посмотрите на изображение ниже (да, я знаю, что я не художник)

Действия программы начинаются с функции main. сначала будут помещены фрагменты, написанные пользователем, затем выполняется функция main, которая представлена ​​записями EIP и EBP. Запись EIP, индикаторные инструкции указывают на текущее место выполнения программы. Таким образом, программа знает, в какое место нужно вернуться после завершения выполнения функции. Следующая запись EBP, так называемый базовый индикатор, запоминает текущую вершину стека. Следующим шагом является вызов функции func, ранее помещённой в стек был аргумент, который принимал функцию, теперь количество аргументов, которые дал пользователь. Затем они снова откладываются на стековые регистры EIP и EBP, но относятся на возврат из функции func.

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

Но это не конец теории, буфер остался, буфер — это просто кусок памяти для определенного количества данных.

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

Чтобы увидеть, что происходит на самом деле, нужно проанализировать работу еще одной простой программы.

текст в первых функциях printf: перед копированием данных в bufor

текст во второй функции printf: после копирования данных в bufor

Программа получает значение от пользователя. Начальное значение переменной initial равно 0. Также объявляем буфер, размер которого равен десяти символам, его размер зависит от архитектуры вашего компьютера. Функция printf отображает объем памяти, который занимает тип char.

С помощью функции strcpy мы можем скопировать значение, введенное пользователем, в буфер, вы можете заметить, что мы контролируем это и копируем все, что происходит.
В конце программа записывает буквами значение переменной int после скопировать процесс в буфер.

После теоретических знаний программы проверим ее работу на практике.

текст на изображении: перед копированием данных в буфер

После копирования данных в bufor

В первом случае значение int равно нулю, что является хорошим результатом, т.к. в буфере на моем компьютере может находиться до 13 символов, т.е. до 12 байт, т.к. один символ равен 1 байту и функция strcpy перезаписывает всю строку, кроме ее знака конца. некоторые более или менее.

При втором запуске программы значение int a по-прежнему равно нулю, что по-прежнему является правильным результатом.

При третьем запуске программы значение int было перезаписано значениями C в шестнадцатеричной форме, поскольку остальные символы не помещались, и отображалась ошибка, исключающая сегментацию, означающую, что программа пыталась сослаться на область памяти. который не был выделен ему.

Я надеюсь, вы знаете, что такое действие стека и буфера, и сейчас мы собираемся реализовать атаку переполнения буфера, конечно, это простой пример, потому что вам нужно только понять, что это такое. Посмотрите на код ниже:

Текст в первом printf: введите свой логин!

Текст во втором printf: введите пароль!

Текст в третьем printf: Вы успешно вошли в систему!

Этот код будет выполняться, если переменная ok будет истинной, a будет истинной, если будет равно 1
В этом коде самое главное то, что функция scanf не имеет фиксированного максимального размера строки, поэтому любой логин или пароль любой длины можно ввести, если вы введете слишком много символов (количество символов зависит от системы) выйдет из буфера, перезаписав ранее установленную переменную стека, то есть переменную ok. Мы будем использовать эту ошибку. Мы сначала введем неправильные данные, затем правильные данные, затем попробуем ввести, например, 30, независимо от того, какие символы, мы увидим, какие будут эффекты.

текст на изображении: введите свой логин:

текст на изображении: введите пароль:

текст на изображении: Неверный логин или пароль!

Это сработало. Переменная int ok была перезаписана и мы залогинились в систему, так как вы видите как система загружает системную оболочку, ее можно отключить командой «выход». Для устранения этой ошибки достаточно изменить:

Вы уже знаете, что такое стек и буфер, и знаете, как это использовать на практике, конечно, я просто объяснил основы, память, переполнение, стек и буферы, об этом можно написать десяток книг.

Этот контент также можно найти в steemit: https://steemit.com/hacking/@slawas/hacking-3-buffer-overflow-attacks

И в моем блоге devman.pl: http://devman.pl/additions/hacking-3-buffer-overflow-attacks/

Надеюсь, я все доступно объяснил, если что-то не понятно, дайте знать в комментарии, берегите себя!!!