В ноябрьском патче безопасности Android исправлена уязвимость, позволявшая разблокировать телефон с помощью SIM-карты.

В ноябрьском патче безопасности Android исправлена уязвимость, позволявшая разблокировать телефон с помощью SIM-карты.

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

Данная уязвимость позволяет любому злоумышленнику с физическим доступом к устройству обойти защиту экрана блокировки (отпечаток пальца, PIN-код и т.д.) и получить полный доступ к данным пользователя на смартфоне с помощью одной лишь SIM-карты и PUK-кода. Уязвимость отслеживается под номером CVE-2022-20465, и исправления уже доступны в исходниках AOSP для Android 10-13. Эта ошибка была исправлена в Патче безопасности от 1 ноября 2022 года

Суть уязвимости.

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

Разработчик David Schütz смог обнаружить уязвимость, которая позволила ему обойти экран блокировки на своих Pixel 5 и 6, используя вышеописанный принцип. При этом он действовал по следующему сценарию: 

  1. Заблокировать устройство
  2. Добиться отключения аутентификации по биометрии (чтобы устройство запрашивало только ключ экрана блокировки)
  3. Достать SIM-лоток и вставить его вместе c SIM-картой. (Появляется экран ввода PIN-кода SIM-карты)
  4. Выполнить процесс сброса PIN-кода SIM-карты с помощью PUK-кода. Ввести новый PIN-код.
  5. Ваше устройство разблокировано без ввода ключа экрана блокировки!

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

За обнаруженную уязвимость компания Google выплатила David Schütz 70 тысяч долларов. Хотя сделали это не сразу, и вообще он мог не получить это вознаграждение, но опустим эту историю.

Что вызывает ошибку?

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

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

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

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

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

Как исправили проблему?

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