Twitter следит за тобой, анонимус

в 2:39, , рубрики: gdb, iOS, Privacy, reverse engineering, Spyware, twitter, twitter api, информационная безопасность, метки: , , , , ,

Часто приходиться слышать о том, что сильные и богатые корпорации вроде Google, Facebook или LG следят за каждым пуком несчастных пользователей. И исследовав некоторое из их software, я должен признать что таки да — они следят. Шпионят, гады.

Вот намедни я исследовал самый свежий (на момент написания этой статьи) официальный iOS-клиент Twitter версии 5.13.1. Мне, кроме всего прочего, было интересно посмотреть на траффик между клиентом и сервером. Поскольку клиент Twitter использует certificate pinning, его траффик довольно трудно перехватить с помощью Fiddler2 и подобных программ. Поэтому я написал define-команду для GDB, который цепляется на точку останова в [NSURLConnection start] и дампит в консоль интересные мне поля NSURLConnection непосредственно перед вызовом этого самого start. Такой нехитрый в общем-то фокус позволяет видеть что именно программа посылает на сервер ещё до того как это «что именно» будет зашифровано для дальнейше передачи по HTTPs.

И знаете что я увидел? Оказывается клиент Twitter, кроме своих обычных запросов (регистрация пользователя, авторизация, твит и т.п.) часто… нет, не так… очень часто посылает на сервер POST запросы на некий загадочный URL https://api.twitter.com/1.1/jot/client_event. Эти загадочные запросы отсылались на сервер почти по любому поводу. Я запустил клиент — запрос пошел! Я нажал кнопку «Sign in» (ещё не залогинился, просто кнопку жмакнул) — запрос пошел! Вылез экран логина, поле «Username» получило фокус — запрос пошел! Я свернул клиент — запрос пошел!.. Я конечно удивился и полез разбираться.

Типичный запрос на https://api.twitter.com/1.1/jot/client_event выглядел вот так (некоторые поля я, по понятным причинам, замазал):

Twitter следит за тобой, анонимус

Посмотрев пару десятков таких запросов, я примерно понял общую структуру:

URL:    https://api.twitter.com/1.1/jot/client_event
Method: POST
Headers:
  X-Twitter-API-Version: 5
  Authorization: OAuth... ля-ля-ля, обычная OAuth авторизация, подписанная секретным ключем (без кавычек)
                 "GgDYlkSvaPxGxC4X8liwpUoqKwwr3lCADbz8A7ADU&fgFuHBbtKUk1ykYzwEKaYeNg28H0XEvztfVQCEu8GA"
  X-Twitter-Client: Twitter-iPhone
  X-Twitter-Client-Version: 5.13.1
  Geolocation: мои координаты, блин (но если выключить Location Service - это поле исчезает из запросов)
  Accept-Language: en
  X-Twitter-Client-DeviceID: ID моего девайса
  X-Client-UUID: уникальный UUID (генерируется один раз при первом старте клиента, дальше не меняется) 
  User-Agent: Twitter-iPhone/5.13.1 тут версия iOS (Apple;iPhone3,1;;;;;1)
Body (понятное дело URL-encoded):
  lang=en&log=<cite>...тут интересный JSON (см. дальше)...</cite>&send_error_codes=1

Конечно самое интересное тут было в JSON в теле запроса. Во всех запросах это был массив элементов следующего вида:

[
  ...
  {
   "event_name": имя события
   "ts": UNIX timestamp,
   "format_version":2,
   "_category_":"client_event",
   "client_version":"Twitter-iPhone5.13.1 тут версия iOS (Apple;iPhone3,1;;;;;1)"
  }
  ...
]

Например, когда я нажимал кнопку «Sign in» (ещё не логинился, просто кпопку жмакал), на сервер уходил запрос с примерно таким JSON:

[
  {
   "event_name":"iphone:login:::impression",
   "ts":1385678390003,
   "format_version":2,
   "_category_":"client_event",
   "client_version":"Twitter-iPhone5.13.1 iOS6.1.3 (Apple;iPhone3,1;;;;;1)"
  }
]

Я смотрел другие запросы (их было много, да), и похоже что поля event_name, ts, format_version, _category_ и client_version являются обязательными. Они были у каждого элемента JSON'а, в каждом запросе. Но кроме них попадались и дополнительные поля. Например когда на экране логина поле «Username» получало фокус, в запросе уходил такой JSON:

[
  {
   "_category_":"client_event",
   "event_name":"iphone:ddg:digits_iphone_signup_1337::experiment",
   "client_version":"Twitter-iPhone5.13.1 iOS6.1.3 (Apple;iPhone3,1;;;;;1)",
   "ts":1385678389354,
   "experiment_key":"digits_iphone_signup_1337",
   "format_version":2,
   "version":12,
   "bucket":"uncheck_follows"
   }
]

Вероятно, поля experiment_key, version и bucket содержат какую-то дополнительную информацию о том что и как я делаю. Ну что бы ребятам в Twitter было понятнее. Что это за информация и что значат эти магические константы, я пока не знаю, но может быть соберусь исследовать этот вопрос внимательнее.

Вот собственно и всё. В конце статьи надо бы что-то сказать такое умное, но в четыре часа ночи в голову ничего не приходит. Могу только сказать что мне не нравится как Twitter через своё приложение следит почти что за каждым моим движением и знает в подробностях что, когда и (учитывая заголовок Geolocation) где я делаю с их программой. Вплоть до того на какую кнопку я тыцнул и когда. Может конечно это какой-то нужный и полезный эксперимент по сбору моего user experience, не даром же в некоторых запросах есть поле experiment_key. Может быть, я точно не знаю. Но мне всё равно эта дотошная подробная слежка не нравится.

А ещё мне не нравится что это приложение своими бесконечными «шпионскими» запросами сжирает мой дорогой (в буквальном смысле) GPRS траффик! Хорошо я хоть не в роуминге, а то с этими Twitter'овскими экспериментами за пару дней без штанов можно остаться… ладно, чего-то я разбурчался. Пойду спать наверное. На комментарии, если таковые будут, отвечу в районе обеда.

Всем хорошей пятницы :)

Автор: dimakovalenko

Источник

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


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