Heap spraying

Heap spraying у інформаційній безпеці — це атака, використовує помилки в роботі з пам'яттю програми. Атакуючи за допомогою heap spraying, хакер змушує додаток виділити пам'ять під велику кількість об'єктів, що містять шкідливий код. При цьому підвищується ймовірність успіху експлойта, який переносить потік виконання на деяку позицію всередині купи. Важливо розуміти, що без експлойта, що дозволяє змінювати потік виконання, heap spraying не завдасть якоїсь шкоди. Атака заснована на передбачуваності положення купи в адресному просторі процесу. Крім цього, виділення пам'яті в купі – це детермінована операція, яка і дозволяє з успіхом застосовувати цю техніку. Heap spraying особливо ефективна в браузерах, де хакер може виділяти пам'ять, використовуючи кілька рядків JavaScript на веб-сторінці. Важливу роль грає подібність виділення пам'яті в різних операційних системах, що робить цю атаку кроссплатформенною. В результаті можна внести певну послідовність байт (наприклад, машинну інструкцію) в заздалегідь передбачену адресу в пам'яті цільового процесу[1].

При створенні процесу в операційній системі під його потреби виділяється адресний простір[2][3][4], в якому розташовані користувальницькі дані, виконуваний код і деяка системна інформація, яка залежить від конкретної операційної системи. Користувальницькі дані розподіляються між купою і стеком в залежності від способу виділення пам'яті під них[5]. Так, у сегменті стека зберігаються змінні з автоматичним класом розміщення, а також інформація, яка зберігається при кожному виклику функції, наприклад, статичні змінні і адреси повернення при виклику функції. Купа — це область оперативної пам'яті, тобто при динамічному виділенні пам'яті місце виділяється в купі. Традиційно купа і стек ростуть назустріч один одному.

Основна концепція

Пам'ять "До" і "Після" heap spraying

Heap spraying сама по собі не є вразливістю. Однак вона може бути використана для доставки шкідливого коду у виконуваний область пам'яті процесу. Ця техніка використовує детермінованість операції виділення пам'яті в системі. Мається на увазі, що великий обсяг пам'яті часто розташовується з одним і тим же зміщенням в адресному просторі процесу. Проте ця техніка не в змозі створити пролом в самій системі безпеки. Тому для її використання необхідна уразливість, що дозволяє змінити порядок виконання команд (машинних інструкцій)[6].

Використовувати цю техніку важко, оскільки дуже велика кількість факторів, що впливають на виконання процесу (з точки зору хакера). Тим не менш, з допомогою heap spraying можна виконати велику кількість інструкцій, що частково компенсує цю складність та дозволяє підвищити вірогідність успішного злому[7].

Heap spraying може бути реалізована для більшості операційних систем і архітектур. Основна трудність – знаходження уразливості, яка дозволяє перенаправити потік виконання. Динамічне виділення великої кількості пам'яті, як говорилося раніше, — операція, що дозволяє передбачити положення купи в пам'яті (в момент проектування віртуальної пам'яті на фізичну) . Кожен раз виконуючи одну і ту ж послідовність звернень до пам'яті, купа буде з великою часткою ймовірності надаватися на одному і тому ж місці.

Характерний вигляд блоків

Однак, щоб підвищити цю ймовірність, необхідно, щоб розмір шматка виділюваної пам'яті був порівнянний з розміром сегменту або сторінки, залежно від способу організації пам'яті.

Основна проблема цієї атаки – зміна потоку виконання. Без можливості перехоплення виконання цей вид атаки не має сенсу. Деякі функції можуть зберігати адресу повернення в купі, тоді хакер може спробувати змінити їх. У цьому випадку при поверненні з такої функції відбудеться переміщення в ділянку пам'яті, зручну для хакера, і, як наслідок, почне виконуватися шкідливий код. Будь-яка функція, що зчитує адресу, що знаходиться в купі, може бути використана як уразливість. Хакер може підмінити цю адресу на адресу модифікованого ним ділянки пам'яті. Це може призвести до спрямування потоку виконання на шкідливий код. Однак це не так просто, як здається[8].

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

Кроки, спрямовані на реалізацію heap spraying:

  • Визначення розміру шматка виділюваної пам'яті таким чином, щоб одне виділення відповідало розміру сторінки.
  • Виділення декількох шматків, в яких розташовуються NOP і shell-код.
  • Використання відомої вразливості для перенаправлення лічильника команд на передбачуване положення шматків, наприклад, за допомогою переповнення стека.
  • Виконання виділеної області.

Цей тип атак дуже ефективний в браузерах. Більшість браузерів підтримують виконання скриптів. Хакер може виділити необхідну пам'ять, використовуючи кілька рядків JavaScript або ActionScript на веб-сторінці. Важливу роль відіграє схожість виділення пам'яті в різних операційних системах, що робить цю атаку кроссплатформнною. Більш того, адреси на які необхідно здійснити перехід, будуть схожі[9].

Історія

Перший раз heap spraying використовувалася в 2001 році і стала широко поширеною влітку 2005 року. Після було знайдено велику кількість вразливостей в Internet Explorer[10][11]. Експлойти були дуже схожі між собою. Кожен такий експлойт складався з heap spraying, метод реалізації якої не змінювався, і перенесення лічильника команд на необхідне місце в пам'яті. Тому новий експлойт виходив зміною кількох рядків HTML і переключенням на нову уразливість.

Реалізація

JavaScript

Найпростіший спосіб виділити місце в пам'яті браузера — декларувати рядкову змінну і ініціалізувати її.

Приклади виділення пам'яті на JavaScript: [9]:

 
		var myvar = "CORELAN!";
		var myvar2 = new String("CORELAN!");
		var myvar3 = myvar + myvar2;
		var myvar4 = myvar3.substring(0,8);

Це дуже прості приклади, так як виділені рядки невеликі. Шматок shell-коду значно більше, але все ж менше цілої сторінки пам'яті.

Гіпотетично можна записати необхідний shell-код багато разів у кожен виділений нами блок, але тоді зловмисникові доведеться стежити, на яку конкретно адресу потрапляє покажчик, так як він не повинен потрапити на середину виконуваного коду. Зазвичай надходять по-іншому — виділяють шматки, містять безліч NOP-ів, і в кінці прописують необхідні команди. Тоді в силу лінійності розташування блоків в купі простіше дотриматися лінійності виконання коду і не потрібно прейматися про точності попадання на початок шматка пам'яті.

При правильному виборі розміру шматки пам'яті що виділяються повинні бути дуже близькі до розміру елемента купи. Якщо виділений шматок пам'яті буде менше, то це місце буде вільно. Менеджер пам'яті, в кращому випадку, залишить системне сміття в цьому «незайнятому просторі», а в гіршому покладе об'єкт, відповідний за розміром. У будь-якому випадку це призведе до помилки при спробі виконати дану ділянку пам'яті.

Таким чином, використовується зловмисниками скрипт виглядає так: [9]:

<html>
 <script >
 var shellcode = unescape('%u\4141%u\4141'); // це напис CORELAN
 var bigblock = unescape('%u\9090%u\9090'); //90 - код NOP
 var headersize = 20;
 var slackspace = headersize + shellcode.length;// початковий розмір нашого шматка: корисний код + розмір заголовка
 while (bigblock.length < slackspace) bigblock += bigblock; //заповнення NOP-ами 
 var fillblock = bigblock.substring(0,slackspace);//корисний код - наповнення
 var block = bigblock.substring(0,bigblock.length - slackspace);//просто NOPы
 while (block.length + slackspace < 0x40000) block = block + block + fillblock;
 //заповнення до розміру елемента купи - в даному випадку - це 0x40000
 var memory = new Array();
 for (i = 0; i < 500; i++){ memory[i] = block + shellcode }// виділення декількох таких елементів.
 </script>
 </html>

unescape()- це функція, що дозволяє покласти байти саме в тому порядку, в якому зазначено в аргументі.

VBscript

VBscript використовують Internet Explorer для створення рядків з допомогою string. Концептуально не відрізняється від реалізації на JavaScript, тільки назви функцій змінюються.

ActionScript

У липні 2009 були знайдені експлойти, що дозволяють використовувати ActionScript для реалізації heap spraying в Adobe Flash.

HTML5

У вересні 2012 на EuSecWest 2012[12] була представлена нова реалізація. Федеріко Мутііс (Federico Muttis) і Анібал Сакко (Anibal Sacco) показали, що heap spraying з високим ступенем гранулярності може бути реалізований за допомогою технології HTML5. Вони використовували низькорівневий растровий інтерфейс, наданий canvas API.

Зображення

Існують методи, що використовують завантаження зображень. Зображення складають з NOPів і далі діють, як і в попередніх випадках.

Способи запобігання

Як і при будь-яких переполнениях буфера, є три основні шляхи захисту. Часто простіше запобігти зміні потоку виконання, чим самому використанні буфера. Сучасні операційні системи використовують всі перераховані нижче методи:

  1. Запобігання виконання шляхом поділу даних і виконуваного коду, зазвичай з використанням архітектурних рішень, наприклад NX bit. Наприклад, вже в більшості ОС впроваджено DEP
  2. Підвищення випадковості розташування даних в пам'яті. Наприклад, щоб наступний виділений елемент купи не мав фіксованого зміщення відносно поточного. Вже впроваджено в більшості ОС: ASLR.
  3. Збільшення кількості перевірок дотримання меж буфера в менеджері пам'яті.

Проекти, пов'язані з даним типом атаки:

  • проект Nozzle від Microsoft Research ставить своєю метою запобігання heap spraying.
  • BuBBle — це інший проект, метою якого є мінімізація шкоди від даної атаки[13].

Див. також

Примітки

  1. Benjamin Livshits, Paruj Ratanaworabhan, Benjamin Zorn. .
  2. Таненбаум Э., Вудхалл А. Операционные системы. Разработка и реалізація. — Питер. — С. 78-252.
  3. Рихтер Дж. Windows для профессионалов: создание эффективных Win32 приложений с учетом специфики 64х разрядной версии Windows. — Русская Редакция. — С. 68-118,333-418.
  4. У. Ричард Стивенс, Стивен А. Раго. UNIX. Профессиональное программирование. — Символ-Плюс. — С. 288-351.
  5. Брайан Керниган, Деннис Ритчи. Язык программирования Си. — Вильямс. — С. 93-123.
  6. Thomas Toth, Christopher Kruegel. . — ISBN 3-540-00020-8.
  7. Tilo Muller. .
  8. Марк Руссинович, Дэвид Соломон. {{{Заголовок}}}.
  9. Sotirov A. .
  10. HwaiGeeng, Chew. .
  11. Black Hat. .
  12. Anibal Sacco, Federico Muttis. .
  13. Francesco Gadaleta, Yves Younan, Wouter Joosen. .

Література

  • Рихтер Дж. Windows для профессионалов: создание эффективных Win32 приложений с учетом специфики 64х разрядной версии Windows. — Русская Редакция, 2008. — 720 с.
  • У. Ричард Стивенс, Стивен А. Раго. UNIX. Профессиональное программирование. — Символ-Плюс, 2014. — 1104 с.
  • Таненбаум Э., Вудхалл А. Операционные системы. Разработка и реализация. — Питер, 2007. — 704 с.
  • Брайан Керниган, Деннис Ритчи. Язык программирования Си. — Вильямс, 2015. — 304 с.
  • Марк Руссинович, Дэвид Соломон. Внутреннее устройство Windows. — Питер, 2013. — 800 с.

Посилання

This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.