В останньому дописі в блозі Project Zero команда знайшла спосіб обійти захист ядра в реальному часі від Samsung під назвою гіпервізор Knox.
Команда Google Project Zero перевірила ряд експлойтів, які дозволяють атакувати телефони Samsung, на яких працює нібито безпечний пакет безпеки Samsung Knox. У блозі зазначається, що всі вразливості були передані Samsung, яка фактично випустила їх виправлення в січневому оновленні програмного забезпечення.
Фон
Як частина набору програмного забезпечення безпеки Samsung Knox, представленого компанією Samsung, є частина програмного забезпечення, яка знаходиться між програмами Android і ядром, називається Гіпервізор. Це можна використовувати як додатковий рівень для додаткового захисту пристроїв Android. Гіпервізор Samsung Knox називається "Захист ядра в реальному часі" або скорочено RKP, оскільки я буду посилатися на нього в решті цієї статті.
Ядро знаходиться під RKP у стеку програмного забезпечення Android, а програми, які працюють на пристрої, розташовані вгорі. Ідея RKP полягає в тому, щоб забезпечити додатковий рівень безпеки для пристрою, оскільки всі запити (пам’яті та інших ресурсів), зроблені Додатки до ядра повинні спочатку пройти через Knox, який намагається виявити, чи програма щось робить не повинен. RKP також забезпечує безпеку через невідомість за допомогою додаткового рівня для приховування конфіденційної інформації, яку програма може використовувати для компрометації пристрою.
Повідомлення в блозі досить глибоко розповідає про те, як працюють пам’ять Android, RKP і операційні системи загалом, тому я скоротив і спростив його, щоб дати короткий огляд того, що було відкрито. Я заохочую вас прочитати статтю повністю, якщо у вас є час, оскільки вона дуже повчальна.
Експлойт №1:
КАСЛР або Рандомізація макета адресного простору ядра — це процес зміни місця розташування коду ядра в пам’яті на випадкову кількість під час завантаження. Кожного разу, коли пристрій завантажується, ядро завантажується в інший адресний простір (область пам'яті). Ідея полягає в тому, щоб ускладнити пошук коду ядра, щоб атакувати його, оскільки після кожного завантаження код ядра «зсувається» на випадкову кількість пам’яті. Це звучить як чудовий крок для запобігання потенційним нападникам, але нещодавнім дослідження показав, що ви можете справді перемогти це, не вимагаючи програмної помилки чи вразливості, оскільки KASLR насправді дуже важко реалізувати надійним способом проти локальних зловмисників.
У випадку з програмним забезпеченням RKP можливість обійти KASLR насправді простіше, ніж дослідження, згадане вище. На пам’ять усіх пристроїв Android посилаються вказівники, щоб захистити пристрої від атак, щоразу, коли пристрої Android друкують або виводять (чи на екран, чи файл для журналів або налагодження), посилання на вказівники анонімні, що робить неможливим з’ясувати, на що насправді вказує вказівник під час читання вихід.
Подумайте про вказівники пам’яті, як про дорожній знак, який вказує на місцезнаходження, а про анонімізацію – як про розмивання цього. Подібно до телебачення, анонімізація виконується після зйомок, Android також застосовує цю анонімізацію під час виходу і лише якщо анонімізацію налаштовано правильно, і автор стверджує що на кожному пристрої, з яким [він] стикався, було правильно налаштовано анонімізацію покажчика. Це може здатися так, ніби це дуже важко зламати, але все, що вам потрібно зробити, це знайти єдиний покажчик (подумайте про вуличний знак), який не був анонімним (розмитим) розробником ядра (зауважте, що це не ваш звичайний розробник програм для Android), коли вказівник записується в журнали або інше місце, наприклад. екран або a файл.
Отже, якщо ви можете знайти вказівник, який не був анонімним, ви можете обчислити випадковий зсув адреси ядра як різницю між ними. Цікаво, що автор не зміг знайти придатний для експлуатації покажчик у ядрі, але знайшов його в RPK де розробники забули анонімізувати вказівник у виводі налагодження (реєстрації), що сталося через опечатка. Щоб анонімізувати покажчики в Android, вам потрібно використовувати спеціальний код, і виявляється, що розробники RPK помилково використали малий регістр 'k' замість an велика буква "К". Тому було відносно просто визначити величину випадкового зсуву коду ядра та атакувати його.
Експлойт №2:
Наступний експлойт дещо складніший: Samsung Knox захищає ваш пристрій, застосовуючи набір правил до пам’яті пристрою, щоб зупинити шкідливий код. Правила такі:
- Усі сторінки (код у пам’яті), за винятком коду ядра, позначено як «Привілейоване виконання, ніколи» (це означає, що код тут ніколи не може виконуватися)
- Сторінки даних ядра (дані, які використовуються програмою в пам’яті) ніколи не позначаються як виконувані (тому код тут ніколи не може виконуватися)
- Кодові сторінки ядра (код у пам’яті) ніколи не позначаються як доступні для запису (тому жоден шкідливий код не може це змінити)
- Усі сторінки ядра позначено як доступні лише для читання в таблиці перекладу етапу 2 (таблиці, яка знаходиться між програмою та ядром, щоб надалі запобігати розпізнаванню програмами реальних місць пам’яті)
- Усі записи трансляції пам’яті позначено як доступні лише для читання для програм.
Ми зосередимося на правилі 3, оскільки саме тут автор виявив проблему з реалізацією наведених вище правил. RPK фактично позначає пам’ять для ядра як доступну лише для читання, однак через недогляд у KASL було виявлено діру, яка призвела до написання коду в нібито розділ «лише для читання».. Для того, щоб приховати розташування ядра під час завантаження, ядру виділяється пам’ять, але цей об’єм пам’яті набагато більший, ніж текстовий сегмент ядра. Через виділення більшого обсягу пам’яті стає набагато важче знайти фактичний код ядра, який може бути де завгодно, і, як ми бачили вище, він переміщується випадковим чином під час кожного завантаження пристрою.
Автор зміг підтвердити, що пам’ять, яка використовується ядром, справді була позначена як «лише для читання», однак решта цього великого обсягу пам’яті, яка використовується для приховування ядра, була ні позначено як «тільки для читання». Це пояснюється тим, що RKP захищає лише область, яка містить текст ядра, після застосування слайда KASLR.
Експлойт №3
У третьому експлойті автор отримав доступ до іншої області пам’яті, яка також має бути обмежена лише для читання. RKP захищає пам'ять і використовує a Реєстр конфігурації гіпервізора (HCR) для керування ключовими операціями ядра. Суть HCR полягає в тому, щоб дозволити дійсним і реальним операціям ядра отримати доступ до реєстрів і блокувати зловмисні атаки. Це робиться шляхом перевірки звернень до регістрів, які керують функціями віртуалізації. HCR налаштований на блокування певних операцій, які оброблятимуться зазвичай, дозволяючи RKP вибирати, дозволяти чи забороняти запит.
У цьому експлойті був контроль HCR не охоплюючи двох регістрів це виявилося дуже важливим. Автор глибоко дослідив довідковий посібник ARM і виявив, що перший реєстр дозволяє йому в основному вимикати RKP для програм. "Регістр керування системою для EL1 (SCTLR_EL1) забезпечує контроль верхнього рівня над системою, включаючи систему пам'яті." В ідеальному світі програма використовувала б пам’ять, яка була відображена через RKP, щоб RKP міг контролювати, до чого програма може отримати доступ. Однак вимкнення цього реєстру дозволило RKP бути відключеним шляхом фактичного повернення пристрою до того стану, в якому він працював до встановлення RKP, тобто пристрій відображається у фізичній пам’яті без додаткового захисту, який забезпечує RKP. Це, у свою чергу, означало, що автор міг читати та записувати в пам’ять, яка спочатку була правильно заблокована програмним забезпеченням RKP.
Другий реєстр, який було пропущено, мав більш тонкий вплив, але в кінцевому підсумку був таким же руйнівним для безпеки. The Регістр керування трансляцією для EL1 Регістр (TCR_EL1) безпосередньо пов’язаний із обсягом пам’яті, з якою працює програма, яка називається сторінкою. RKP жорстко закодовано на розмір сторінки 4 Кб, оскільки ядра AARCH64 Linux (наприклад, Android) використовують розмір перекладу 4 КБ. Розглянутий регістр (TCR_EL1) встановлює для чіпсетів ARM розмір пам’яті, який потрібно повернути. Виходить, що цей реєстр не захищений HCR і тому зловмисник може змінити його, оскільки автор змінив його на розмір сторінки 64 Кб.
Це означає, що коли RKP виконує запит, фактичний обсяг доступної пам’яті тепер становить 64 Кб замість 4 Кб. Причина полягає в тому, що чіпсет ARM все ще контролює розмір сторінки, а експлойтом було встановлено 64 Кб. Оскільки RKP захищає пам’ять від запису, як частину правил, перелічених у експлойті №2, пам’ять усе ще фактично захищена. Але тут є підступ: оскільки RKP жорстко закодовано на 4 Кб, він не змінюється на розмір сторінки 64 Кб після оновлення реєстру, тому захищено лише перші 4 Кб пам'яті дозволяючи зловмиснику зробити все, що він хоче, з рештою 60 Кб.
Експлойт №4
Останній експлойт, який показує автор, посилається на пам’ять, де знаходиться програмне забезпечення RKP, щоб зловмисник міг атакувати саме програмне забезпечення RKP. Один із способів зупинити цей тип атаки, який також використовують ядра Linux, полягає в тому, щоб скасувати зіставлення вашої програми з адресним простором віртуальної пам’яті, щоб жодні програми не могли атакувати її, оскільки вони не можуть посилатися на неї.
Пам’ятайте, що пам’ять — це вказівники та таблиці, які відображають фізичну пам’ять у віртуальну. Згідно зі звичайним захистом у цьому типі атаки, RKP декартує себе, щоб його неможливо було атакувати. Однак, якщо ядро не надає таких можливостей, RKP дозволяє відображати частину пам’яті та позначати її як читання/запис. Єдина перевірка полягає в тому, що це не саме базове ядро, оскільки RKP не перевіряє, чи адреси, які запитуються для відображення, є областю, де сам RKP знаходиться в пам’яті. В основному, РКП дозволяє переставити себе на карту повертається в адресний простір, до якого програми можуть отримати доступ і як сторона впливають на пам'ять автоматично позначається як читання/запис тому зловмисник тепер може використовувати пам’ять як завгодно.
Висновок
Однією з найбільших проблем із чотирма перерахованими вище експлойтами є те, що автор згадує, наскільки важко їх виконати через відсутність функцій у базовому ядрі Android. За іронією долі, безпечний гіпервізор RKP надав усі інструменти, необхідні для здійснення атак. Це свідчить про те, що іноді програмне забезпечення з добрими намірами створює більше проблем, ніж вирішує, і нам пощастило, що у нас є люди як Гал Беніаміні, готовий забруднити руки та перевірити, чи документація відповідає дійсності програмного забезпечення робить.
Хоча ці експлойти здаються страшними та роблять Нокс дуже вразливим, я хотів би запевнити всіх, що всі ці проблеми були виправлено в січневому оновленні від Samsung. Крім того, ці експлойти вимагають дуже глибокого розуміння процесорів ARM і програмування, тому бар’єр для входу у використання цих експлойтів є астрономічно високим.
Джерело: Project Zero