Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
БІКС 2015_1 / lec_2 BIKS.doc
Скачиваний:
76
Добавлен:
12.02.2016
Размер:
465.92 Кб
Скачать

5.4.1. Переповнення буфера у стеку

Переповнення буфера у стеку, або «зривання стека», є найвідомішою техкшкшєю використання переповнення буфера, яка, незважаючи на складність її реалізації, становить цілком реальну загрозу. Саме помилку перепрвнеііця буфЩа^5й^Щ^Й існувала в демоні fingerd, успішно використовував мережний хробак, відомий як вірус Морріса (докладніше про нього йтиметься в розділі 6). Якщо у програмі ви­являють помилку переповнення буфера у стеку, її оголошують як критичну.

Локальні змінні, оголошені у процедурі (функції), компілятор, як ^правило, розміщує у стеку. Тому розміщення у стеку буфера — явище типове. Розглянемо структуру стека. Як відомо, на багатьох апаратних платформах, зокрема на персо­нальних комп'ютерах, стек зростає «зверху вниз», тобто в бік молодших (мен­ших) адрес пам'яті. Після занесення даних у стек, його покажчик автоматично (апаратно) зміщується в бік молодших адрес, а в разі видалення даних зі стеку — в бік старших. Якщо у функції оголошено кілька локальних змінних, вони розмі­щуються (або для них резервується місце) у стеку послідовної неперервно. Поря­док розміщення залежить від компілятора, тобто першою у стек може потрапити або перша, або остання змінна. Якщо, наприклад, у функції є такий фрапдент [60]:

test_function ()

і <ЩТО

char а;

char buff[5];

char b;

}

то стан стека після виклику функції test_f unction () може бути таким, як на рис. 5.4. Різним може бути порядок розміщення змінних, тобто а і Ь можуть помі­нятися місцями.

Рис. 5.4. Стан стека після виклику функції testJunQBpn()

З наведеної схеми стають очевидними кілька важливих особливостей. По-перше, оскільки стек зростає в бік молодших адрес, а зміннЬйаповнюють пам'ять у напрямку зростання адрес, то переповнення буфера призведе до того, що будуть змінені ті дані, які були занесені у стек раніше. У нашому випадку це змінна Ьу службова інформація, а далі — адреса повернення з функції, тобто адреса ін­струкції, що розташована за командою виклику функції. У багатьох архітектурах комп'ютерів адреса повернення розміщується саме у стеку. У таких архітектурах шляхом переповнення буфера у стеку можна не лише модифікувати значення окремих змінних, але й передати керування у довільне місце.

Тепер розглянемо, за яких умов порушники матимуть можливість використа­ти переповнення буфера. Атака може бути здійснена за таких умов:

  • локальні змінні розміщені у стеку;

  • стек зростає «вниз»;

  • існують програми, в яких є вразливий код на кшталт наведеної вище функції

test_function() .

Атака матиме сенс, якщо:

  • функція приймає рядок символів від користувача (з клавіатури, зі стандарт­ного вводу, через мережу, від іншої програми);

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

За цих умов користувач-порушник має можливість змінити у стеку значення деякої змінної. Це може мати сенс, оскільки цілком імовірно, що така змінна ма­тиме критичне для безпеки системи значення (наприклад, логічна змінна, яка визначає результат перевірки прав доступу).

Порушник може передати керування іншій функції за таких додаткових умов:

  • адресу повернення також розміщено у стеку;

  • дані у стеку можуть бути інтерпретовані як команди.

Порушника, що хоче лише передати керування певній системній функції, ад­реса якої в пам'яті йому відома, вдовольнить виконання першої умови. Виконан­ня другої умови надає порушнику унікальну можливість — вставити програмний код, який потрібно виконати, безпосередньо в рядок, що порушник передає у бу­фер, і на нього ж передати керування через адресу повернення. Хоча апаратні за­соби, зокрема процесори Intel х86 (про них ітиметься в розділі 10), розрізняють сегменти коду і стека та підтримують заборону виконання інструкцій, розміще­них у стеку, моделі пам'яті поширених ОС ці заборони скасовують за допомогою повного перекриття сегментів. Підсумовуючи всі викладені вище умови здій­снення атак, можна дійти висновку, що більшість поширених ОС, зокрема UNIX і Windows, надають порушникам чимало можливостей щодо «зривання стека».

Ще раз переглянемо принципову схему атаки. Перед початком атаки в системі функціонує певна вразлива програма, що виконується з високими привілеями. Вона приймає дані (наприклад, текстовий рядок) від непривілейованих користу­вачів (або від будь-кого з мережі). Порушник передає програмі спеціально під­готовлений текстовий рядок. У результаті модифікуються важливі дані, до яких порушник із його повноваженнями доступу не мав, або виконується певний про­грамний код порушника з повноваженнями вразливої програми. Певний інтерес для порушників становлять програми зі встановленим атрибутом SUID і майже всі демони в UNIX, сервіси (служби) Windows, а також багато прикладних про­грам, які так чи інакше здійснюють виклик привілейованого коду. Детальніше технології переповнення буфера у стеку роаглянуто в [15, 60].