Переповнення буфера: причини, ефективні методи вирішення проблеми і необхідний захист

Атака часовій області зберігання

Буфер являє собою тимчасову область для зберігання даних. Коли програма або системний процес розміщує більше даних ніж було виділено для зберігання, додаткові переповнюються. Це призводить до того, що деякі з них просочуються в інші buffer, пошкоджують або замінюють дані.

При атаці з переповненням додаткові дані містять спеціальні інструкції для дій, призначених хакером або зловмисних користувачем, наприклад, вони викликають відповідь, який пошкоджує файли, змінює дані або розкриває особисту інформацію.

Зловмисник використовує експлойт з переповненням, щоб скористатися програмою, яка очікує введення користувача. Існує два типи переповнення buffer: на основі стека і купи. Засновані на купі важкі для виконання і найменш поширені, при цьому атакують додаток, заповнюючи простір, зарезервоване для програми.

Стек – простір пам’яті, що використовується для зберігання користувальницького введення. Таке переповнення частіше зустрічається у зловмисників, які використовують програми.

Сучасні компілятори зазвичай надають можливість перевірки переповнення під час компіляції/компонування, але під час виконання досить складно перевірити цю проблему без якого-небудь додаткового механізму захисту обробки винятків.

Варіанти роботи програми:

  • Enter: 12345678 (8 байт), програма працює без збоїв.
  • Enter: 123456789 (9 байт), з’явиться повідомлення «Помилка сегментації», програма завершується.
  • Уразливість існує через переповнення, якщо користувальницький введення argv перевищує 8 байтів. Для 32-бітної системи (4 байта) заповнюють пам’ять подвійним словом (32 біта). Розмір символу становить 1 байт, тому якщо запитати буфер з 5 байтами, система виділить 2 подвійних слова (8 байтів). Ось чому при введенні більше 8 байтів Buffer буде переповнений.

    Подібні стандартні функції, які технічно менш уразливі, існують. Наприклад, strncpy (), strncat () і memcpy (). Проблема з цими функціями полягає в тому, що відповідальність за визначення розміру буфера лежить на програміста, а не на компіляторі.

    Кожен програміст C/C++ повинен знати проблему перш ніж починати кодування. Багато генеруються проблеми в більшості випадків можуть бути захищені від переповнення.