Pull to refresh

Обход двухфакторной аутентификации Google

Reading time 8 min
Views 146K
Original author: Adam Goodman
Злоумышленник может обойти двухфакторную аутентификацию (2ФА) на сервисах Google, сбросить пользовательский пароль и получить полный контроль над аккаунтом, просто заполучив т.н. пароль приложения — ПП (ASP — Application-Specific Passwords).


(При всём уважении к рекламной компании Google «Good to Know»)


Злоупотребление паролями приложений Google


2ФА Google предоставляет материал для исследования различных проблем, непременно возникающих в настолько масштабных системах надежной аутентификации.
Чтобы сделать подобную аутентификацию возможной для всех пользователей (и безболезненно интегрировать её в уже существующую экосистему), инженерам Google пришлось пойти на некоторые компромиссы. Такие, например, как пароли приложений.
Несколько месяцев назад мы нашли способ использовать ПП для получения полного контроля над google аккаунтом, полностью обойдя 2ФА. Мы рассказали о нашей находке службе безопасности Google и недавно получили от них ответ, что они предприняли некоторые шаги для нейтрализации наиболее серьезных угроз из тех, что мы обнаружили. И так, вот что мы нашли:

Пароли приложений


Как только вы включите 2ФА, Google попросит вас создать отдельный пароль для каждого приложения, что вы используете (отсюда и название «пароль приложения»), который не поддерживает 2ФА. Этот пароль Вы используете вместо своего основного. Выражаясь конкретнее, вы создаёте ПП для большинства приложений, которые не используют логин из web-формы: e-mail клиенты, использующие IMAP и SMTP (Apple Mail, Thunderbird, и т.п.); XMPP чат-клиенты (Adium, Pidgin и т.п.), а так же различные календари, синхронизирующиеся с помощью CalDAV (iCal, etc.).
Даже некоторые софт от Google вынуждает вас использовать ПП — например, чтобы включить синхронизацию в Chrome или настроить свой аккаунт на Android устройстве. Совсем недавно эти клиенты в большинстве своём перешли на авторизацию через OAuth. В такой модели, когда вы впервые логинитесь на своём новом устройстве или в приложении, вы получаете запрос на авторизацию в web-форме, которая использует 2ФА. После успешной авторизации, сервер возвращает токен с ограниченным доступом, который в дальнейшем используется для аутентификации вашего устройства/приложения.
На самом деле, OAuth токены и ПП очень сильно похожи — в конечном итоге всё заканчивается созданием уникального авторизационного токена для каждого устройства/приложения, которое вы привязываете к вашему google аккаунту. Кроме того, каждый отдельный токен может быть отозван, без ущерба для остальных: если вы потеряли ваш смартфон, вы можете быть уверены, что никто не сможет получить доступ к вашему почтовому ящику, не имея пароля.
И так, основные отличия между OAuth токенами и ПП следующие:

  • OAuth токены создаются автоматически, в то время как ПП нужно создавать вручную. Вам нужно пойти в настройки google аккаунта чтобы его создать, а затем скопировать в приложение.
  • OAuth токены предоставляют более гибкую модель авторизации и могут быть использованы для ограничения доступа только к определенным данным или сервисам в вашем аккаунте. С другой стороны, пароли приложений, если уж быть совсем точным, не совсем ТОЛЬКО для приложений!

Остановимся на втором пункте подробнее. Если вы создаете ПП для XMPP чат-клиента, этот же самый пароль может быть использован для чтения почты через IMAP или получения списка событий из CalDAV календаря. Что, собственно, не является таким уж сюрпризом. На самом деле, Eric Gorss и Mayank Upadhyay из Google уже указывали на эту слабость в их статье о 2ФА Google:

«Другая слабость ПП в обманчивом впечатлении, что они предоставляют доступ к конкретному приложению, а не полномасштабный доступ к аккаунту»

Authentication at Scale из «IEEE S&P Magazine» vol. 11, no. 1

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

Авто-логин в Chrome


В последних версиях Android и ChromeOs Google включил в свои браузеры механизм авто-логина в google аккаунты. После того, как вы свяжите ваше устройство с аккаунтом, браузер будет использовать уже существующую авторизацию и перестанет запрашивать её через web-форму. (Есть даже экспериментальная поддержка этой функциональности в десктопной версии Chrome, вы может включить её, открыв «chrome://flags/.»).

До недавнего времени, этот механизм работал даже для самой важной части google аккаунта — странице настроек. Она включает в себя страницу восстановления пароля, на которой возможно добавление и редактирование e-mail адреса и телефонных номеров, на которые вам будет отослана информация, необходимая для сброса пароля. Короче говоря, если вы сможете получить доступ к этой странице — вы сможете отобрать аккаунт у его законного владельца.

Технические детали


В своём отличном блоге Android Explorations Николай Еленков опубликовал обширное исследование механизма авто-логина в Android. Оно стало отличной отправной точкой, но всё не содержала всю необходимую нам информацию. Мы захотели узнать, как можно использовать этот механизм, не имея Android устройства или Хромбука.
Чтобы сделать это, мы установили перехватывающий прокси, чтобы следить за траффиком между эмулятором Android и серверами Google. Во время добавления google аккаунта, мы увидели следующий запрос:

POST /auth HTTP/1.1
Host: android.clients.google.com

accountType=HOSTED_OR_GOOGLE&Email=user%40domain.com&has_permission=1&add_account=1&EncryptedPasswd=AFcb4...\
&service=ac2dm&source=android&androidId=3281f33679ccc6c6&device_country=us&operatorCountry=us&lang=en&sdk_version=17



Ответ, помимо всего прочего, содержал следующее:

Token=1/f1Hu...

Несмотря на то, что урл и некоторые параметры не документированы, это очень напоминает Google ClientLogin API. Чтобы воссоздать такой запрос самим, нам нужно было понять, что за значения нужно передавать в параметрах «EncryptedPasswd» и «androidId». Со вторым всё оказалось просто — это тот самый параметр «ANDROID_ID», упоминаемый в Android API Docs — случайно сгенерированный 64-битное значение, которое предназначено для однозначной идентификации устройства Android.
Другой пост Еленкова вселил нас надежду, что «EncryptedPasswd» может быть нашем ПП, зашифрованным публичным 1024-битным RSA ключём, который включён в Android платформу. «EncryptedPasswd» являлся бинарными данными(закодированными base64) длинной 130 байт, так что вполне возможно, что так оно и есть. Однако, прежде чем двигаться дальше, мы решили попробовать заменить этот параметр параметром «Passwd» (не зашифрованный пароль) из документации и установить ему значение — наш ПП:

POST /auth HTTP/1.1
Host: android.clients.google.com

accountType=HOSTED_OR_GOOGLE&Email=user%40domain.com&has_permission=1&add_account=1&Passwd=xxxxxxxxxxxxxxxx\
&service=ac2dm&source=android&androidId=3281f33679ccc6c6&device_country=us&operatorCountry=us&lang=en&sdk_version=17



И это сработало! Мы получили ответ, в котором содержалось что-то очень похожее на валидный токен. Этот токен, созданный сервером android.clients.google.com, стал видим в разделе «Connected Sites, Apps, and Services» нашего аккаунта и, похоже, предоставляет нам полный доступ к аккаунту:


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

POST /auth HTTP/1.1
Host: android.clients.google.com

accountType=HOSTED_OR_GOOGLE&Email=user%40domain.com&has_permission=1&Token=1%2Ff1Hu...&\
service=weblogin%3Acontinue%3Dhttps%253A%252F%252Faccounts.google.com%252FManageAccount\
&source=android&androidId=3281f33679ccc6c6&app=com.android.browser&client_sig=61ed377e85d386a8dfee6b864bd85b0bfaa5af81&\
device_country=us&operatorCountry=us&lang=en&sdk_version=17



Этот запрос возвращал тело ответа, а так же следующую строчку:

Auth=https://accounts.google.com/MergeSession?args=continue%3Dhttps%253A%252F%252Faccounts.google.com%252FManageAccount&uberauth=AP...&source=AndroidWebLogin
Expiry=0



Из этого запроса мы установили, что форматом для параметра «service» является weblogin:continue=url_encode(destination_url). Мы решили попытаться указать этот параметр для нашего изначального запроса с ПП вместо токена (вместо того, чтобы пытаться понять происхождение непонятного параметра «client_sig»):

POST /auth HTTP/1.1
Host: android.clients.google.com

device_country=us&accountType=HOSTED_OR_GOOGLE&androidId=3281f33679ccc6c6Email=user%40domain.com&lang=en&\
service=weblogin%3Acontinue%3Dhttps%253A%2F%2Faccounts.google.com%2FManageAccount&\
source=android&Passwd=xxxxxxxxxxxxxxxx&operatorCountry=us&sdk_version=17&has_permission=1



И получили ответ, полностью повторяющий предыдущий:

Auth=https://accounts.google.com/MergeSession?args=continue%3Dhttps%253A%252F%252Faccounts.google.com%252FManageAccount&uberauth=AP...&source=AndroidWebLogin
Expiry0



Ключевым параметром здесь является «MergeSession». Если вы откроете этот урл в неавторизованном браузере после того, как выполните запрос (это нужно сделать очень быстро), вы будете немедленно залогинены в аккаунт!

Таким образом, имея только имя пользователя, ПП и выполнив запрос к android.clients.google.com/auth, возможно залогиниться на страницу настроек аккаунта, в обход двухступенчатой верификации!

Фикс Google


Как было замечено ранее, этот способ работает даже для самой критичного раздела google аккаунта — настроек. Атакующий может предпринять рад действий, используя ПП жертвы:

  • Он может передать «accounts.google.com/b/0/UpdateAccountRecoveryOptions?hl=en&service=oz» в качестве урла в API запросе. MergeSession URL, полученный в ответе, приведёт его прямо на страницу восстановления пароля, где он сможет сбросить основной пароль.
  • Аналогично, атакающий может передать в запрос урл «accounts.google.com/b/0/SmsAuthConfig?hl=en», что приведет его на страницу с настройками 2ФА, где он сможет добавлять и удалять ПП или же отключить 2ФА совсем.

Это больше невозможно, начиная с 21 февраля, когда инженеры Google закрыли эту дыру. Насколько мы можем судить, Google теперь поддерживает некое дополнительное состояние, которое позволяет определить, как именно вы аутентифицировались — с помощью MergeSession URL и с помощью обычного логина и пароля, используя 2ФА. Страница настроек станет доступна только в последнем случае. Если же вы залогинились с помощь MergeSession URL, вас перенаправлят на страницу 2ФА, которую нельзя пропустить.

Насколько всё было плохо?


Мы считаем, что это большая дыра в системе аутентификации, если пользователь имеет некую форму для ввода пароля, которая позволит получить доступ к полному контролю над аккаунтом. Но несмотря на это, мы всё же согласны, что даже до того, как Google выкатил свой фикс, включить 2ФА на своём аккаунте гораздо лучше, чем не делать этого.

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

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

Оба этих примера представляют собой типы атак, которые могут быть предотвращены с помощью следования простым правилам и «цифровой гигиены». Например, не использовать один и тот же пароль на различных сайтах и не нажимать на подозрительные ссылки в e-mail сообщениях. К сожалению, такого рода «образовательные программы для пользователей» редко работают хорошо на практике(и могут быть нецелесообразны с экономической точки зрения).

Несмотря на это, даже с ПП, 2ФА Google может сгладить оба этих типа атак, даже если пользователи продолжают делать глупые вещи. ПП генерируются Google и не предполагают запоминание пользователем, т.о. маловероятно, что он использует точно такой же пароль на другом сайте. Если даже злоумышленник создаст фишинговый сайт и выманит ПП, его шансы на успех будут значительно (возможно, на порядки) ниже, чем с обычным паролем.

Тем не менее, повсеместное использование ПП всё же несёт в себе потенциальную опасность. Если злоумышленник сможет заставить установить вредоносное ПО, оно сможет найти и извлечь ПП где-нибудь в пользовательской системе (например, популярный чат-клиент Pidgin хранит пароли в открытом виде в XML файле). Кроме того, «толстоклиентские» приложения, основной пользователь ПП, частенько подвержены довольно известной проблеме слабой проверки SSL сертификата, что потенциально позволяет украсть ПП с помощью MiM-атаки.

Фикс Google значительно помогает в данной ситуации. Несмотря на то, что ПП всё ещё могут нанести значительный вред пользователю, он сможет сохранить контроль над своим аккаунтом и возможность отозвать ПП, если вдруг что-то пойдет не так. Тем не менее, мы твердо верим в принцип минимальных привилегий и хотели бы видеть дальнейшие шаги Google, направленные на ограничение привилегий отдельных ПП.


Апдейт #1
Google обновил своё предупреждение при создании ПП, в котором предупреждается о потенциальном риске:


Апдейт #2
Craig Young из nCircle выступил с докладом об аналогичной проблеме на конференции BSides, проводимой совместно с RSA!

Хронология событий:
2012/07/16: Исследователи из Duo подтвердили наличие ПП уязвимости.
2012/07/18: Описание проблемы направлено в security@google.com.
2012/07/20: Дискуссия со службой безопасности Google с целью уточнения деталей.
2012/07/24: Проблема подтверждена и классифицирована Google как «ожидаемое поведение».
2013/02/21: Google выпустила фикс, который запрещает доступ к критичной информации для ПП сессий.
2013/02/25: Duo публикуют статью с описанием проблемы.
Tags:
Hubs:
+104
Comments 20
Comments Comments 20

Articles