Атака с переполнением буфера — это распространенная кибератака, которая намеренно использует уязвимость переполнения буфера, при которой контролируемые пользователем данные записываются в память. Отправляя больше данных, чем может поместиться в выделенный блок памяти, злоумышленник может перезаписать данные в других частях памяти.
Злоумышленники могут выполнять атаки с переполнением буфера по различным причинам, таким как перезапись критического кода или данных для аварийного завершения работы программы, внедрение вредоносного кода для запуска в программу или изменение критических значений, изменяющих поток выполнения программы.
Угроза переполнения буфера
Атаки с переполнением буфера могут использоваться для достижения различных целей, включая:
- В области памяти приложения находятся указатели, код и другие фрагменты данных, которые имеют решающее значение для способности программы выполняться. Перезапись этих данных может привести к сбою программы, что приведет к DoS-атаке.
- Распространенной целью эксплойтов с переполнением буфера является принуждение уязвимого приложения к выполнению кода, предоставленного злоумышленником. Это позволяет злоумышленнику запускать код в уязвимой системе с тем же доступом и разрешениями, что и у эксплуатируемого приложения.
- Использование переполнения буфера для запуска кода может расширить доступ злоумышленника к целевой системе. Этот расширенный доступ затем может быть использован для выполнения последующих атак.
Типы атак с переполнением буфера
Атака на переполнение буфера может быть выполнена несколькими различными способами, но некоторые из наиболее распространенных примеров включают:
- Программный стек содержит критически важные данные потока управления для приложения —такие как указатели возврата функций — и является распространенной целью атак с переполнением буфера. Перезапись возвращаемого указателя может привести к тому, что программа перейдет к данным, контролируемым злоумышленником, и выполнит их в виде кода, позволяя злоумышленнику запускать код с теми же разрешениями, что и приложение.
- Программная куча используется для динамического выделения памяти переменным, размер которых не определен при компиляции программы. Используя уязвимость переполнения буфера и заполняя системную кучу, злоумышленник может перезаписать критически важные данные приложения.
- Функции семейства printf в C/C++ могут использовать форматные строки, которые позволяют считывать и записывать данные из памяти. Если предоставленные пользователем данные интерпретируются как строка формата, они могут быть использованы для утечки или изменения конфиденциальных значений.
Примеры атак с переполнением буфера
Уязвимости, связанные с переполнением буфера, распространены в C/C++ и возникают, когда программа выделяет фрагмент памяти фиксированного размера, а затем небезопасно копирует в него данные. Следующий пример кода содержит уязвимость к переполнению буфера:
char buf[BUFSIZE];
gets(buf);
В этом примере кода переменная buf имеет фиксированный размер BUFSIZE. Однако функция gets будет считывать данные и сохранять их в buf до тех пор, пока не достигнет нулевого значения (0x00). Злоумышленник может воспользоваться этим, чтобы перезаписать данные после окончания buf.
Как предотвратить переполнение буфера
Уязвимости, связанные с переполнением буфера, можно предотвратить с помощью:
- Уязвимости, связанные с переполнением буфера, возникают, когда программа делает предположения о вводимых пользователем данных без проверки этих предположений. Проверка длины данных или копирование только определенного количества байт в ячейку памяти может помочь избежать переполнения буфера.
- Большинство компьютеров имеют встроенные средства защиты от переполнения буфера, такие как рандомизация расположения адресного пространства (ASLR), предотвращение выполнения данных (DEP) и защита от перезаписи при структурированной обработке исключений. Включение этих средств защиты значительно затрудняет выполнение атак с переполнением буфера.
- Переполнение буфера становится возможным благодаря таким уязвимым функциям, как gets, scanf и strcpy в C/C++. Уязвимостей, связанных с переполнением буфера, можно избежать, правильно используя безопасные версии этих функций.
- Переполнение буфера происходит в языках программирования с переменными фиксированного размера и без защиты памяти. Использование других языков программирования, таких как Python, Java или C#, затрудняет или делает невозможным переполнение буфера.
- Брандмауэры веб-приложений (WAFs) и решения для защиты веб-приложений и API (WAAP) могут выявлять и блокировать попытки использования уязвимостей переполнения буфера. Это снижает риск, который атаки с переполнением буфера представляют для безопасности корпоративных приложений (AppSec).