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

Уразливості компіляції

У разі коли небезпечна функція залишає відкриту можливість переповнення буфера C, то не все втрачено. При запуску програми компілятори часто створюють випадкові значення, відомі як канарки (canary), і поміщають їх в стек, тому являють небезпеку. Перевірка значення канарки по відношенню до її первісного значення може визначити, чи відбулося переповнення буфера Windows. Якщо значення було змінено, програма буде закрита або перейде в стан помилки, а не до потенційно зміненим адресою повернення.

Деякі сучасні операційні системи надають додаткову захист від переповнення буфера у вигляді нездійсненних стеків і рандомізації розміщення адресного простору (ASLR). Неисполняемые стеки – запобігання виконанню даних (DEP) – позначають стек, а в деяких випадках інші структури як області, де код не буде виконаний. Це означає, що зловмисник не може впровадити код експлойта в стек і чекати його успішного виконання.

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

Він працює шляхом рандомізації областей пам’яті структур, так що їх зміщення складніше визначити. Якщо б ця захист існувала в кінці 1980-х років, хробака Морріса можна було б не допустити. Це пов’язано з тим, що він функціонував частково, заповнюючи буфер в протоколі UNIX finger кодом експлойта, а потім переповнював його, щоб змінити адресу повернення і вказував на заповнений буфер.

ASLR та DEP ускладнюють точне визначення адреси, який потрібно вказати, виконуючи цю область пам’яті повністю неробочою. Іноді уразливість прослизає крізь тріщини, відкриті для атаки переповнення буфера, незважаючи на наявність елементів управління на рівні розробки, компілятора або операційної системи.