Переполнение буфера — ошибка работы с памятью, при которой программа записывает в буфер больше данных, чем он вмещает, и затирает соседние области памяти.
Как происходит переполнение буфера
Программы на C и C++ выделяют буферы фиксированного размера для строк, сетевых пакетов и других данных. Если код копирует входные данные без проверки длины — например, функциями strcpy или sprintf, — лишние байты «перетекают» в соседнюю память. При переполнении в стеке можно перезаписать адрес возврата функции, при переполнении в куче — повредить другие объекты и служебные данные аллокатора.
Атакующий, управляющий этими данными, может перенаправить выполнение на свой код или собрать его из существующих фрагментов (ROP — возвратно-ориентированное программирование). Итог — удалённое выполнение кода или повышение привилегий, в лучшем случае — падение программы.
Почему это важно
Переполнение буфера — один из самых старых и эксплуатируемых классов уязвимостей. Его использовал червь Морриса в 1988 году, а Code Red (2001) и SQL Slammer (2003) распространились по миру через переполнения в серверах Microsoft. Запись за пределы буфера (CWE-787) по-прежнему входит в число лидеров рейтинга CWE Top 25 самых опасных программных ошибок. По данным Microsoft и Google, ошибки работы с памятью вместе с use-after-free составляют большинство критических уязвимостей в крупных проектах на C/C++.
Как предотвратить
- Писать новый код на языках с безопасной работой с памятью — Rust, Go, Java, C#, как рекомендуют CISA и АНБ.
- В C/C++ использовать функции с проверкой границ и современные контейнеры, тестировать фаззерами и AddressSanitizer.
- Не отключать защиты компилятора и ОС: stack canary, DEP/NX, ASLR, CFI.
- Быстро ставить обновления — публичные эксплойты для переполнений появляются быстро.