Пользователь
0,0
рейтинг
4 февраля 2015 в 23:16

Разработка → Как взломать двухфакторную аутентификацию Яндекса

Наконец-то Яндекс запилил двухфакторную аутентификацию. Я не ждал подвоха, но, похоже, зря.

Как работает двухфакторная аутентификация Яндекса?

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

QR-код расшифровывается в ссылку вот такого вида:

yandex.ru/promo/2fa?track_id=38e701d0bb5abaf50d381c3f95e0f341a8

Внутри всего этого веб-страничка с QR-кодом постоянно опрашивает сервер в ожидании авторизации:
POST /auth/magic/status/ HTTP/1.1
Host: passport.yandex.ru

track_id=38e701d0bb5abaf50d381c3f95e0f341a8

Как только пользователь отсканирует приложением Яндекса QR-код, следующий такой запрос отдаст браузеру куку.

В чем здесь проблема?

Для получения куки используется тот же ID, что закодирован в QR-коде.
Обратите внимание на параметр track_id в ссылке и такой же параметр в POST-запросе.
Это значит, что злоумышленник может подсмотреть из-за плеча пользователя его QR-код, достать из него ID сессии, и, притворившись браузером, выполнять часто-часто такой же запрос.

И если хакер раньше жертвы успеет получить сессию — он сразу окажется в аккаунте пользователя.

Я написал на коленке простенькое приложение под Android, которое демонстрирует эту уязвимость.
Достаточно встать за спиной жертвы и успеть отсканировать qr-код раньше нее, пока жертва запускает приложение и вводит пин-код.

После того, как она авторизуется, приложение покажет вам почтовый ящик жертвы.

Приложение декодирует QR-код с помощью библиотеки github.com/dm77/barcodescanner, быстро-быстро делает POST запросы к Яндексу, получает куки, подставляет их в WebView и открывает в нем Яндекс.Почту.

Для успешной атаки требуется относительно быстрый интернет на смартфоне (чтобы успеть получить cookie раньше жертвы) и желательна хорошая камера на устройстве. У меня код успешно распознавался с расстояния до метра, при этом мои подопытные друзья ничего не замечали и очень удивлялись этому фокусу, когда я им показывал их почту на своем телефоне.
Зумный Яков @zuyac
карма
16,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

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

  • +58
    С таким же успехом можно подсматривать как человек набирает пароль на клавиатуре ;D
    • +81
      И как раз двухфакторная аутентификация могла бы от этого защищать :)
      • +5
        Подсмотреть можно и код из Google Authenticator, например. Но перехватить QR код со страницы, используя какой-нибудь троян можно, вкупе с кейлоггером есть возможность произвести атаку.
        • +2
          С трояном и кейлоггером можно сразу сессионную куку перехватывать. Чего лишнюю возню разводить?
          • +3
            С паяльником или утюгом можно перехватить текст письмо до его набора на компьютере.
    • +4
      Ну и к тому же это гораздо проще — подсматривать можно издалека и за спиной, как если бы пароль не закрывался звездочками при вводе.
    • +4
      Так в этом и суть что никакой кейлоггер уже не поможет — нужно еще и мобильник хакать. А тут достаточно удаленного доступа к машине
    • +60
      Просто дождаться авторизации и посмотреть вместе с ним его почту.
    • +2
      Не у человека, который набирает привычный пароль вслепую за полторы секунды.
      • 0
        У секретарши в универе пароль был цифр из 30. Мы всё время смотрели как она набирает и пытались запомнить, но обычно сбивались не доходя до конца.
  • +18
    Да, знаем. Спасибо. Исправим.

    Если б вы написали в bugbounty, мы бы были рады выплатить приз.
    • +37
      Но очевижно же, что там скажут, что это известная проблема.
      • +2
        Я более-менее уверен, что если бы автор написал туда, ему бы так не ответили.
        • +77
          "… ему бы так и не ответили."
          • +4
            Насколько я знаю, у нас нет проблемы с неответами. Если у вас есть конкретные примеры тикетов, покажите, пожалуйста.
            • +2
              Не беспокойтесь, тут так принято :)
            • 0
              Смотря, что вы имеете ввиду под «у нас». Бьюсь 4 месяца с проблемой Яндекс почты для домена.
              Тикет #14111319452084437
              Ответ пришел спустя два месяца. Не знаю, правда, считается ли два месяца вакуума «неответом». Стоит ли говорить, что ответ ситуацию не поменял.
              • 0
                Добрый день! Насколько я вижу, в указанном тикете велась активная переписка, то есть уже нельзя его отнести к неотвеченным. Но в какой-то момент и правда случилось взаимное непонимание ситуации. Пришлите мне личным сообщением, пожалуйста, свежий лог отправки писем, где будут видны временные отказы 451. Проверьте также, пожалуйста, что Ваш отправляющий сервер корректно передаёт параметр To при общении с нашим сервером. Из-за ошибки адрес может считаться несуществующим, например, и тогда сервер будет производить попытку отправить его на адрес по умолчанию для несуществующих адресов. А на такие адреса действительно постоянно очень большой поток входящих писем, потому что валится много спама.
            • +1
              к слову, на тикет #11120920003398267 нет ответа больше трёх лет, а на тикет #201001159022687 — больше пяти лет :)
              • 0
                На оба тикета были даны ответы. На один — в течение суток, на другой — в течение двух. По обоим проблемам были созданы задачи на исправление. Если Вы проверите описываемые Вами ситуации, то можно убедиться, что изменения в Яндекс.Картах уже были произведены, маршруты строятся так, как Вы хотели. Признаю, наша вина в том, что не оповестили о починке — ребята из Карт работают над этим. Но Вы же, наверное, уже заметили её, если пользуетесь этими маршрутами?
                • 0
                  То, что я получил, ответом назвать нельзя. Автоматическое сообщение вида: «Спасибо за информацию, мы её обязательно проверим...» ответом не считается. Этими маршрутами я действительно какое-то время назад пользовался регулярно, но я перестал их строить с помощью яндекс.карт, так как они делали это неправильно. Примерно через 3-4 месяца после этих сообщений я проверил каждый и да, ошибки были исправлены, но мне об этом не было сообщено. Более того, я не нашёл (может быть, у меня просто не хватило прав на просмотр?) ответов на эти тикеты в вашем трекере. Предлагаю перенести дальнейшее обсуждение этого оффтопика, если оно будет, в другое место, на ваш выбор.
          • +3
            "… ему бы так и не ответили."

            Справедливости ради замечу, что мне ответили довольно оперативно.
      • +5
        Добрый день, я являюсь руководителем конкурса «Охота за ошибками».
        В наших интересах, чтобы им пользовалось как можно больше исследователей безопасности. По нашей статистике количество случаев, когда в короткий промежуток времени о серьезной уязвимости сообщало больше одного пользователя, крайне мало.
        Если у вас есть конкретные примеры, то изложите их, пожалуйста, здесь либо письмом.
        • +1
          Вот я бы хотел что-нибудь отправить, но в процессе нашел баг в вашей собиралке багов.
          При заходе на yandex.ru/bugbounty меня редиректит куда-то в космос:
          image
          • 0
            Добрый день! Напишите нам, пожалуйста, подробности через форму обратной связи конкурса feedback2.yandex.ru/bugbounty
          • 0
            У меня, кстати, часто такое на различных сервисах Яндекса, где я авторизован. Писал в поддержку, но мы так и не смогли докопаться до истины.
    • +15
      Исправили.
    • +16
      «Мы да, знаем… Но мы выплатили бы...»
      Занятно.
    • +8
      Знаем? Исправим?

      Эти два слова совершенно не вяжутся в одном предложении про безопасность.
      Если вы сами знали о проблеме, и осознанно решили отложить исправление, то это кромешный ад.

      АД
      • +33
        Если вы сами знали о проблеме, и осознанно решили отложить исправление, то это кромешный ад.
        Нет, разумеется, мы не знали о проблеме, когда выкатывали. Я узнал о ней примерно за 2 минуты до того, как написал комментарий.

        Вы хотите придраться к формулировке комментария, написанного в 12 ночи параллельно с побудкой разработчика и договаривании о выкатке хотфикса с админом? Честное слово, я — не пресс-служба, не могу каждое слово выверять.
        • +3
          Ну что значит «за две минуты»? Вам про это писали еще 3 числа, и вы даже отвечали: habrahabr.ru/company/yandex/blog/249547/#comment_8262151
          • +6
            Я узнал об этом посте за две минуты до того, как написал комментарий. Вы тоже придраться хотите?

            Давайте, я попробую переформулировать: с момента публикации того комментария до момента выкатки первой версии исправления прошло чуть больше суток. С момента осознания о существовании exploit-in-the-wild до момента выкатки прошло чуть больше часа.
            • +3
              Мы не придираемся к словам, нет :-)

              Да, исправление после этого поста произошло очень оперативно! Тут разработчики Яндекса молодцы, вопрсов нет.

              В 23:16 появился пост, через полтора часа (ночью) появился комментарий «исправили». Это здорово и оперативно.
    • +5
      А сейчас что мешает?
    • +19
      ну так возьмите и выплатите ;-)
    • +7
      Почему бы и сейчас не выплатить?
      Вот например TopFace связались с пользовательем форума который у них нашел баг и выплатили ему премию за нахождение бага уже после сообщения на форуме.
    • –1
      Если б вы написали в bugbounty, мы бы были рады выплатить приз.


      Если вы помните, то это я сообщил вам про эту уязвимость тут habrahabr.ru/company/yandex/blog/249547/#comment_8261973.
      Запостил на bugbounty. Жду приз.
      • +9
        Кажется, весь смысл bugbounty в том, чтобы не объявлять о таких ошибках публично (и зарабатывать карму), а писать им лично (и зарабатывать доллары).
        • +2
          Если б вы написали в bugbounty, мы бы были рады выплатить приз.

          Я лишь воспользовался советом ivlad. Мне, в принципе, ни то, ни другое не нужно, но хоть бы упомянули для порядка.
  • +5
    Забавно. Особенно после вчерашнего поста яндекса с рекламно-надежной картинкой сейфа. Видимо завтра бакенд яндекса будет хранить в хеш-таблице сгенеренный post-ID для каждого показанного QR-кода
  • +13
    Т.е. ДВУХфакторная авторизация не предполагает ввода пароля? Забавно…
    • 0
      пароль тут — пин-код в приложении

      «вы задаёте в приложении четырёхзначный пин-код. Этот код станет одним из факторов, частью «секрета», на основе которого алгоритм будет создавать одноразовые пароли. Второй фактор хранится в смартфоне»
      • 0
        Только в случае телефона с TouchID вторым фактором вместо пин-кода становится палец владельца, так что теперь будет очень легко воспользоваться айфоном подвыпившего уставшего коллеги, чтобы зайти в его аккаунт, не зная пароль.
        • +2
          Я в оригинальном посте написал, что мы в курсе про проблемы биометрии. Поэтому TouchID является опциональным, можно продолжать пользоваться пином.
          • +1
            Ну тогда ведь должны знать, и как их обычно решают, вводя, как и в случае пароля, какой-то второй фактор. Т.е. биометрия вместе с паролем работают приемлемо, а вот биометрия вместо пароля при отсутствии физического контроля — сомнительно. Тут ведь проблема не столько с биометрией, сколько вообще с ситуацией потери контроля над телефоном, на который вы собрали оба фактора.

            Кстати, и если я правильно представляю, как была решена проблема (поскольку вряд ли за тот час, что все исправлялось, можно было радикально перелопатить архитектуру), запросы от браузера действительно идут по открытому http, в случае перехвата которого атаку опять можно будет воспроизвести, добавив во взламывающее приложение функциональность wireshark (понятно, что времени на это уйдет еще больше и успеть будет сложнее)?
            • +1
              Тут ведь проблема не столько с биометрией, сколько вообще с ситуацией потери контроля над телефоном, на который вы собрали оба фактора.
              Мне кажется, я это место в оригинальном посте тоже довольно подробно описал.

              Да, для разделения факторов мы закладываемся на то, что с реализацией secure enclave ребята в Apple не слишком налажали. Возможно, мы тут ошибаемся, и вскоре опубликуют уязвимость в их реализации. Тогда уберем TouchID. Сейчас можно не хранить пин в телефоне, разделяя хранение факторов.
              Кстати, и если я правильно представляю, как была решена проблема
              Кажется, неправильно. Запросы от браузера всегда ходят по https. Ссылка, которая есть в QR-коде нужна для того, чтобы, если ты отсканируешь ее обычным сканнером QR-кодов, попасть в какой-то URL, где пользователю расскажут, что это за QR-код. Из всей этой ссылки приложением Ключа используется только параметр track_id, который оттуда выкусывается и потом используется для провязки сессии.

              Исправили так: это по сути вариант CSRF, так что и защищаться от него можно способом, похожим на защиту от CSRF.
              • 0
                Ну понятно, я это и имел в виду. Насчет http уточнил, поскольку из первоначального поста это было не очевидно.

                С TouchID, конечно, вопрос религиозный.
        • 0
          Ну, если человек получит доступ к телефону подвыпившего коллеги, то это же совсем другая проблема. И неважно как он получит доступ — зная пароль, пин-код или приложив палец.
          • +2
            Вообще-то очень даже важно — палец вон он, лежит вместе с коллегой, а пин/пароль из его головы не вытащить.
            • +1
              Не хотел бы я таких коллег иметь, которые только и ждут момента что бы я напился, что бы воспользоваться моими телефоном.
      • 0
        То есть пользователь должен ввести ПИН-код, чтобы открыть приложение на смартфоне? Согласен, тогда появляется второй фактор (если конечно ПИН запрашивается для каждого нового входа, иначе воспользоваться чужим телефоном в отсутсвии хозяина даже проще, чем узнать его пароль). Но тогда каким образом автор этой статьи сумел обойти ввод пин-кода?
        • 0
          ПИН запрашивается даже перед каждой авторизацией.
        • +3
          Вообще, отдельное приложение для Яндекс-сервисов — это главная причина, почему я не буду пользоваться Яндекс.Ключом. Зачем мне ещё одно приложение, которое не поддерживает общепринятый стандарт, когда в приложении Google Auth я могу генерировать коды и для гугла и для Facebook и для Dropbox и прочего и прочего?
        • 0
          Ему не нужен был ввод ПИН-кода — ему нужен был только track_id (который он получал из QR), получив который он начинал делать те же самые запросы, которые делал JS у юзера в браузере.
  • –2
    Справедливости ради нужно отметить, что сам URL
    yandex.ru/promo/2fa?track_id=38e701d0bb5abaf50d381c3f95e0f341a8
    не используется в работе приложения, а только track_id из него передается на passport.yandex.ru.
  • +4
    Странно, мне показалось, что весь смысл этой разработки именно в привязке к устройству, к его ID?
    • –4
      Теряете телефон, прощай почта? Привязка к вашему номеру телефона
      • 0
        Там нет привязки к номеру телефона.
  • +23
    друзья ничего не замечали и очень удивлялись этому фокусу, когда я им показывал их почту на своем телефоне.

    Умеете вы, сударь, друзей развлекать.
  • 0
    Просто из любопытства. Если добавим проверку, чтоб IP отправителя PIN и QR-кода совпали, то это не поможет?
    • +1
      В сценарии с официантом — нет, ведь пользователь может быть подключен к точке доступа в кафе.
  • +12
    Никто так и не сделал двуфакторки с защитой от ниндзя.
  • +1
    Как-то не понятно. Вы бы хоть ссылку оставили на анонс этой самой «двухфакторной» авторизации. Судя по описанию в этой статье, она никакая не двухфакторная, раз имея доступ ко всего одному девайсу можно пройти авторизацию.
  • +2
    Как то никак.
  • +2
    Что-то я включил эту «двухфакторную» авторизацию и почувствовал себя гораздо менее защищенным, если раньше я вбивал пароль 20 символов со спец-знаками, то теперь я вбиваю лишь простой пинкод из 4 цифр.

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

    P.S. приложение кстати не хотело меня авторизовывать через QR-код, постоянно писало ошибку, через пароль тоже не хотело одноразовый, и только после того как я попытался авторизоваться с главной страницы — заработало.
    • 0
      если раньше я вбивал пароль 20 символов со спец-знаками, то теперь я вбиваю лишь простой пинкод из 4 цифр.
      Мы думаем над увеличением длины пин-кода.
      • 0
        Зачем он вообще нужен?
        Пин-код намного проще подсмотреть и запомнить, чем длинный пароль.
        • 0
          Пин-код — второй фактор. Не хочется использовать — не используйте, включите TouchID. Некоторые не доверяют TouchID, предпочитают вводить пин.
          • 0
            Какой TouchId на андроиде?
          • 0
            Так первый фактор должен быть пароль в основном браузере, нет?
    • +1
      А зачем вам пароль в 20 символов? Считаете что пароль в 10 символов недостаточно надёжен? А почему, сможете подробнее объяснить?
  • +1
    Ждем, когда Яндекс создаст табличку соответствия ID из QR-кода ID из куки.
    И тем самым пофиксит данное недоразумение.
    • –1
      Эту проблему давно исправили.
      • 0
        не обратил внимание на дату поста

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