SandboxEscaper/PoC-LPE: що всередині?
Here is the alpc bug as 0day: https://t.co/m1T3wDSvPX I don’t fucking care about life anymore. Neither do I ever again want to submit to MSFT anyway. Fuck all of this shit.
— SandboxEscaper (@SandboxEscaper) August 27, 2018
На хабре вже є новина про цю уразливість, але, на жаль, без технічних деталей. Пропоную заглянути всередину опублікованого архіву (автор — SandboxEscaper).
Під катом розташований переклад документа-опису, який знаходиться в архіві.
Опис уразливості
Служба Task Scheduler (планувальник завдань) має RPC інтерфейс (доступний через транспорт ALPC), підтримує метод SchRpcSetSecurity.
Так виглядає прототип цього методу:
long _SchRpcSetSecurity(
[in][string] wchar_t* arg_1, //Task name
[in][string] wchar_t* arg_2, //Security Descriptor string
[in]long arg_3);
Завдання, створені планувальником завдань, створюють відповідну директорію/файл c:windowssystem32tasks. Ймовірно, цей метод призначений для запису DACL’а завдань, розташованих там. Але запис буде відбуватися відбувається після имперсонации. Однак, з деяких причин, реалізація методу так само перевіряє наявність .job-файлу в c:windowstasks і записує йому dacl назад без имперсонации. Оскільки користувач (навіть користувач в групі осіб) може створювати в цій директорії, файли, що ми просто можемо створити hardlink на будь-який інший файл, доступний нам на читання. Використовуючи такий hardlink, ми можемо примусити службу планувальника (исполняющейся з правами SYSTEM) записати довільний dacl назад (дивись другий параметр SchRpcSetSecurity) у файл по нашому вибору.
Таким чином: у будь-якого файлу, доступного на читання, можна змінити dacl назад, що дозволяє повністю його замінити.
Експлуатація уразливості
Ця вразливість дає нам дійсно сильний примітив! Основна проблема полягає в тому, що після установки (за замовчуванням) багато важливі файли можуть бути модифіковані тільки користувачем TrustedInstaller (але не користувачем SYSTEM).
В архіві присутній powershell-скрипт для перерахування файлів, які ви можете контролювати. Просто запустіть:
./enumerate.ps1 >output.txt
У системі є багато цілей. Ви можете контролювати файли Program Files і, якщо ваш цільовий файл використовується адміністратором/іншим користувачем, перезаписані вами файли можу бути запущені з необхідними привілеями.
Друга проблема полягає в тому, що хоча ми можемо отримати контроль над безліччю файлів, запис у них часто неможлива, оскільки ці DLL вже кудись завантажені на виконання. Спроба запису dacl назад для завантаженого на виконання файлу викличе помилку розділяється доступу. Але вразливість можна використовувати і для інших типів файлів, які можуть бути кращою метою, ніж DLL.
Для експлуатації обраний файл C:WindowsSystem32DriverStoreFileRepositoryprnms003.inf_amd64_4592475aca2acf83Amd64printconfig.dll (ім’я директорії може відрізнятися, це враховано в PoC). Схоже цей файл відноситься до принтера XPS і не завантажений в службу друку за замовчуванням (може так вийти, що файл буде завантажений… але найчастіше це не так).
А коли ми запустимо завдання на друк з використанням XPS-принтера, сервіс завантажить цю DLL, яку ми можемо попередньо переписати. Такий вектор атаки (hijacking) може бути легко використаний для чогось кращого. Я можу спробувати знайти кращі варіанти… просто дайте мені знати.
Зауваження: На старому ноутбуці, де Windows 10 працює вже кілька років, є дві директорії prnms003.inf_amd64_*. Нова версія не видаляє стару, а отже, немає гарантії, що FindFirstFile (використовуваний в PoC) знайде актуальну директорію. Тому ви можете розширити код, перезаписавши всі знайдені printconfig.dll або перевірити атрибут останнього запису в файл і вибрати новий.
Демо
В архіві так само можна знайти відео з демонстрацією:
Прихований текст