macOS xpc_connection_get_audit_token Attack

Support HackTricks

Для отримання додаткової інформації перегляньте оригінальну публікацію: https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/. Це резюме:

Основна інформація про Mach Messages

Якщо ви не знаєте, що таке Mach Messages, почніть з перегляду цієї сторінки:

macOS IPC - Inter Process Communication

На даний момент пам'ятайте, що (визначення звідси): Mach messages надсилаються через mach port, який є каналом зв'язку з одним приймачем і кількома відправниками, вбудованим у ядро mach. Кілька процесів можуть надсилати повідомлення на mach port, але в будь-який момент тільки один процес може читати з нього. Як і дескриптори файлів і сокети, mach ports виділяються та керуються ядром, а процеси бачать лише ціле число, яке вони можуть використовувати, щоб вказати ядру, який з їх mach ports вони хочуть використовувати.

XPC Connection

Якщо ви не знаєте, як встановлюється XPC-з'єднання, перегляньте:

macOS XPC

Резюме вразливостей

Цікаво знати, що абстракція XPC є з'єднанням один до одного, але вона базується на технології, яка може мати кілька відправників, тому:

  • Mach ports є одноразовим приймачем, кількома відправниками.

  • Аудитний токен з'єднання XPC є токеном аудиту скопійованим з найостаннішого отриманого повідомлення.

  • Отримання аудитного токена з'єднання XPC є критично важливим для багатьох перевірок безпеки.

Хоча попередня ситуація виглядає багатообіцяюче, є деякі сценарії, де це не викличе проблем (звідси):

  • Аудитні токени часто використовуються для перевірки авторизації, щоб вирішити, чи прийняти з'єднання. Оскільки це відбувається за допомогою повідомлення до сервісного порту, з'єднання ще не встановлено. Більше повідомлень на цьому порту просто обробляються як додаткові запити на з'єднання. Отже, будь-які перевірки перед прийняттям з'єднання не є вразливими (це також означає, що в межах -listener:shouldAcceptNewConnection: аудитний токен є безпечним). Тому ми шукаємо XPC-з'єднання, які перевіряють конкретні дії.

  • Обробники подій XPC обробляються синхронно. Це означає, що обробник подій для одного повідомлення повинен бути завершений перед викликом для наступного, навіть на паралельних чергах. Тому всередині обробника подій XPC аудитний токен не може бути перезаписаний іншими звичайними (не-відповідь!) повідомленнями.

Два різні методи, які можуть бути вразливими:

  1. Варіант 1:

  • Експлойт підключається до сервісу A та сервісу B

  • Сервіс B може викликати привілейовану функціональність у сервісі A, яку користувач не може

  • Сервіс A викликає xpc_connection_get_audit_token під час не всередині обробника подій для з'єднання в dispatch_async.

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

  • Експлойт передає сервісу B право ВІДПРАВКИ до сервісу A.

  • Отже, svc B фактично надсилає повідомлення до сервісу A.

  • Експлойт намагається викликати привілейовану дію. У RC svc A перевіряє авторизацію цієї дії, поки svc B перезаписує аудитний токен (надаючи експлойту доступ до виклику привілейованої дії).

  1. Варіант 2:

  • Сервіс B може викликати привілейовану функціональність у сервісі A, яку користувач не може

  • Експлойт підключається до сервісу A, який надсилає експлойту повідомлення, що очікує на відповідь у конкретному порту відповіді.

  • Експлойт надсилає сервісу B повідомлення, передаючи цей порт відповіді.

  • Коли сервіс B відповідає, він надсилає повідомлення до сервісу A, поки експлойт надсилає інше повідомлення до сервісу A, намагаючись досягти привілейованої функціональності і очікуючи, що відповідь від сервісу B перезапише аудитний токен у потрібний момент (умова гонки).

Варіант 1: виклик xpc_connection_get_audit_token поза обробником подій

Сценарій:

  • Два mach сервіси A та B, до яких ми можемо підключитися (на основі профілю пісочниці та перевірок авторизації перед прийняттям з'єднання).

  • A повинна мати перевірку авторизації для конкретної дії, яку B може пройти (але наш додаток не може).

  • Наприклад, якщо B має деякі права або працює як root, це може дозволити йому попросити A виконати привілейовану дію.

  • Для цієї перевірки авторизації A отримує аудитний токен асинхронно, наприклад, викликавши xpc_connection_get_audit_token з dispatch_async.

У цьому випадку зловмисник може викликати умову гонки, створюючи експлойт, який просить A виконати дію кілька разів, поки B надсилає повідомлення до A. Коли RC є успішною, аудитний токен B буде скопійовано в пам'яті поки запит нашого експлойту обробляється A, надаючи доступ до привілейованої дії, яку тільки B могла б запитати.

Це сталося з A як smd і B як diagnosticd. Функція SMJobBless з smb може бути використана для встановлення нового привілейованого допоміжного інструмента (як root). Якщо процес, що працює як root, контактує з smd, жодні інші перевірки не будуть виконані.

Отже, сервіс B є diagnosticd, оскільки він працює як root і може бути використаний для моніторингу процесу, тому, як тільки моніторинг розпочато, він надсилає кілька повідомлень на секунду.

Щоб виконати атаку:

  1. Ініціюйте з'єднання з сервісом, названим smd, використовуючи стандартний протокол XPC.

  2. Сформуйте вторинне з'єднання з diagnosticd. На відміну від звичайної процедури, замість створення та надсилання двох нових mach ports, право на відправку клієнтського порту замінюється дублікатом права на відправку, пов'язаного з з'єднанням smd.

  3. В результаті XPC повідомлення можуть бути надіслані до diagnosticd, але відповіді від diagnosticd перенаправляються до smd. Для smd здається, що повідомлення як від користувача, так і від diagnosticd походять з одного з'єднання.

Image depicting the exploit process
  1. Наступний крок полягає в тому, щоб дати вказівку diagnosticd розпочати моніторинг вибраного процесу (можливо, власного користувача). Одночасно надсилається потік звичайних 1004 повідомлень до smd. Намір полягає в установці інструмента з підвищеними привілеями.

  2. Ця дія викликає умову гонки в функції handle_bless. Таймінг критичний: виклик функції xpc_connection_get_pid повинен повернути PID процесу користувача (оскільки привілейований інструмент знаходиться в пакеті додатка користувача). Однак функція xpc_connection_get_audit_token, зокрема в підпрограмі connection_is_authorized, повинна посилатися на аудитний токен, що належить diagnosticd.

Варіант 2: пересилання відповіді

В середовищі XPC (міжпроцесна комунікація), хоча обробники подій не виконуються паралельно, обробка відповідей має унікальну поведінку. Зокрема, існує два різних методи для надсилання повідомлень, які очікують на відповідь:

  1. xpc_connection_send_message_with_reply: Тут XPC повідомлення отримується та обробляється на призначеній черзі.

  2. xpc_connection_send_message_with_reply_sync: Навпаки, у цьому методі XPC повідомлення отримується та обробляється на поточній черзі.

Ця відмінність є критично важливою, оскільки вона дозволяє можливість пакетів відповіді оброблятися паралельно з виконанням обробника подій XPC. Зокрема, хоча _xpc_connection_set_creds реалізує блокування для захисту від часткової перезаписи аудитного токена, це не поширюється на весь об'єкт з'єднання. В результаті це створює вразливість, де аудитний токен може бути замінений під час інтервалу між обробкою пакета та виконанням його обробника подій.

Щоб експлуатувати цю вразливість, потрібна наступна установка:

  • Два mach сервіси, які називаються A та B, обидва з яких можуть встановити з'єднання.

  • Сервіс A повинен включати перевірку авторизації для конкретної дії, яку може виконати лише B (додаток користувача не може).

  • Сервіс A повинен надіслати повідомлення, яке очікує на відповідь.

  • Користувач може надіслати повідомлення до B, на яке він відповість.

Процес експлуатації включає наступні кроки:

  1. Чекайте, поки сервіс A надішле повідомлення, яке очікує на відповідь.

  2. Замість того, щоб відповісти безпосередньо A, порт відповіді захоплюється і використовується для надсилання повідомлення до сервісу B.

  3. Потім надсилається повідомлення, що стосується забороненої дії, з очікуванням, що воно буде оброблено паралельно з відповіддю від B.

Нижче наведено візуальне зображення описаного сценарію атаки:

![https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/variant2.png](../../../../../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png)

Проблеми виявлення

  • Складнощі в знаходженні екземплярів: Пошук екземплярів використання xpc_connection_get_audit_token був складним, як статично, так і динамічно.

  • Методологія: Frida була використана для підключення до функції xpc_connection_get_audit_token, фільтруючи виклики, які не походять з обробників подій. Однак цей метод був обмежений до підключеного процесу і вимагав активного використання.

  • Інструменти аналізу: Інструменти, такі як IDA/Ghidra, використовувалися для вивчення досяжних mach сервісів, але процес був трудомістким, ускладненим викликами, що стосуються спільного кешу dyld.

  • Обмеження скриптів: Спроби створити скрипт для аналізу викликів до xpc_connection_get_audit_token з блоків dispatch_async були ускладнені складнощами в парсингу блоків і взаємодією з спільним кешем dyld.

Виправлення

  • Повідомлені проблеми: Було подано звіт до Apple, в якому детально описано загальні та специфічні проблеми, виявлені в smd.

  • Відповідь Apple: Apple вирішила проблему в smd, замінивши xpc_connection_get_audit_token на xpc_dictionary_get_audit_token.

  • Природа виправлення: Функція xpc_dictionary_get_audit_token вважається безпечною, оскільки вона отримує аудитний токен безпосередньо з mach повідомлення, пов'язаного з отриманим XPC повідомленням. Однак вона не є частиною публічного API, подібно до xpc_connection_get_audit_token.

  • Відсутність більш широкого виправлення: Залишається незрозумілим, чому Apple не реалізувала більш комплексне виправлення, наприклад, відкидання повідомлень, які не відповідають збереженому аудитному токену з'єднання. Можливість легітимних змін аудитного токена в певних сценаріях (наприклад, використання setuid) може бути фактором.

  • Поточний статус: Проблема залишається в iOS 17 та macOS 14, що становить виклик для тих, хто намагається виявити та зрозуміти її.

Support HackTricks

Last updated