Ваше «приложение» могло быть просто сайтом (и я ему в этом помог)

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

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

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

Моя веб-страница выглядит не такой «красивой», как приложение, у которого она «заимствует» информацию. Зато весит она в разы меньше, и все стандартные фишки веб-браузеров достались ей абсолютно бесплатно.
Некоторым людям нравится формат «приложения», и это… нормально. Но ведь встречаются такие приложения, которые можно было бы вполне реализовать в виде веб-страницы. Особенно в таких случаях, как мой, когда их контент уже написан на HTML и передаётся по HTTP. Ну ведь очевидно, что это должен быть сайт, разве не так?
И как только мы докатились до такой «культуры создания приложений»… Разработчики ПО сами же усложняют себе жизнь (и удорожают, так как размещение в крупных магазинах стоит денег), чтобы в результате предложить HTML-контент меньшему числу людей и с меньшим количеством функций7, чем в случае прямого размещения в веб-среде.
Да, есть такие задачи, для которых «приложение» реально оправдано. Но это явно не про Travelbound.
Зато теперь, по крайней мере, у меня и у остальных участников, с которыми я поделился своей страницей, есть выбор, каким способом получать доступ к этому контенту. Либо использовать приложение на 43 МБ (раздувающееся до 124 после скачивания допов) с отслеживанием и рекламой… либо сайт размером 0,05 МБ (с возможностью подгрузить ещё 35 МБ изображений), который имеет больше функций и работает на большем числе устройств. Для меня выбор очевиден!
Сноски
1 И это только те фичи, которые оценят абсолютно все. Веб-страница, которую я в итоге сделал как альтернативу приложению, также имеет несколько функций из разряда «полезно для юзера / кошмар для разработчика» — например, она вырезает код отслеживания и вообще не показывает рекламу. ↵
2 Получить root-права на устройстве необходимо для того, чтобы заставить приложения, использующие Certificate Pinning (привязку сертификатов), доверять вашему MITM-серверу. Без этого некоторые приложения — включая то, которое я пытался разобрать — распознают ваш самоподписанный TLS-сертификат как недействительный и просто откажутся устанавливать связь. ↵
3 Без изменения этой настройки в Magisk я столкнулся с тем, что HTTP Toolkit запрашивал su-доступ, но не дожидался ответа и переходил в режим работы без привилегий ещё до того, как я успевал этот запрос одобрить! ↵
4 Из-за политики безопасности Android мне пришлось вручную установить корневой сертификат удостоверяющего центра, который подготовила программа, но сами инструкции вполне сработали. ↵
5 Имя пользователя и пароль выдаются сразу всей туристической группе. Сдаётся мне, у них вообще нет никакого плана на случай утечки этих данных. Ну или, возможно, они считают всю эту информацию настолько неважной, что не придают этому значения… В таком случае я возвращаюсь к своему первому вопросу: «Какого чёрта это нельзя было изначально сделать обычной веб-страницей»? ↵
6 Ну или изображения нужно кэшировать локально — судя по всему, именно это приложение и делает, причём максимально раздутым способом. ↵
7 И зачастую с худшей доступностью. Я не проводил аудит доступности этого приложения, но некоторые детали подсказывают, что пользоваться им с помощью ассистивных технологий будет гораздо сложнее, чем моей простой и понятной веб-версией. ↵
Автор: Bright_Translate

