Яндекс.Пробки. А туда ли вы едете?

в 9:57, , рубрики: digital security, Блог компании «Digital Security», информационная безопасность, пробки, яндекс, метки: , ,

В прошлой статье была затронута тема информационной безопасности такой крупной компании, как Google.
Настало время посмотреть в сторону отечественного производителя, а именно, компании Яндекс и её сервиса карт.
С чего все началось. Стоял я, значит, как-то в пробке и думал, что заставляет всех людей ездить теми или иными маршрутами. Ответ очевиден: много чего.
Однако не последнюю роль определенно играет наличие пробок и разного рода дорожных ситуаций (ДТП, ремонт полотна, камеры).
Кроме того, эти факторы учитывают и все современные навигаторы при прокладке маршрута.
Что ж, попробуем повлиять на дорожную обстановку, хотя бы виртуально…
Яндекс.Пробки. А туда ли вы едете?

Играть будем с картами от компании Яндекс. Для начала разберемся, как вообще работает система. Все просто: мобильные пользователи ставят приложение и отправляют данные с координатами, направлением и скоростью на уютный сервачок Яндекса, где полученные данные агрегируются, после чего и рисуется карта.
Коротко говоря, едешь медленно – значит стоишь в пробке, быстро – все свободно. Чем больше людей (устройств) отправляют статистику, тем точнее данные. Подробнее о работе системе написано у самого Яндекса.

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

Так-так-так, если данные обезличены, то почему бы нам не попробовать стать той кучей пользователей, которые отправляют данные, например, с нужной нам скоростью, дабы информация о загруженностью дорог в выбранном направлении изменилась? (http://en.wikipedia.org/wiki/Spoofing_attack)
Итак, у нас на руках телефон с ОС Android на борту, приложение "Яндекс.карты" и сниффер "Shark".
Необходимо для начала посмотреть, как обмениваются между собой данными приложение и сервер.
Соглашаемся на отправку данных о дорожных ситуациях, запускаем сниффер и катаемся по городу, собирая пакеты (сетевые, конечно).

Для начала попробуем поставить какую-нибудь метку о дорожной ситуации, например:

Яндекс.Пробки. А туда ли вы едете?

ловим пакет:

GET /userpoi/addpoint?uuid=a61d46553953fc3e346dae59d852c950&catidx=2&lat=59.985712&lon=30.350740&utf&comment=bla%20bla&packetid=2936036690 HTTP/1.1
Host: mobile-partners.maps.yandex.net

uuid – параметр-идентификатор пользователя
catidx – категория метки
lat;lon – координаты, куда ставится метка
comment – коментарий
packetid – ID пакета

Как, собственно, и ожидалось, можно рандомно менять uuid. Метки успешно ставились. Изменение packetid также ни на что не повлияло.
Играя с различными значениями (координаты и тип метки) и многократно посылая пакеты, можно в короткие сроки затруднить просмотр карты:

Яндекс.Пробки. А туда ли вы едете?

Но это все ребячество, где же данные о пробках?
Долго ждать не приходится, сразу бросается в глаза следующий пакет:

POST /ymm_collect/2.x/?uuid=a61d46553953fc3e346dae59d852c950&packetid=2052426273&compressed=1&oauth_token= HTTP/1.1
Content-Type: multipart/form-data; boundary=edge_here
Host: mobile-partners.maps.yandex.net

--edge_here
Content-Disposition: form-data; name="data"
Content-Type: application/gzip

..........m.[.. .E.....(/.4.C1... ..../m.l..Y;G....i..........'....4..}..>..3...[.:.E...1i.d![)x..?.'.k...a<.......0.=o..*w.[.F.H....J)c.)ot^.......z#oq..x...
.i......

uuid – знакомый нам параметр-идентификатор, значение которого можно произвольно менять.
packetid – как можно понять из названия, это ID пакета. Он же является и его контрольной суммой.

В пейлоаде POST-запроса – не что иное, как gzip, внутри которого можно увидеть что-то типа:

<?xml version="1.0" encoding="utf8" ?><traffic_collect><point lat="59.946379" lon="30.329207" avg_speed="2" direction="180" time="23052011:194509" /></traffic_collect>

Как раз то, что мы ищем: текущее местоположение, направление, скорость и время.

Пробуем играть со значениями в xml, меняя направление, положение, скорость и время => пакеты не принимаются сервером. Оно и очевидно, контрольные суммы не сходятся. Выход один: узнать, как сгенерировать packetid.

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

Яндекс.Пробки. А туда ли вы едете?

Шикарно. Исходник есть, осталось только разобраться, как это работает.
А работало оно следующим образом:

1) xml с данными gzip'овалась
2) полученный gzip ксорился побайтово с uuid
3) от полученого результата вычислялся CRC32
4) итоговым результатом и был заветный packetid

Мы знаем, как генерятся контрольные суммы – теперь ничто не мешает нам накодить скрипт, который будет отправлять на сервера Яндекса данные с нашими координатами и скоростью.
Тестим.

Яндекс.Пробки. А туда ли вы едете?

Все отлично работает: на улице появился несуществующий затор.
А если там еще поставить парочку меток об аварии или дорожных работах, то вполне можно заставить некоторых доверчивых водителей (или их навигаторы) принять решение об изменении своего маршрута, тем самым позволив мне, любимому, свободно доехать до дома!

Этот и еще множество других докладов по инфобезу можно услышать на ежемесячных встречах Russian Defcon Group, что проходят в Питере. Приходите, там всегда интересно.

Такие дела.
Ах да, информация о данной баге была своевременно предоставленна ребятам из Я, которые все очень оперативно прикрыли. Молодцы.
Вам же предлагаю не расстраиваться, ведь есть еще Google и Nokia с их пробками!
Ну и совсем любопытным – код скрипта для спуфинга Яндекс Пробок: http://pastebin.com/9y4hmFX9
Огромное спасибо ntkt за помощь и с прошедшим ДР!

До встречи на дорогах.

Автор: chipik

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js