Задача тестировщика — проверить софт на стойкость в самых разных и непредсказуемых ситуациях. Одно из направлений тестирования — проверка приложения на безопасность и уязвимость к странным действиям пользователя. Проще говоря, что бы пользователь ни делал, он не должен получить доступ куда не следует.
Но предсказать и проверить последовательность всех действий пользователя часто невозможно: слишком много вариантов и их комбинаций. Одну из них обнаружил Дэвид Шульц, специалист по ИТ-безопасности. По иронии судьбы этот баг он обнаружил случайно и в первый момент даже не понял, что произошло :-)
Мы сделали короткую версию его статьи в блоге, чтобы было проще понять, в чём суть истории. Если знаете английский, почитайте полную версию, там больше подробностей.
Забытый ПИН-код
Чтобы обезопасить свой телефон и сим-карту, Дэвид включил проверку пин-кода: его нужно вводить после каждой перезагрузки, чтобы разблокировать симку. После этого телефон у него спрашивает отпечаток пальца, а если он не совпадает несколько раз — цифровой код разблокировки. У него Google Pixel 6 с чистым Андроидом.
Теперь ситуация: телефон выключается, Дэвид ставит его на зарядку и включает, вокруг суета и много дел. Телефон, как обычно, спрашивает пин-код, Дэвид в спешке три раза подряд вводит неправильный пин, и телефон начинает запрашивать PUK-код (он нужен для разблокировки сим-карты, если забыл пин). Парень находит большой пластик от симки, видит на нём PUK-код, вводит его, потом вводит новый пин и перезагружает телефон.
После перезагрузки телефон сразу спрашивает отпечаток, а потом выводит странную надпись «Pixel is starting…» и зависает. Если перезагрузить ещё раз — работает как обычно.
👉 В этот момент Дэвид первый раз обошёл систему безопасности Android и даже не заметил этого. Но он заметил, что происходит что-то странное, и день спустя решил изучить всё подробнее.
Эксперименты и взлом
Дэвид много раз повторил то, что делал вчера, и результат всегда был одним и тем же: после первой перезагрузки телефон зависал, а после второй — работал как обычно. Но, увлёкшись, Дэвид вытащил и вставил симку, на автомате повторил всё, что делал до этого, и телефон оказался разблокированным: не спросил ни цифровой код, ни пин-код, а сразу показал рабочий стол. В итоге нашёлся рабочий алгоритм взлома Google Pixel 6:
- Берём заблокированный, но включённый телефон.
- Вытаскиваем сим-карту и вставляем свою, на которой установлен пин-код.
- Вводим пин неправильно три раза подряд.
- Вводим PUK-код от этой сим-карты и устанавливаем новый пин.
- Телефон разблокируется и сразу показывает рабочий стол.
Видео:
Получается, что для взлома любого такого телефона нужен только физический доступ к нему и своя симка с известным PUK-кодом.
Дэвид обратился в Google и рассказал о найденной уязвимости. Несколько месяцев напряжённой переписки спустя компания выпустила обновление безопасности, по которому можно понять, почему всё работало именно так.
Как это работает
Андроид — открытая ОС, и все патчи и обновления выкладываются на Гитхабе. Там же появился и коммит с исправлением этой ошибки:
Судя по всему, проблема была не в одном экране смены PUK-кода, потому что изменения внесли сразу в 12 файлов:
После изучения подробностей Дэвид понял, как именно работает его уязвимость, и объяснил в своём блоге, а мы расскажем короткую версию.
В Андроиде «экран безопасности» — это виртуальный экран, который отображается поверх всего и защищает телефон. Этих экранов может быть несколько: один спрашивает цифровой код, второй — пин, третий спрашивает отпечаток и так далее. В зависимости от ситуации на телефоне может работать сразу несколько экранов безопасности.
В обычном случае при замене сим-карты всё выглядит так: есть рабочий стол, над ним — экран безопасности с отпечатком, а над ним — экран безопасности пин-кода.
Когда мы вводим верный пароль или прикладываем палец, экран безопасности вызывает функцию dismiss(), которая закрывает верхний экран из списка экранов безопасности. Это самый важный момент: система ведёт учёт экранов — кто из них поверх кого отображается, — чтобы закрывался всегда самый верхний.
Но при вводе PUK-кода система в какой-то момент начинает думать, что самый верхний экран безопасности — экран с запросом отпечатка (который на самом деле второй по счёту). В тот момент, когда мы вводим PUK и переустанавливаем пин-код, этот экран закрывается и вызывает функцию dismiss(). Но вместо того чтобы штатно отработать смену пин-кода, система закрывает экран безопасности с отпечатком. В итоге телефон оказывается разблокированным:
Этот трюк точно работает на телефонах Google Pixel и, возможно, на некоторых других моделях. Каких — мы не знаем, но на всякий случай проверили свои телефоны в редакции. Сейчас Google уже закрыла эту уязвимость, но мало ли что.
Что в итоге
Дэвид получил за своё открытие 70 тысяч долларов, а весь мир — новое обновление безопасности. Сколько ещё уязвимостей осталось в системе — неизвестно, но, скорее всего, ещё немало. Поэтому и обновляться в любом случае нужно.