Перевод: Случайный обход экрана блокировки Google Pixel за $70 тысяч

Перевод: Случайный обход экрана блокировки Google Pixel за $70 тысяч

@Ent_TranslateIB

Я обнаружил уязвимость, затрагивающую, похоже, все телефоны Google Pixel: если вы отдадите мне любое заблокированное устройство Pixel, я смогу вернуть его вам разблокированным. Ошибка была исправлена в обновлении безопасности от 5 ноября 2022 года.

Проблема позволяла злоумышленнику с физическим доступом обойти защиту экрана блокировки (отпечаток пальца, PIN-код и т.д.) и получить полный доступ к устройству пользователя. Уязвимость зарегистрирована под номером CVE-2022-20465 и может затронуть других производителей Android. Вы можете ознакомиться с моей рекомендацией по исправлению и необработанным отчетом об ошибке, который я отправил в Google, на сайте feed.bugs.xdavidhu.me.

ГЛАВА 1: ЗАБЫВ СВОЙ ПИН-КОД SIM-КАРТЫ

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

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

Pixel запустился и попросил ввести PIN-код SIM-карты. Обычно я знал его, но в этот раз я не смог его вспомнить. Я надеялся, что смогу его вспомнить, поэтому попробовал несколько комбинаций, но в итоге ввел 3 неправильных PIN-кода, и SIM-карта заблокировалась. Теперь, чтобы разблокировать и снова начать работать, ей требовался PUK-код.

Запрыгнув в шкаф и каким-то образом найдя оригинальную упаковку SIM-карты, я поцарапал заднюю часть и получил PUK-код. Я ввел PUK-код на Pixel, и он попросил меня установить новый PIN-код. Я сделал это, и после успешного завершения процесса я оказался на экране блокировки. Но что-то было не так:

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

После принятия пальца устройство застряло на странном сообщении "Pixel запускается..." и пробыло там до тех пор, пока я не перезагрузил его еще раз.

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

ГЛАВА 2: ЧТО СЛУЧИЛОСЬ?

Как я и обещал себе, на следующий день я снова начал наблюдать за этим поведением. После перезагрузки телефона, введения неправильного PIN-кода 3 раза, ввода PUK и выбора нового PIN-кода я дошел до того же состояния "Pixel запускается...".

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

Как и раньше, я ввел PUK-код и выбрал новый PIN-код. На этот раз телефон глюкнул, и я оказался на своем личном домашнем экране. Что? Он же был заблокирован раньше?

Это было тревожно странно. Я сделал это снова. Заблокировал телефон, снова вставил SIM-карту, сбросил PIN-код... И снова я на домашнем экране. ЧТО?

В этот момент у меня начали трястись руки. ЧТО ЗА Х**НЯ? ОН САМ СЕБЯ РАЗБЛОКИРОВАЛ?

Когда я немного успокоился, я понял, что это действительно чертовски полный обход экрана блокировки на полностью пропатченном Pixel 6. Я достал свой старый Pixel 5 и попытался воспроизвести ошибку и там. Это тоже сработало.

Вот процесс разблокировки в действии:

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

ГЛАВА 3: РЕАКЦИЯ GOOGLE

Я отправил отчет. Думаю, это был самый короткий мой отчет. Потребовалось всего 5 простых шагов.

Google (точнее, Android VRP) устранил и зафиксировал внутреннюю ошибку в течение 37 минут. Это было действительно впечатляюще. К сожалению, после этого качество и частота ответов начали ухудшаться.

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

Также стоит упомянуть, что перед тем, как сообщить о проблеме, я проверил таблицу вознаграждений Android VRP, в которой говорится, что если вы сообщите об обходе экрана блокировки, который затронет несколько или все устройства [Pixel], вы можете получить максимальную награду в 100 тысяч долларов. Поскольку я поставил галочки во всех необходимых пунктах, я решил, что у этой ошибки есть все шансы получить награду в $100 тыс.

После того, как она попала на рассмотрение, был практически месяц тишины. Я чувствовал, что она может быть закрыта как дубликат. Очевидно, кто-то уже сообщил об этом ещё до меня, хотя именно мое сообщение заставило их принять меры. Видимо, что-то пошло не так при обработке первоначального сообщения. Действительно, через 31 день после сообщения я проснулся от того, что автоматическое электронное письмо гласило: "Команда безопасности Android считает, что это дубликат проблемы, о которой ранее сообщил другой внешний исследователь". Это было что-то вроде фирменного момента "баг баунти", когда ошибка превратилась из $100 тыс. в $0. Я не мог ничего сделать, кроме как принять тот факт, что эта ошибка теперь является дубликатом и платить не будут.

После моего сообщения прошло почти два месяца, а вокруг была тишина. На 59-й день я написал в тикет, попросив обновить статус. В ответ я получил шаблонный ответ о том, что они все еще работают над исправлением.

Перенесемся в сентябрь, через три месяца после моего отчета. Я был в Лондоне, посещая мероприятие Google по поиску ошибок под названием ESCAL8. Только что вышел сентябрьский патч 2022 года, я обновил свой телефон и однажды ночью в своем номере в отеле попытался воспроизвести ошибку. Я надеялся, что они уже исправили ее. Нет. Я все еще мог разблокировать телефон.

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

На следующий день я объяснил свою ситуацию нескольким людям и даже провел живую демонстрацию некоторых Pixel в офисе Google. Это был незабываемый опыт. У нас не было инструмента для извлечения SIM-карты. Сначала мы пытались использовать иглу, и каким-то образом я умудрился порезать палец в нескольких местах, и моя рука начала кровоточить. Инженер Google наклеил мне на палец пластырь. Поскольку игла не сработала, мы начали расспрашивать людей, и одна очень добрая женщина дала нам свои серьги, чтобы попробовать. Сработало! Мы поменяли SIM-карты местами, и нам удалось, с некоторыми трудностями, разблокировать устройства. Теперь мне стало легче от того, что люди, похоже, неравнодушны к этой проблеме.

я на следующий день после того, как порезал палец

Я установил срок раскрытия информации на 15 октября, но команда Android VRP ответила, что ошибка не будет исправлена в октябре. Они нацелились на декабрь. Это показалось мне слишком далеким, учитывая последствия. Я решил придерживаться октябрьского срока.

После разговора с несколькими сотрудниками Google об этом октябрьском сроке, один из членов команды Android VRP лично прокомментировал заявку на исправление ошибки и попросил меня организовать встречу для обсуждения ошибки и обмена мнениями. Мы провели встречу с несколькими людьми, и они были очень любезны и выслушали всю мою историю о том, что я месяцами находился в неведении, получал только шаблонные ответы (даже на дубликат $100k -> $0) и в целом чувствовал, что я больше забочусь об этой ошибке, чем Google. Они сказали, что исправление теперь планируется выпустить в ноябре, а не в декабре. Тем не менее, мой крайний срок был назначен на октябрь.

Через две недели после нашего разговора я получил новое сообщение, которое подтвердило первоначальную информацию, которая у меня была. Они сказали, что, хотя мой отчет был дубликатом, только из-за моего отчета они начали работать над исправлением. В связи с этим они решили сделать исключение и вознаградить 70 000 долларов за обход экрана блокировки. Я также решил (еще до получения вознаграждения), что я слишком напуган, чтобы действительно выложить живую ошибку, а поскольку до исправления оставалось меньше месяца, то оно того не стоило. Я решил подождать исправления.

Вы можете прочитать полный текст разговора на feed.bugs.xdavidhu.me.

В общем, несмотря на то, что эта ошибка началась как не слишком приятный опыт для меня, хакера, после того, как я начал "кричать" достаточно громко, они заметили и действительно захотели исправить ошибку. Надеюсь, они справедливо отнеслись и к первоначальному докладчику (докладчикам). В конце концов, я думаю, что Google поступил довольно хорошо, хотя время исправления все еще кажется мне долгим.

Но об этом судить вам.

ГЛАВА 4: ЧТО ВЫЗВАЛО ОШИБКУ?

Поскольку Android является открытым исходным кодом, исправление этой проблемы со всеми изменениями кода находится в открытом доступе:

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

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

Похоже, что в Android существует понятие "экран безопасности". Экран безопасности может быть несколькими вещами. Экран ввода PIN-кода, экран сканирования отпечатков пальцев, экран ввода пароля или, в нашем случае, экран ввода SIM PIN-кода и SIM PUK.

Эти экраны безопасности можно накладывать друг на друга. Так, например, когда телефон был заблокирован и был виден ввод SIM PIN, экран безопасности SIM PIN располагался поверх "экрана безопасности отпечатков пальцев".

Когда SIM PUK был успешно сброшен, компонент сброса PUK на "стеке экранов безопасности" вызывал функцию .dismiss(), заставляя устройство отменить текущий экран и показать экран безопасности, который находился "под" ним в стеке. В нашем примере это был экран защиты отпечатков пальцев.

Поскольку функция .dismiss() просто отключала текущий экран безопасности, она была уязвима к состоянию гонки (Race condition). Представьте, что бы произошло, если бы что-то в фоновом режиме изменило текущий экран безопасности до того, как компонент сброса PUK добрался до вызова .dismiss()? Отклонил бы компонент PUK не связанный с ним экран безопасности, когда он наконец-то вызвал .dismiss()?

Похоже, что именно это и произошло. Какая-то другая часть системы отслеживала состояние SIM в фоновом режиме, и когда она обнаруживала изменения, то обновляла, какой экран безопасности был активен в данный момент. Похоже, что этот фоновый компонент установил обычный, например, экран отпечатков пальцев в качестве активного экрана безопасности еще до того, как компонент PUK смог добраться до своего собственного вызова функции .dismiss(). К тому времени, когда компонент PUK вызвал функцию .dismiss(), он фактически отключил экран безопасности отпечатков пальцев, вместо того чтобы просто отключить экран безопасности PUK, как было задумано изначально. А вызов функции .dismiss() на экране защиты отпечатков пальцев приводил к разблокировке телефона.

Похоже, инженеры Android решили изменить функцию .dismiss() и сделали ее требующей дополнительного параметра, в котором вызывающая сторона может указать тип защитного экрана, который она хочет отключить. В нашем случае компонент PUK теперь явно вызывает .dismiss(SecurityMode.SimPuk), чтобы отменить только экраны безопасности с типом SimPuk. Если текущий активный экран безопасности не является экраном SimPuk (потому что, возможно, какой-то фоновый компонент изменил его, как в нашем случае), функция dismiss ничего не делает.

Это кажется мне довольно элегантным и надежным решением для защиты от этого, а также будущих состояний гонки (Race condition). Я не ожидал, что эта ошибка вызовет такие большие изменения кода в Android.

Оригинал статьи - здесь.


Перевод статьи был выполнен проектом перевод энтузиаста:

  • 📚 @Ent_TranslateIB - Телеграмм канал с тематикой информационной безопасности
  • 🔥 @Ent_Translate - Инстаграм проекта

Report Page