Привет, Хабр! В данной статье хотел бы поделиться историей, как был найден достаточно простой в исполнении баг, но приводящий к опасной уязвимости веб приложения. Данный баг был найден в сервисе CloudTips от Тинькофф и CloudPayments на BugBounty площадке app.bugbounty.bi.zone.
![](https://habrastorage.org/getpro/habr/upload_files/6af/84e/294/6af84e294bf8dfa56f54820d0a8f4428.jpg)
Сперва расскажем, что вообще за такой CloudTips и в чем суть этого сервиса. CloudTips — сервис для приема безналичных чаевых, а также донатов. На данный момент можно наткнуться на многие ссылки для донатов каким-либо блогерам или компаниям, сделанных с помощью этого сервиса.
Чтобы воспользоваться сервисом, нужно использовать поддомен lk.cloudtips.ru. При успешной регистрации нас встречает страница нашего личного кабинета.
![](https://habrastorage.org/getpro/habr/upload_files/e5a/4c4/450/e5a4c445006bc544d10af0c04cbec01c.png)
Основной функционал сервиса CloudTips позволяет создавать свои страницы для перевода донатов (так называемые paymentpages), а также привязка этих страниц к QR-кодам, которые позволяют официантам их демонстрировать для перевода чаевых.
А сейчас пройдем путь обычного официанта, либо человека, желающего получить донат, по созданию той самой страницы для выплаты.
Выберем пункт «QR-Визитка» в левой панели личного кабинета QR-визитка. Видим, что по умолчанию у каждого пользователя присутствует одна ссылка для получения денег вместе с QR-кодом. Перейдем по ссылке и увидим внешний вид нашего paymentpage
![](https://habrastorage.org/getpro/habr/upload_files/1e7/891/e70/1e7891e709b6f5ac8d8a559b2eae39e4.png)
Видим, что по умолчанию у каждого пользователя присутствует одна ссылка для получения денег вместе с QR-кодом. Перейдем по ссылке и увидим внешний вид нашего paymentpage.
![](https://habrastorage.org/getpro/habr/upload_files/924/981/3db/9249813db425d76a312e32ef5d3c85a3.png)
Но что делать, если нам нужно создать новую страницу для переводов? CloudTips представляет нам эту возможность. Для этого выберем пункт «Мои ссылки» и дальше «Создать ссылку». Нас встретит интерфейс, позволяющий сделать страницу для переводов с огромным количеством параметров, которые можно редактировать:
backgroundId (Фоновое изображение)
title (название страницы)
backgroundUrl (фоновое изображение страницы оплаты)
paymentMessage (Текст на странице оплаты)
successMessage (Текст на странице успешной оплаты)
minimal (минимальная сумма платежа)
maximal (максимальная сумма платежа) и так далее
![](https://habrastorage.org/getpro/habr/upload_files/4a9/430/bc5/4a9430bc5ad1b1206ec7af3b8d4e6529.png)
Таким образом, создается новая страница для перевода денег вместе с QR-кодом, ведущим непосредственно на эту страницу.
Начало самого интересного
Мое внимание привлекла ссылка, которая генерируется самим сервисом, а именно уникальный ID:
![](https://habrastorage.org/getpro/habr/upload_files/42b/1b4/4b0/42b1b44b0b3c848204ca0fad2b5d1779.png)
Но каким образом происходит генерация ссылки? Для этого запустим инструмент, без которого не обходится ни один багхантер, а именно BurpSuite. Перехватываем запросы и смотрим как происходит весь процесс генерации страницы для оплаты:
![](https://habrastorage.org/getpro/habr/upload_files/1b8/326/9f2/1b83269f2b0544dd2850bc3061d83443.png)
Мы видим, что присутствует запрос, который генерирует ссылку для создания страницы для переводов по эндпоинту api.cloudtips.ru/api/paymentpages/urls/generate. Но куда эта ссылка попадает дальше? Перехватываем следующий запрос:
![](https://habrastorage.org/getpro/habr/upload_files/c70/d7e/bfd/c70d7ebfd535babfd9532b067f4b4cbe.png)
И видим, как по эндпоинту api.cloudtips.ru/api/paymentpages в наш запрос вставляется сгенерированная при прошлом запросе ссылка. Отправляем запрос… И видим в ответе от сервера, как создался наш paymentpage!
![](https://habrastorage.org/getpro/habr/upload_files/edb/af3/98b/edbaf398b7c87baf19dffe02658fd6c5.png)
Эксплуатация
И тут пришла в голову мысль, что произойдет, если при отправке запроса в параметр URL самому подставить что-либо вместо сгенерированного сервером URL. Недолго думая, пробуем подставить ID чужой страницы для переводов!
![](https://habrastorage.org/getpro/habr/upload_files/f9d/c3e/487/f9dc3e48733da956708439221e6788e7.png)
Иии…вуаля! Страница для выплаты добавилась к нам в профиль, теперь мы являемся ее полноценным обладателем. Но… ссылка на страницу осталась та же самая, то есть искомый владелец страницы не заметит подмены, а деньги, которые переводились жертве, теперь окажутся у злоумышленника.
![Страница жертвы Страница жертвы](https://habrastorage.org/getpro/habr/upload_files/4e0/4f2/d2d/4e04f2d2d369027c38794773633e98b9.jpg)
![После проделанных действий она становится достоянием злоумышленника После проделанных действий она становится достоянием злоумышленника](https://habrastorage.org/getpro/habr/upload_files/5b5/306/9df/5b53069dfd7e89efa37c781bcdc7f054.jpg)
Обратите внимание, что ссылка никак не поменялась и QR-код остается тем же. Но на этом не все. Функционал данного сервиса позволяет нам выставляет абсолютно любые параметры paymentpage’а, которые описывались раннее, в том числе никнэйм владельца страница, фото аватара, фон изображении. Для злоумышленника не составит труда подделать страницу идентичную жертвы. Вся работа api у CloudTips описана в их документации https://support.cloudpayments.ru/wiki/spaces/CA/pages/2601811972/API. В конце концов, злоумышленник привязывает к странице свою карту, подделывает ее внешний
вид - профит. Отличить ее от подлинника невозможно и донаты вместе с чаевыми уже приходят не пользователю, а злоумышленнику.
Итоговая оценка бага службой безопасности CloudPayments
Cразу хотелось бы поблагодарить сервис CloudPayments за оперативное ведение диалога, а площадку BI.ZONE BugBounty(https://app.bugbounty.bi.zone) за предоставленную возможность.
Изначально отправляя данную багу выставил критичность уровня "Critical", но пришел ответ от службы безопасности:
![](https://habrastorage.org/getpro/habr/upload_files/af9/98b/f6d/af998bf6df283c0b0f6688057cc88d46.png)
С первым пунктом я был не согласен, так как
Используем google dorks,например
site:pay.cloudtips.ru/p/*
Используем WaybackMachine
![](https://habrastorage.org/getpro/habr/upload_files/95f/e0b/3cb/95fe0b3cbda05d3da657d8a713468698.png)
И находим еще 1204 уникальных ссылок.
Второй аргумент парировать не получилось. Заранее предвидеть такую особенность было сложновато, не хватило опыта в тестировке.
Итог
Данная статья была опубликована с согласия службы безопасности CloudPayments. Баг был закрыт 3 месяца назад. Спасибо представителям BI.ZONE BugBounty и CloudPayments за быстрые ответы и существенные вознаграждения!
pyrk2142
Проблема выглядит интересно, но вот второй аргумент от компании очень странный:
Кажется, что достаточно легко найти/купить старый аккаунт, слышал даже про специальные сервисы/людей, которые регистрируют аккаунты пачками на новых сервисах, чтобы потом перепродать их с хорошими именами или бонусами для старых клиентов.
Про уменьшение скоупа странный аргумент, создал аккаунт, подождал месяца 2 с небольшим, куча официантов вышла к новогодним праздникам подработать, перед праздниками присвоил их ссылке заранее созданным аккаунтам, вывел деньги, смотришь на то, как негодует толпа официантов, в маркетинг и безопасники пытаются после праздников объяснить, где все чаевые.
Плюс, вообще не понимаю тягу сотрудников ИБ снижать критичность багов. И так довольно много людей считает, что в BugBounty надо нести мелочь, которую сложно реализовать выгоднее, так ещё тем, кто приносит реально серьёзную проблему, говорят, что она не серьезная.
ap_security Автор
Особенности российского BB))
pyrk2142
В целом, о российском BB у меня очень теплые воспоминания и отзывы. Самый кринж выдавали как раз крайне знаменитые и богатые иностранные компании, два ярких случая:
А первом компания подождала несколько месяцев, чтобы закрыть уязвимый сайт акции, а потом сказать, что они не могут воспроизвести проблему, так как сайт не открывается.
А во втором на довольно копеечную уязвимость была реакция вида: "На проде тестировать по правилам программы нельзя, вознаграждение за отчет с прода не дадим. Для тестирования есть специальный открытый тест. А на тесте нет угрозы от использования уязвимости, так как это тест, и он не используется в бизнес-процессе"
visse
Бессмертная классика.
visse
Более чем. Там всего восемь символов в уникальном ID, так что можно было бы и сбрутить какую-то часть без проблем.