Уязвимости ритейлеров — три случая, когда OTP можно было получить в запросе

При входе в личные кабинеты различных сервисов, в целях безопасности, часто используется 2FA — помимо логина и пароля, нужно ввести одноразовый код.

Но, как оказалось, не всё так безопасно даже с двухфакторной аутентификацией — за последний год я нашёл три (!) сервиса, когда одноразовый код для входа, который отправляется клиенту в SMS, можно было посмотреть в самом запросе.

Далее кратко о том, чем это грозило, на конкретных примерах.

1. Популярная сеть АЗС, более 500 000 зарегистрированных клиентов.

Запрос при входе в веб-версию личного кабинета:
POST https://someazs.ua/ua/profile/auth/
Accept: application/json, text/javascript, */*; q=0.01
Accept-Encoding: gzip, deflate, br
Accept-Language: ru,en-US;q=0.9,en;q=0.8,uk;q=0.7
Connection: keep-alive
Content-Length: 408
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Cookie: PHPSESSID=6n3l2o90hfb020u9ag020u8ha1; usersomeazs_popupcoupons=1;...
Host: someazs.ua
Origin: https://someazs.ua
Referer: https://someazs.ua/ua/login/
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
X-Compress: null
X-Requested-With: XMLHttpRequest

data[phone_mask]: 951234567
data[phone]: 0951234567


64gwlig4jbxmmjgyarfwpk1_lxa.png

Ответ: {"Status":0,"Code":"7038","status":true,"step2":true}

Код из SMS — 7038 — виден просто в ответе сервера.


То есть на сайте, при входе в личный кабинет, в ответе был одноразовый код для входа, который отправляется клиенту в SMS — можно было войти в чужую учётную запись, указав только номер телефона клиента —, а OTP посмотреть в самом запросе.

В личном кабинете доступны: номер карты лояльности, ФИО, балансы (бонусный в гривне, литровый, кофейный), история транзакций, в настройках — дата рождения, e-mail клиента и др.

cyg1fca8yzihzbxvru6nuybbuvi.png

С помощью дальнейших действий нетехнического характера (например, прозвон клиентов) при должном везении можно было бы воспользоваться клиентскими деньгами/литрами/кофе. Почему я пишу «при должном везении»? Когда общался о проблеме, мне сообщили, что расчёты чужими бонусами не так просто выполнить, даже если иметь доступ к учётной записи, так как есть дополнительные проверки. Тем не менее…

Ошибку исправили быстро, поблагодарили.


2. Сеть социальных магазинов (похожа на Fix-Price), мобильное приложение (более 100 тысяч скачиваний)

wxpsibh9vr7yeouxqlrsk65xyy8.png

Отслеживая запросы через Fiddler, я заметил следующее. При входе в мобильное приложение, после ввода номера телефона и карты лояльности, клиенту отправляется одноразовый код.

Проблема в том, что при этом выполняется GET-запрос вида:

https://bulk.somesmssender.com/?sending_method=sms&from=someretailes&user=onviber4821&txt=%D0%9A%D0%BE%D0%B4+%D0%BF%D0%BE%D0%B4%D1%82%D0%B2%D0%B5%D1%80%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D1%8F%3A+1234&phone=380987654321&sign=42f66957a03090eb90556b0ef7fed2e1

Прямо в этом запросе виден и сам одноразовый код: текст отправляемой SMS — это

%D0%9A%D0%BE%D0%B4+%D0%BF%D0%BE%D0%B4%D1%82%D0%B2%D0%B5%D1%80%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D1%8F%3A+1234&

Простое преобразование сообщает: Код+подтверждения:+1234

dxvkiw2myayp4dj-yys1bqlilka.png

Т.е. в самом приложении можно посмотреть, какой код будет отправлен. Здесь также можно входить в чужие учётные записи, уже без второго фактора.

Клиенты данной сети по определённым причинам наименее защищены от мошенничества, поэтому я много раз пытался донести информацию в компанию. Я писал три раза в августе на адрес, который был указан на странице приложения в Play Market — ни одного ответа не получил, даже автоматического.

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

Это верно, но, я предполагал, что сервис рассылки сообщений может повлиять на них как на партнёра/клиента. К тому же, причина, по которой я написал в сервис рассылки, в том, что указанный мной GET-запрос — это именно их разработка, и эта же ситуация с большой долей вероятности может быть у других их клиентов. Я предложил, что сервису желательно исправить логику рассылки — не передавать в запросе одновременно номера телефонов клиентов и одноразовый код — на это мне не ответили.

Немного о том, как ещё я пытался донести проблему

Затем на сайте магазина я написал на контактный email, подождал — и снова ничего. Но так как я упрямый, нашёл на том же сайте все возможные контакты (и общие ящики почты, и личные адреса) и написал им — как вы понимаете, тоже никто не ответил.
Поэтому позже я обратился в чат и прямо в чате задал вопрос, получали ли они мои письма. Сначала ответили, что не видят, потом нашли и пообещали, что передадут.


Что интересно, помимо отсутствия реакции на email на основной адрес приложения, после общения в чате мне приходили письма. В одном из них я увидел, как они меня завели в систему: «Умник»

jorofpagidbbwkbn96uoo9itapc.png

Так себе отношение к клиенту.

Когда я последний раз проверял, исправления со стороны Avrora не было.
Со стороны сервиса рассылки также не было исправлений, но тут ситуация более серьёзная, поэтому названия сервиса я прямо не указываю.


3. Мобильное приложение для хранения скидочных карт и выполнения мобильных платежей (более 130 тыс. клиентов)

При входе нужно ввести только email и код. При этом выполняется запрос:

POST http://api.somewallet.com/mobileclient.svc/getRegistrationCode HTTP/1.1
Content-Type: application/json; charset=UTF-8
Content-Length: 100
Host: api.somewallet.com
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/3.12.3

{«request»:{«Culture»: «ru_RU», «DeviceIdentifier»:»4514825570005447», «Identifier»: «some@email»}}

Вот ответ:
{"GetRegistrationCodeResult":{"ErrorMessage":{"Code":0,"LogReferenceId":0,"Message":"SUCCESS"},"Data":{"Code":"044912"}}}

Здесь в ответе также видно код, который нужно ввести (044912).

После входа я получил доступ к следующим функциям:

  • просмотр карт лояльности и бонусов на них,
  • купонов для определённых магазинов,
  • контактной информации о клиенте (номера телефонов и email, дата рождения и ФИО),
  • установка, изменение и удаление кода доступа из 4 цифр,
  • просмотр платёжных карт,
  • получение платёжного токена (похоже на токен из моей предыдущей статьи Как ездить на такси за чужой счёт).

Таким образом, все функции приложения могли быть доступны любому, кто просто укажет email пользователя данного приложения — не нужно узнавать одноразовый код у пользователя, так как его видно сразу при входе. Проблема идентична двум другим.

На моё сообщение отреагировали, уязвимость исправили и финансово отблагодарили.


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

© Habrahabr.ru