Как мы кикшеринг взломали

Предисловие

В один прекрасный весенний вечер мне в голову пришла прекрасная идея — попробовать зареверсить приватный API одного из самых крупных шерингов самокатов в РФ. Сразу скажу что на публикацию этого материала мне дал разрешение лично директор компании, но попросил не называть имена и название сервиса. Так же скажу что это не инструкция к действию, ведь уязвимость уже исправили и смысла пытаться её воспроизвести нет.

Цель

Для начала определим цель нашего исследования — понять как происходит взаимодействие с сервером, как запускается самокат и можно ли в этот процесс вмешаться с целью извлечения выгоды.

Подготовка

Отлично, с целью определились, как это реализовать?

Для перехвата пакетов данных которыми обмениваются клиент с сервером нам понадобится сниффер. Сниффер поможет нам влезть в передачу данных посредством Man In The Middle атаки.

Принцип работы MITM атаки.Принцип работы MITM атаки.

Снифферов полно, но мне нравится HTTP toolkit (он по непонятным мне причинам не доступен в РФ без VPN).

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

Тут нам на выручку приходит процесс подмены сертификатов в Android. Если вкратце, мы просто добавляем в систему наш сертификат, ключи от которого нам известны заранее. Соответственно, все что передается с использованием этого сертификата можно расшифровать

Подменить сертификат просто, но Android приложения зачастую не очень хотят отправлять данные используя наш сертификат, ведь они ему не доверяют.

Тут есть два пути:

  1. Если у вас есть root. Использовать встроенный в HTTP toolkit функционал и установить свой сертификат как системный, что убедит все приложения доверять ему.

  2. Если у вас нет root. Поменять настройки приложения путем его декомпиляции. Для этого можно использовать apkmitm.

Так как на моём телефоне есть root права, я пошёл по первому пути. Я просто запустил HTTP toolkit, подключился к телефону и он сам установил свой сертификат как доверенный. Теперь все приложения в которых нет защиты от подмены сертификатов будут отправлять данные используя мой сертификат.

Reverse engineering

Отлично, мы все подготовили, сертификаты подменили, сниффер настроили. Пора начинать реверсить.

Первым делом, после открытия приложения мы видим следующее.

Запросы на серверЗапросы на сервер

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

На самом деле, там целая куча запросов и разбирать каждый из них мы будем до утра.
Так что, в целях сокращения объема статьи я сразу перейду к тому запросу, который позволил мне взломать сервис и получить за это свой bug bounty.

Меня привлек запрос /gatewayclient/api/v1/order/make

Этот запрос на начало аренды самоката и в нём на самом деле немного параметров. Помимо необходимого токена авторизации и прочих скучных заголовков там есть всего 6 параметров. locationLat, locationLng, isQrCode, rateId, Identifier и withInsurance

locationLat и locationLng это координаты пользователя, они там находятся для того что бы пользователь не брал самокаты которые слишком далеко от него

isQrCode и withInsurance это логические значения (true или false) которые отвечают за то, взял ли пользователь самокат по qr коду и оформил ли он страховку поездки.

И самые интересные параметры — Identifier и rateId

Identifier — номер самоката

rateId — id тарифа по которому мы берем самокат

Меня очень зацепил rateId так как в теории, его можно подменить и взять самокат по другому тарифу.

Я решил посмотреть какие у них есть тарифы. Оказалось, что действительно, для каждой цены есть свой rateId

Например

5 р/м

j123id901k

8р/м

1asda2dasd

10 р/м

2ad32ad3a4

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

Нереальное веселье

Я тут же побежал писать маленький скрипт на основе модуля mitmproxy для Python. Этот модуль позволяет ловить запросы и изменять их на ходу. Я написал небольшой аддон для этого mitmproxy который подменял координаты на координаты рядом с самокатом, что бы можно было взять самокат где угодно. И добавил подмену тарифа, на самый дешёвый. Как только софт был готов, я быстренько залил его на телефон и запустил через Termux (это такой очень прикольный эмулятор терминала под Android).

Я подбежал к самокату, поднял прокси, и взял его в аренду. Посмотрел на телефон и понял, что я взял самокат в аренду за 2 рубля в минуту вместо положенных 10.

Радости были полные штаны, я в тот вечер накатался на этом самокате почти час, заплатив за это всего лишь 120 рублей, вместо положенных 600+

Bug report

Я конечно был безумно рад своему успеху, но мы же все порядочные люди и white hat хакеры. Поэтому я еще чуть-чуть покатался на дешевых самокатах и написал email в тех поддержку этого сервиса, в котором изложил всю суть уязвимости и дал предложения о том, как это исправить.

Мне ответили буквально через 10 минут и дали контакт их директора, сказали связаться с ним.

Я изложил суть ему, он выразил мне благодарность и спросил, чего я хочу в качестве bug bounty. Деньги мне в принципе не нужны, да и мерч какой-то тоже, так что я попросил просто начислить мне побольше бонусов, ведь я сам пользуюсь их сервисом. Через 10 минут у меня уже были мои драгоценные бонусы, которых мне скорее всего хватит на пару лет вперёд.

Как это предотвратить? Фикс

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

Заключение

В заключении скажу, что на самом деле уязвимость лежит на поверхности, но мне пришлось пройти достаточно длинный путь, что бы до неё добраться и конечным результатом я остался доволен. Надеюсь этот кейс даст вам хотя бы примерное понимание о том, как тестируют сервисы на уязвимости и может кто то из читателей сможет внести свой вклад в улучшение их любимого сервиса.

Всем спасибо за внимание, удачи.

Всегда ваш, @moscow_intelligent

© Habrahabr.ru