- PVSM.RU - https://www.pvsm.ru -

Этим летом наша детская школа искусств выступает с песнями и танцами на шоу в Диснейленде. Мы все предвкушаем поездку, но мою радость слегка омрачил тот факт, что для доступа к расписанию, графику поездки и информации о проживании придётся установить приложение Travelbound [1].
Да на кой оно мне надо? Это должна была быть простая веб-страница. С чего ради я должен устанавливать очередное хреново приложение только ради того, чтобы увидеть информацию, которую можно было уместить в гораздо более компактном, быстром и доступном документе?
И я нисколько не преувеличиваю. По своей сути, это приложение представляет текст, картинки и ссылки на PDF-файлы, загружаемые из интернета.
При этом делает оно буквально две вещи, на которые неспособна веб-страница, и которые обе являются антифичами:
Отправляет разработчикам данные отслеживания действий вашего аккаунта Google.
Показывает рекламу других путешествий, организуемых тем же агентством, преподнося их как «источники вдохновения».
Обычная веб-страница подошла бы намного лучше. В отличие от этого приложения её можно:1 [2]
копировать,
распечатывать,
сохранять,
добавлять в закладки,
использовать практически на любом устройстве,
плюс на ней можно искать текст, и «потенциально» она более доступна.
Меня настолько взбесила эта ситуация, что я собираюсь «исправить» это приложение. Подержите моё пиво.
Я уже давно не реверсил Android-приложение [3] на основе его сетевого трафика, так что пришлось вспоминать, как это лучше всего сделать. В итоге я пошёл таким путём:
Создал новые виртуальные устройства в Virtual Device Manager в Android Studio.
Проверил, работает ли adb shell, и с помощью rootAVD [4] получил root-права: ./rootAVD.sh system-images/android-33/google_apis_playstore/x86_64/ramdisk.img.2 [5]
Выполнил холодную загрузку, запустил Magisk [6] и перенастроил его так, чтобы он автоматически выдавал права суперпользователя любому приложению, которое его запросит.3 [7]

Весь ваш трафик принадлежит мне. С этого момента работа с ним ничем не отличается от анализа с помощью Wireshark или TCPdump.
Запустил HTTP Toolkit [8] и настроил его на перехват трафика с виртуального устройства (AVD). Программа развернула локальный VPN и пустила трафик телефона через него.4 [9]
Установил приложение Travelbound из Play Store.
Настроил HTTP Toolkit так, чтобы проксировать только приложение Travelbound (меньше лишнего шума — больше полезных данных).
Всего за пару минут экспериментов я выяснил принцип работы приложения: оно конкатенирует имя пользователя и пароль5 [10], после чего подставляет результат в URL следующего вида:
https://travelbound.api.vamoos.com/api/itineraries/{username}-{password} [11]
Этот запрос возвращает огромный массив данных в формате JSON, в котором после небольшого анализа можно легко разглядеть весь контент, который приложение «показывает». Например, там есть:
массив, содержащий каждый этап маршрута,
массив, содержащий все рекламные объявления для показа пользователю,
перекрёстный массив, содержащий все файлы (изображения и прочее), на которые ссылаются другие разделы, и так далее.

И они всё равно генерируют HTML-код… так что я снова задаюсь вопросом: «Почему это не веб-страница?»
Немного поэкспериментировав, я выяснил, что для URL-адресов изображений, поступающих из хранилища S3, устанавливается довольно короткий срок действия. Это значит, что необходимо периодически запрашивать JSON-данные, даже если контент за это время не изменился.6 [12]
Теперь у меня было всё необходимое, чтобы сделать нечто... получше. Я написал на Ruby скрипт, который запускается по расписанию через Cron, забирает актуальный JSON и собирает на его основе HTML-страницу.
Я решил полностью пропускать «вдохновляющую» рекламу (использовав overlayRows в схеме данных) и выводить только:
элементы маршрута,
все файлы, на которые не ссылаются ни маршрут, ни подборки (ленивый способ собрать вместе ссылки для скачивания PDF-файлов).
После этого я захостил страницу, защитив её паролем: тем же, который выдали моей тур-группе. А исходный JSON, на основе которого она строилась, я скрыл в HTML-элементе <details>. Это позволит мне его перепроверить в случае, если в схеме появятся новые элементы, которые я изначально не учёл.

Моя веб-страница выглядит не такой «красивой», как приложение, у которого она «заимствует» информацию. Зато весит она в разы меньше, и все стандартные фишки веб-браузеров достались ей абсолютно бесплатно.
Некоторым людям нравится формат «приложения», и это… нормально. Но ведь встречаются такие приложения, которые можно было бы вполне реализовать в виде веб-страницы. Особенно в таких случаях, как мой, когда их контент уже написан на HTML и передаётся по HTTP. Ну ведь очевидно, что это должен быть сайт, разве не так?
И как только мы докатились до такой «культуры создания приложений»… Разработчики ПО сами же усложняют себе жизнь (и удорожают, так как размещение в крупных магазинах стоит денег), чтобы в результате предложить HTML-контент меньшему числу людей и с меньшим количеством функций7 [13], чем в случае прямого размещения в веб-среде.
Да, есть такие задачи, для которых «приложение» реально оправдано. Но это явно не про Travelbound.
Зато теперь, по крайней мере, у меня и у остальных участников, с которыми я поделился своей страницей, есть выбор, каким способом получать доступ к этому контенту. Либо использовать приложение на 43 МБ (раздувающееся до 124 после скачивания допов) с отслеживанием и рекламой… либо сайт размером 0,05 МБ (с возможностью подгрузить ещё 35 МБ изображений), который имеет больше функций и работает на большем числе устройств. Для меня выбор очевиден!
1 И это только те фичи, которые оценят абсолютно все. Веб-страница, которую я в итоге сделал как альтернативу приложению, также имеет несколько функций из разряда «полезно для юзера / кошмар для разработчика» — например, она вырезает код отслеживания и вообще не показывает рекламу. ↵ [14]
2 Получить root-права на устройстве необходимо для того, чтобы заставить приложения, использующие Certificate Pinning (привязку сертификатов), доверять вашему MITM-серверу. Без этого некоторые приложения — включая то, которое я пытался разобрать — распознают ваш самоподписанный TLS-сертификат как недействительный и просто откажутся устанавливать связь. ↵ [15]
3 Без изменения этой настройки в Magisk я столкнулся с тем, что HTTP Toolkit запрашивал su-доступ, но не дожидался ответа и переходил в режим работы без привилегий ещё до того, как я успевал этот запрос одобрить! ↵ [16]
4 Из-за политики безопасности Android мне пришлось вручную установить корневой сертификат удостоверяющего центра, который подготовила программа, но сами инструкции вполне сработали. ↵ [17]
5 Имя пользователя и пароль выдаются сразу всей туристической группе. Сдаётся мне, у них вообще нет никакого плана на случай утечки этих данных. Ну или, возможно, они считают всю эту информацию настолько неважной, что не придают этому значения… В таком случае я возвращаюсь к своему первому вопросу: «Какого чёрта это нельзя было изначально сделать обычной веб-страницей»? ↵ [18]
6 Ну или изображения нужно кэшировать локально — судя по всему, именно это приложение и делает, причём максимально раздутым способом. ↵ [19]
7 И зачастую с худшей доступностью. Я не проводил аудит доступности этого приложения, но некоторые детали подсказывают, что пользоваться им с помощью ассистивных технологий будет гораздо сложнее, чем моей простой и понятной веб-версией. ↵ [20]
Автор: Bright_Translate
Источник [21]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/ruby/455167
Ссылки в тексте:
[1] приложение Travelbound: https://play.google.com/store/apps/details?id=com.vamoos.apps.travelbound
[2] 1: #id1
[3] давно не реверсил Android-приложение: https://danq.me/2018/07/05/comic-chameleon/
[4] rootAVD: https://gitlab.com/newbit/rootAVD
[5] 2: #id2
[6] Magisk: https://github.com/topjohnwu/Magisk
[7] 3: #id3
[8] HTTP Toolkit: https://httptoolkit.com/
[9] 4: #id4
[10] 5: #id5
[11] https://travelbound.api.vamoos.com/api/itineraries/{username}-{password}: https://travelbound.api.vamoos.com/api/itineraries/%7Busername%7D-%7Bpassword%7D
[12] 6: #id6
[13] 7: #id7
[14] ↵: #id11
[15] ↵: #id12
[16] ↵: #id13
[17] ↵: #id14
[18] ↵: #id15
[19] ↵: #id16
[20] ↵: #id17
[21] Источник: https://habr.com/ru/companies/ruvds/articles/1060106/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1060106
Нажмите здесь для печати.