Взлом iOS приложений без модификации пакета
Дай человеку рыбу, и он будет сыт один день, научи его ловить рыбу, и он будет сыт всегда.
Наверняка во время скачивания готовых взломов приложений с каналов хоть раз вы задумывались, "как бы здорово было уметь взламывать самому". Когда-то и я так думал, однако в то время и до сих пор не было таких материалов, которые бы провели сквозь это непростое дело и досконально всё показали. И вот, когда я всё-таки на какую-то часть освоил дело взломов iOS приложений, у меня появился уникальный шанс перевернуть сложившийся порядок и пролить свет на то, чем мы занимаемся. Соблазн этим шансом воспользоваться был слишком велик, я долго собирался, а теперь вы читаете эти строки. Так давайте приблизим дивный новый мир, где каждый взламывает себе сам что хочет!
Будем начинать с самого простого и постепенно углубляться. Но сначала немного теории для реально заинтересованных. Желающие просто спокойно взломать могут пропустить следующий раздел и перейти к реализации, однако пропуск теории может помешать дальнейшему пониманию.
Содержание
Редактирование файлов приложения
Места, которые стоит проверить в первую очередь
Редактирование оперативной памяти приложения
Подмена ответа от сервера проверки чека
Отслеживание запросов и просмотр ответов
Теория
В iOS существует StoreKit — система выполнения внутренних покупок в приложениях. Она осуществляет учёт внутренних покупок и их оплату, именно её окно с запросом подтверждения вы видете при попытке оплатить покупку. По правилам App Store приложение в обязательном порядке должны проводить оплату через неё. И эта система предполагает 4 категории внутренних покупок.
- Невозобновляемые подписки
- Авто-возобновляемые подписки
- Нерасходуемые (разовые покупки)
- Расходуемые (монетки в игре, "разы использования" в некоторых программах)
Данные о первых трёх категориях покупок, сохраняются на сервере Apple, чтобы любое приложение всегда могло получить сведения обо всех выполненных пользователем в нём покупках. Информацию о расходуемых покупках приложение вынуждено хранить где-то у себя, и их невозможно восстановить, следовательно, дальнейшие рассуждения будут касаться в основном первых трёх категорий. Как же сервер Apple в лице StoreKit передаёт информацию о покупках приложению? Через специальный файл — чек, вокруг которого всё и будет вращаться. Чек — это зашифрованный файл в формате PKCS#7, который содержит в себе информацию обо всех покупках, выполненных в приложении. Чек может появиться даже если приложение не имеет покупок, в таком случае в нём будет зафиксировано их отсутствие.
Как и когда он появляется?
- Если приложение устанавливается с App Store, то сразу же после установки
- Если приложение устанавливается из других источников, то изначально чека нет, и, чтобы получить, приложение должно самостоятельно его запросить у StoreKit.
После создания чек сохраняется по пути /private/var/mobile/Containers/Data/Application/*/StoreKit. При попытке открыть его в текстовом редакторе, конечно, вы мало что что сможете прочитать (он зашифрован), поэтому просто дописать в чек выполненные покупки не вариант.
Но вот незадача: приложения без дополнительных действий, как и мы, не способны его прочитать. Перед этим его необходимо расшифровать. Сделать это можно несколькими способами:
- Интегрировать в приложение специальную библиотеку OpenSSL и расшифровывать локально на устройстве.
- Отправлять для расшифровки на сервер apple по адресу https://buy.itunes.apple.com/verifyReceipt. Сервер вернёт содержащийся в чеке json с данными о покупках.
- Отправлять для расшифровки на свой собственный (или чей-то ещё) сервер, который вернёт ответ в таком формате, который захочет разработчик. Обычно это также какой-либо json.
После того, как приложение получило сведения о покупках из чека, оно может сохранить их в свой кэш или оставить в оперативной памяти, одним словом, оно будет знать, что покупка действительно выполнена, или что она отсутствует.
Рассмотрим процессы, происходящие при выполнении новой или восстановлении старой покупки.
- Пользователь пытается выполнить покупку или восстановить её
- В случае выполнения приложение вызывает StoreKit, через который происходит оплата, и который создаёт чек, добавляет туда покупку и возвращает чек приложению. В случае восстановления приложение получает чек из своей папки "StoreKit" или, если его там нет, запрашивает у самого StoreKit.
- Приложение расшифровывает чек одним из приведённых выше способов.
- Приложение использует полученные данные о покупках.
Какие же места этого процесса уязвимы? Таких мест три.
- Формирование чека. При выполнении покупки её можно отменить, а чек подделать, зашифровать и отдать приложению. Такой метод реализован при помощи твиков, о которых речь пойдёт во втором разделе. Такой способ подходит только в случае, если проверка чека происходит локально на устройстве, серверная проверка замечает подвох. Речь о нём пойдёт во третьем разделе.
- Хранение данных о покупке в оперативной памяти. Такой способ больше всего подходит для расходуемых покупок, так как зная их количество можно отыскать их в оперативной памяти приложения и изменить, об этом речь идёт в четвёртом разделе.
- Хранение данных в кэше приложения. После проверки чека, приложение где-то хранит сведения о покупке, а если оно их не шифрует, то их можно изменить. Об этом речь пойдёт в первом разделе
- Передача сервером для проверки данных от расшифрованного им чека приложению. Следите за руками. Приложение шлёт чек на проверку на сервер; сервер расшифровывает его и посылает приложению ответ о том, что покупок в нём нет; мы перехватываем ответ и пишем, что они есть; приложение получает ответ и думает, что всё в порядке. Подходит только для серверной проверки. Этот способ самый перспективный, так как всё больше приложений используют серверный метод расшифровки чека, при этом такой способ проще для выполнения без джейлбрейка. Речь о нём пойдёт в предпоследнем разделе
Также в качестве домашнего задания рекомендую изучить следующие темы (понадобятся в предпоследней части):
- Веб-запросы
- JSON
- Регулярные выражения
Редактирование файлов приложения
Плюсы: позволяет быстро накрутить игровую валюту, включить премиум данные сохраняются в кэш
Минусы: Как правило может быть применён только на расходуемых покупках, без джейлбрейка нужно подписывать и устанавливать приложения, взламывать, а затем переносить кэш с выполненной накруткой в оригинальные приложения
Очень редко приложения хранят данные о покупках в кэше в незашифрованном виде, тогда эти данные можно найти и изменить. Как уже сказано, получаться будет нечасто.
Поиск кэша приложения
В iOS приложения хранят свои данные по путям /private/var/mobile/Containers/Data/Application/* и /private/var/mobile/Containers/Shared/AppGroup/*.
- Для джейлбрейка и Тролль стора есть программа Apps Manager, позволяющая делать копии данных и быстро открывать папки с данными приложений в Filza. Подробнее здесь.
- Универсальный способ добраться до кэша — вытащить его через iMazing, отредактировать и затем перенести обратно. Подробнее здесь.
- Для некоторых iOS это можно сделать через Filza. Подробнее здесь.
Места, которые стоит проверить в первую очередь
Файл plist с названием в виде bundle id приложения, находящийся по пути папка-с-кэшем/Library/Preferences. Он предназначен для хранения настроек приложения, там же может находится значение по типу Premium = true или Unlock = 1, говорящее о совершённой покупке. Игры иногда хранят там число внутриигровой валюты. Пример — Nicegram, у которого когда-то было достаточно изменить значение HasUnlimPremium на YES.
Папка Documents в папке кэша. Больше всего актуально для игр, которые хранят тут ваш прогресс, включая число внутриигровой валюты. Обращайте внимание на файлы с названием наподобие save и открывайте их в текстовом редакторе. Например у игры SonicDash+ в папке Documents лежит файл save.txt, в котором можно легко найти и изменить числа валюты, опыта и звёзд.
Не шифруют данные обычно те игры, которым нечего защищать, то есть в которых нет внутриигровых покупок, поэтому таким способом валюту чаще всего можно накрутить в играх из Apple Arcade.
Подделка чека
Плюсы: простота и скорость (с джейлбрейком:)), данные о покупке сохраняются в кэш.
Минусы: срабатывает в меньшинстве случаев, без джейлбрейка нужно подписывать и устанавливать приложения, взламывать, а затем переносить кэш с выполненной покупкой в оригинальные.
Чек можно подделать при помощи следующих твиков:
Функционал твиков примерно одинаковый, но
- крайне редко приложение ломается только одним из них,
- при покупке валюты в играх при активации двух или всех этих твиков одна покупка может засчитываться за две или три, из-за чего валюта накручивается быстрее,
поэтому с джейлбрейком есть смысл поставить все три твика.
Без джейлбрейка возможно использовать только Satella.
Установка инструментов
Если у вас есть джейлбрейк, добавьте в ваш менеджер пакетов репозиторий ReJail установите iAP26 и LocalIAPStore, добавьте репозиторий Paisseon, найдите и установите Satella.
Достать ipa файл приложения, которое хотите взломать, с просторов интернета. Можно попробовать дешифровать на этом сайте.
Скачать специальную версию Satella — SatellaJailed.
Подписать и установить ipa взламываемого приложения, при этом вшив dylib Satella любым способом. О подписи и установке приложений читайте здесь.
Важно! Для подписи не подойдут бесплатный семидневный сертификат (кроме bullfrog), а также корневой сертификат (troll), т.к. они не обладают правами на использование внутренних покупок.
Рассмотрим способ с вшиванием через eSign.
Сохраните ранее скаченный файл dylib в eSign.
При подписи приложения нажмите "Установить твик (dylib,framework,deb)".
Выберите Satella и нажмите "OK".
Подписывайте и устанавливайте дальше по плану.
Настройка инструментов
Рассмотрим важные настройки твиков.
iAP26 достаточно просто включить.
В настройках LocalIAPStore есть пункт "Enable Double Coins", при включении которого в играх одна покупка валюты начинает считаться за две.
Чтобы открыть настройки SatellaJailed, вшитой в приложение, зайдите в установленное приложение и нажмите на "звезду".
В Satella есть возможность включить твик для всех приложений ("Global Injection") или для определённых ("Enabled Apps").
"Sideloaded" сделает твик активным для приложений, установленнных не из App Store.
"Observer" срабатывает очень редко, но в некоторых приложениях, пока он включен, покупки будут считаться выполненными (таким образом, в кэш они не сохраняются).
Использование инструментов
Запустите приложение, в котором хотите взломать покупку.
Найдите покупку и попытайтесь выполнить её.
Нажмите "Отменить" во всплывающем окне.
Если твики могут взломать данное приложение, покупка выполнится. Если же она не выполнилась, этими твиками данное приложение не взломать.
Данные о покупке сохраняются в файлы приложения. После взлома можно попробовать перенести кэш любым способом на другое устройство / в официальную версию приложения. Некоторые приложения поддаются переносу покупок, некоторые нет.
Редактирование оперативной памяти приложения
Плюсы: позволяет относительно быстро накрутить игровую валюту, включить премиум, данные сохраняются в кэш
Минусы: Как правило может быть применён только на расходуемых покупках, без джейлбрейка нужно подписывать и устанавливать приложения, взламывать, а затем переносить кэш с выполненной накруткой в оригинальные приложения
К числу этих твиков относятся:
iGameGod является современным и обновляющимся твиком, который использовать удобно и предпочтительно. Не смотря на это, он имеет два недостатка: в нём имеется встроенная реклама, а (редко) некоторые приложения при его активации начинают вылетать. GameGemiOS очень старый и работает только через терминал, вследствие чего не подойдёт для неуверенных пользователей, однако не имеет недостатков первого твика.
Без джейлбрейка можно использовать только iGameGod.
Установка инструментов
Если у вас есть джейлбрейк, добавьте в ваш менеджер пакетов репозиторий iOSGods, найдите и установите iGameGod.
В случае желания опробовать также GameGemiOS,
- добавьте в ваш менеджер пакетов репозиторий ReJail установите GameGemiOS;
- установите терминал, например NewTerm;
- по желанию для большего удобства установите команду автоматизации запуска GameGem.
Достать ipa файл приложения, которое хотите взломать, с просторов интернета. Можно попробовать дешифровать на этом сайте
Скачать deb файл iGameGod.
Подписать и установить ipa взламываемого приложения, при этом вшив deb iGameGod любым способом. О подписи и установке приложений читайте здесь.
Рассмотрим способ с вшиванием через eSign.
Сохраните ранее скаченный файл deb в eSign.
При подписи приложения нажмите "Установить твик (dylib,framework,deb)".
Выберите iGameGod и нажмите "OK"
Подписывайте и устанавливайте дальше по плану.
Использование инструментов
Если вы с джейлбрейком и устанавливали iGameGod как твик, откройте приложение iGameGod, найдите взламываемое приложение и активируйте
Откройте взламываемое приложение, получите некоторое количество валюты и запомните его. Справа сверху увидите значок iGameGod. Нажмите на него.
Нажмите на "*" и в выпадающем списке выберите "int32 i4"
Впишите нынешнее количество валюты и нажмите "Search"
Скорее всего, вариантов нашлось много. В таком случае закройте iGameGod нажатием крестика.
Измените количество валюты — потратьте её или приобретите. Запомните новое количество валюты и снова откройте iGameGod.
Введите в поиск новое количество валюты и снова нажмите "Search"
Скорее всего результатов найдётся несколько (если их всё ещё много, повторите действия с изменением количества). Нажмите нижнюю левую кнопку.
Нажмите нижнюю правую кнопку, которая выделит все результаты, затем нажмите "Edit selection"
Введите желаемое количество и нажмите "Confirm"
Если число валюты в игре не изменилось, снова потратьте или получите её, после этого изменения должны закрепиться.
Чтобы накрутить другой показатель, нажмите на лупу в нижнем правом углу и начинайте всё по новой.
Если нужные значения не ищутся, или после редактирования значения сбрасываются, значит данную игру так не взломать. Если приложение вылетает со включенным/вшитым iGameGod и у вас есть джейлбрейк, можно попробовать GameGemiOS.
Вам нужно последовательно ввести в установленный ранее терминал три команды:
Чтобы ускорить этот процесс, запустите установленную ранее команду. Она трижды скопирует нужный текст и откроет приложение терминала, каждый раз вам нужно будет только вставить скопированный текст и вернуться в команды.
В процессе взлома нужно будет периодически открывать терминал, чтобы GameGemiOS работал и не зависал на загрузке.
Откройте взламываемое приложение, получите некоторое количество валюты и запомните его.
Откройте GameGemiOS, перейдите на вкладку "Scan" и нажмите на пустой значок
Выберите взламываемое приложение
Впишите нынешнее количество валюты и нажмите "Search"
Скорее всего, вариантов нашлось много. В таком случае перейдите во взламываемое приложение и измените количество валюты — потратьте её или приобретите.
Запомните новое количество валюты и снова откройте GameGemiOS.
Введите в поиск новое количество валюты и снова нажмите "Search".
Скорее всего результатов найдётся несколько (если их всё ещё много, повторите действия с изменением количества). Нажмите нижнюю левую кнопку.
Выберите все варианты и нажмите "Modify"
Введите нужное значение и нажмите "Confirm"
Если число валюты в игре не изменилось, снова потратьте или получите её, после этого изменения должны закрепиться.
Чтобы накрутить другой показатель, нажмите "Reset" и начинайте всё по-новой
Если нужные значения не ищутся, или после редактирования значения сбрасываются, значит данную игру так не взломать.
Подмена ответа от сервера проверки чека
Плюсы: срабатывает часто, не требует джейлбрейка, не требует компьютера
Минусы: часто взлом не сохраняется в кэш, для его работы необходимо дополнительное платное приложение со включенным vpn, труден для неопытных пользователей, для самостоятельного взлома обычно необходим активный пробный период подписки / легально выполненная разовая покупка
Вот мы и подошли к самой интересной части, к чему-то новому для русскоязычного сообщества, чем раньше пользовались лишь китайцы, о чём раньше вы могли слышать лишь мельком. Это единственный способ в равной степени удобный и с наличием джейлбрейка и без него, а так же способный "взять" наибольшее число приложений из всех рассмотренных здесь. Да, он непрост, но и не так сложен, как может показаться, и автор данной статьи уверен, что рано или поздно разобраться смогут многие. Вашему покорному слуге не удалось найти никаких инструкций по его применению в свободном доступе, а значит перед этой статьёй встаёт ответственная задача впервые изложить его, в полной мере и как насколько возможно доходчиво. Будем надеяться, у неё это получится.
Принцип работы
Вспомним теорию. Когда приложение получает чек, оно может отправить его для расшифровки на сервер. Сервер возвращает данные, содержащиеся в чеке. Если в нём не прописаны покупки, сервер так и "скажет". Однако мы можем перехватить его ответ и подменить, дописав то, что захотим. Если допишем наличие выполненных покупок, приложение будет думать, что так и есть на самом деле.
Такой вид атаки называется MiTM — Man in The Middle (человек посередине), что обозначает хакера, перехватывающего информацию, передающуюся между сервером к устройством и изменяющего её. Подробнее можно узнать на википедии.
Инструменты
Чтобы перезватить запросы и ответы — трафик приложения, необходимы специальные приложения. Для перехвата они устанавливают свой профиль vpn, через который проходят все запросы, а также корневой сертификат, чтобы трафик расшифровывать.
Некоторые приложения для просмотра и изменения трафика:
- Stash.
- Loon. Не покупайте на общих аккаунтах! Перестанет работать через некоторое время, так как на одном аккаунте может быть не больше 5 устройств.
- Quantumult X. Не покупайте на общих аккаунтах! Не будет работать, так как общие аккаунты добавляют в "семьи", и Quantmult X будет куплен не на сам аккаунт, который вам выдают, а на аккаунт из одной с ним семьи. Вам предлагают скачать его через семейные покупки, а QX будет работать только будучи скаченным непосредственно с apple id, с которого его купили. Кроме того, на одном аккаунте может быть не более 3 устройств.
- Surge. Для джейлбрейка есть взлом твиком для версии 5.5.0.
- Egern. Есть открытое бета-тестирование, но обычно заполнено.
- Spider Proxy. Для редактирования не рекомендуется.
- Hodor.
- Proxyman. Единственное приложение, котрое позволяет изменять ответы не скриптами, а редактировать руками, вручную всё дописывая и отправляя ответ. Этот функционал доступен даже в бесплатной версии, хоть и для одного запроса.
- HTTPS Traffic.
- Storm Sniffer.
- Traffic Capture.
- iHTTP Tracker.
- HTTP Capture.
- Charles. Можно получить бесплатно на общем аккаунте.
- MQTT Loupe. Бесплатный
- WebProxyTool. Бесплатный
- Shadowrocket. Есть и работает на общих аккаунтах (бесплатно здесь, платно здесь, здесь или здесь).
- LanceX.
Взломанные ipa некоторых из данных приложений доступны для установки через Troll Store здесь
При покупке доступа к каналу со скриптами M[i]TM[OS] вы получаете наш общий аккаунт с рабочим Loon в бете и Shadowrocket, к которым вы будете иметь постоянный доступ, а значит сможете бесплатно обновлять и переустанавливать эти приложения.
В данной статье будут рассмотрены Loon и Shadowrocket.
Настройка инструментов
Найдите секцию "Certificate Management" и перейдите в неё.
Нажмите "Generate A New CA Certificate".
Нажмите "Install CA Certificate To System".
Откройте приложение "Настройки"
Загруженный профиль будет висеть на главной странице. Откройте его.
Нажмите "Установить" ещё два раза
В настройках перейдите по пути "Основные" → "Об этом устройстве" → Доверие сертификатам"
Включите доверие сертификату Loon.
Введите домен "buy.itunes.apple.com". Это домен проверки чека от Apple, и он нужен для дешифровки соответствующего запроса.
Перейдите на вкладку "Dashboard"
Здесь можно добавить или убрать ярлыки главного меню. Ниже показаны ярлыки, которые могут понадобиться. Обязательно должны присутствовать ярлыки "Captured Session" и "Requests".
Активируйте "Captured Sessions" нажатием на серый кружок.
Перейдите на вкладку "Настройки".
Выберите "English", английский. Без этого шага не всё будет работать из-за бага.
Откройте раздел "HTTPS Decryption".
Включите раздел "HTTPS Decryption".
Нажмите "Generate A New CA Certificate" дважды
Нажмите "Install CA Certificate to System".
Установите сертификат и включите ему доверие, как в случае с Loon.
Отслеживание запросов и просмотр ответов
Как мы помним, приложение посылает чек на сервер, а сервер расшифровывает его и возвращает информацию о покупках. Сейчас при помощи Loon мы вмешаемся в этот процесс и посмотрим, какие же данные возвращает сервер приложению.
Для примера возьмём Adguard как приложение с очень простым ответом от сервера. Установите его.
Запустите Adguard. Может понадобиться дойти до покупки и нажать "Восстановить".
Откройте Loon и перейдите в раздел "Requests". Тут мы видим разнообразные запросы, которые приложение посылает к серверу. Например, при помощи запросов на домен filters.adtidy.org, оно загружает списки рекламы для блокировки.
Loon можно выключить.
Где-то среди этих запросов затерялся запрос на проверку чека для восстановления возможной покупки, и наша задача его найти. Надо искать запрос на адрес, содержащий что-то типа purchase, receipt, validate, verify.
Вот он, нашёлся: https://mobile-api.adguard.org/api/2.0/ios_validate_receipt/ADG_EXT.
Во вкладке General общая информация о запросе: статус завершения, время соединения, объём переданных данных и так далее.
Во вкладке Request информация непосредственно о запросе, об обращении к серверу.
В заголовках (REQUEST HEADER) передаётся базовая информация.
В теле (REQUEST BODY) передаётся то, ради чего создавался запрос: чек
Нашему взору открывается словарь (json) с закодированным в base64 для передачи в текстовом виде файлом чека. Мы опознаём его по его ключу — receipt_data. Раз в запросе передаётся чек, значит это тот запрос, который нам нужен.
Перейдите во вкладку Response.
Здесь также можно увидеть заголовки и тело. Ответ о подписке передаётся в теле.
Откройте тело ответа, нажав на "JSON Viewer".
Перед нами открывается пустое тело. А что вы хотели? Подписка не выполнена, потому и ответ о ней пустой.
Чтобы увидеть, как должен выглядеть ответ при наличии подписки, необходимо оформить пробный период в Adguard.
После этого переустановите Adguard, чтобы сбросились данные о подписке, повторите действия с отслеживанием запросов, найдите нужный и перейдите во вкладку "Response".
Можно наблюдать ответ об активной подписке:
{ "products": [ { "premium_status": "ACTIVE", "product_id": "com.adguard.monthly", "expiration_date": 1689343002000 } ] }
Данные в формате json, давайте разберём, за что отвечает каждое из значений.
premium_state означает состояние премиума. ACTIVE — активен и FREE — неактивен.
product_id — идентификатор конкретной совершённой покупки. В нашем случае com.adguard.monthly — идентификатор месячной подписки. Если вы активировали годовую подписку, будет com.adguard.annualy
expiration_date — время истечения подписки. Но, кажется, что здесь не дата, а набор цифр; на самом деле она просто в формате unix. В человеческий вид её можно сконвертировать на многочисленных сайтах. Например, на этом (при конвертировании убирайте три последних нуля). 1689343002000 = 14.07.2023 13:56:42.
У разных приложений приложений могут быть разные ответы, но, руководствуясь рассуждениями выше, старайтесь их разгадать и выделить важные значения.
Создание скриптов
После того, как мы отследили и разобрали ответ, он, кажется, как на ладони, и руки чешутся поскорее изменить одно-два значения и получить заветный премиум. Однако всё не так просто. Дело в том, что для изменения ответа необходимо ознакомиться с таким понятием, как скрипты.
В подобных Loon программах для изменения ответа используются специальные алгоритмы действий на языке java script. Конечно, в идеале, следовало бы вплотную изучить джава скрипт, однако для написания большинства скриптов для изменения ответа достаточно азов, а их мы разберём здесь и сейчас.
Каждый скрипт имеет начало и конец. В начале скрипт должен получить тело, которое он будет редактировать, а в конце отдать его для последующей передачи целевому приложению.
Тело ответа получается переменной "$response.body
".
Чтобы тело можно было редактировать, его необходимо декодировать. Для этого используется функция "JSON.parse
". "JSON.parse($response.body)
" — декодирование тела ответа.
После того, как мы получили и декодировали тело, нужно его сохранить для дальнейшего редактирования. Сохраним его в переменную "body
". Переменная задаётся через функцию "let
". "let body = JSON.parse($response.body)
" — задаём для переменной "body
" значение декодированного тела.
Это и есть начало.
В конце изменённый ответ надо закодировать обратно и отдать для дальнейшей передачи взламываемому приложению. Функция "JSON.stringify
" кодирует ответ. "JSON.stringify(body)
" — кодирование содержимого переменной "body
".
Чтобы передать результат далее, необходимо заменить им содержимое тела ответа до изменения. Новое значение тела задаётся функцией "{body: ...}
". "{body: JSON.stringify(body)}
" — меняем содержимое тела на закодированное значение переменной "body
".
Теперь надо закончить выполнение скрипта. Для этого используем функцию "$done
". "$done({body: JSON.stringify(body)})
" — конец выполнения скрипта с заменой содержимого тела на закодированное значение переменной "body
".
- задаёт для переменной "body" значение декодированного тела,
- заменяет содержимое тела на закодированное значение переменной "
body
".
let body = JSON.parse($response.body) $done({body: JSON.stringify(body)})
Инными словами берётся значение тела и снова задётся этому телу. То есть по итогу ничего не меняется.
Перейдём к самому главному — собственно изменению ответа скриптом.
Как уже было сказано, обычно ответ в формате json. Поэтому потребуется знание структуры json, и тут уже не отвертеться: как было рекомендовано в начале статьи, придётся ознакомиться самому.
Самый простой способ редактирования тела ответа заключается в полной его замене. Мы пишем "body = ...
", вместо многоточия вписывая свой, заранее изменённый словарь. Вернёмся к Adguard. Выше мы получили словарь из ответа о подписке, истекающей в 13:56:42 14.07.2023. Предлагаю изменить дату её окончания на 31.12.2099 23:59:59. Конвертируем эту дату в unix формат, получая 4102444799, и добавляем 000. Зададим переменной "body
" значение нового словаря:
body = { "products" : [ { "premium_status" : "ACTIVE", "product_id" : "com.adguard.monthly", "expiration_date" : 4102444799000 } ] }
Остаётся только добавить "начало" и "конец", и скрипт готов:
let body = JSON.parse($response.body); body = { "products" : [ { "premium_status" : "ACTIVE", "product_id" : "com.adguard.monthly", "expiration_date" : 4102444799000 } ] } $done({body: JSON.stringify(body)});
Рассмотрим на примере Adguard более тонкий метод, точечную замену значения без перезаписывания всего тела. В данном случае — это значение даты с ключом "expiration_date". Чтобы заменить его, к нему надо прописать путь. Посмотрим на словарь, где лежит эта пара ключ-значение? В словаре вложен массив под названием "products", значит первый объект в пути — products. Объекты в пути разделяются точками. Строим путь, начиная с названия переменной, получается "body.products.
". В массиве products один объект — ещё один словарь. Так как это массив, у того словаря нет ключа, а значит нам надо указать его номер. Номер указывается так: products[0] (products — ключ массива; нумерация начинается с нуля). Строим путь дальше: " body.products[0].
". В словаре в массиве products три ключа. Нас интересует "expiration_date". Заканчиваем путь: "body.products[0].expiration_date
". Теперь задаём новое значение: "body.products[0].expiration_date = 4102444799000
". Весь скрипт будет выглядеть так:
let body = JSON.parse($response.body); body.products[0].expiration_date = 4102444799000 $done({body: JSON.stringify(body)});
В случае Adguard такой метод излишен, ведь, как мы помним, без пробного периода тела ответа пустое. А значит весь этот путь не имеет смысла, и сработает, только если оформлен пробный период и тела ответа содержит информацию о пробном периоде. Первый способ заменяет тело полностью, поэтому может работать и с пустым содержимым. Этот метод подходит в случаях, когда помимо информации о лицензии через этот запрос передаётся какая-либо другая важная меняющаяся информация, или время отправки запроса, замена которого на фиксированное значение сигнализирует приложению о подмене.
Например, взглянем на ответ от Simpler:
{ "id": 5139330, "level_id": 1, "name": "", "provider": 4, "is_purchased": 0, "active_days_cnt": 0, "reached_achievements": [], "last_active_at": "", "notification_at": "", "league_unlock_at": null, "gift_premium_till": "", "last_active_timezone": "UTC", "created_at": "2023-03-14 18:11:23", "image": "", "updated_at": "2023-03-14 18:11:24", "purchased_till": "", "email": "", "gift_premium": 0 }
И электронная почта, и уровень, и чего здесь только не передаётся. Нас интересуют только два ключа: "is_purchased" и "purchased_till". Можем заменить только их:
let body = JSON.parse($response.body); body.is_purchased = 1 body.purchased_till = "2099-12-31 23:59:59" $done({body: JSON.stringify(body)});
В ещё более редких случаях требуется заменить множество одинаковых значений и прописывать путь до каждого слишком долго. Например этот случай — ответ от сервера для проверки apple buy.itunes.apple, который настолько длинный, что приводить его здесь излишне. Тогда можно использовать регулярные выражения. Регулярные выражения позволяют находить и заменять одинаковые ключи и значения или по заданному шаблону одним действием без прописывания пути к каждому. Здесь тоже придётся заняться самоподготовкой, однако базовый приём я всё же покажу. Нам потребуется новая функция "replace()
". "replace(/\"Ключ\":\".+?\"/g, "\"Ключ\":\"Новое значение\""))
" заменит все значения с заданным ключом на новые. Снова вернёмся к Adguard: нам нужно заменить пару ключ-значение «"expiration_date" : 4102444799000
», значит полная функция будет выглядеть "replace(/\"expiration_date\":\".+?\"/g, "\"expiration_date\":\"4102444799000\""))
". В скрипте:
let body = JSON.parse($response.body); body = JSON.parse(JSON.stringify(body).replace(/\"expiration_date\":\".+?\"/g, "\"expiration_date\":\"4102444799000\"")) $done({body: JSON.stringify(body)});
Порой приложения используют не свой сервер для проверки чека, а, как было сказано, сервер Apple, или сервера специальных компаний, специализирующихся на этом. RevenueCat, AppHud, Qonversion и другие. Для некоторых из них можно сделать универсальный скрипт, срабатывающий на всех приложениях с их проверкой.
Применение скриптов
Откройте раздел "Local JavaScript Files".
Нажмите на "Create empty script"
Введите любое название скрипта.
Скопируйте url-адрес, на который шёл запрос.
В "Script Type" выберите "http-response".
В "Script Location" выберите "Local"
Выберите скрипт, который только что создавали.
В "Expression" вставьте ссылку, на которую шёл запрос. Здесь снова может понадобиться знание регулярных выражений, если запрос о проверке идёт сразу на несколько адресов, возвращающих одинаковые ответы. Если адреса изменяются небольшими фрагментами, возьмите их в круглые скобки и перечислите через "|". Например, выражение "https://api.revenuecat.com/v1/(receipts|subscribers)" охватывает два адреса: "https://api.revenuecat.com/v1/receipts" и "https://api.revenuecat.com/v1/subscribers". "." означает любой символ, ".*" — любое количество любых символов.
Скопируйте домен вставленной ссылки.
Подписка активировалась. Иногда это происходит сразу, иногда нужно нажать "восстановить покупки".
Возвращаемся в Adguard и снова находим наш запрос. Видим зелёный значок скрипта на нём — верный признак того, что скрипт сработал.
Можем увидеть логи скрипта, оригинальное и изменённое тело ответа для сравнения.
Adguard достаточно один раз запустить со включенной заменой, подписка сохраняется в кэш и её можно перенести вместе с кэшем. Однако многие приложения проверяют подписку каждый раз и вруную включать Loon перед каждым запуском не удобно. Решение есть — в таком случае можно настроить автоматизацию на запуск.
Откройте приложение "Команды" на вкладке "Автоматизация"
Нажмите "Создать автоматизацию для себя"
Найдите и выберите автоматизацию "Приложение".
Выберите взламываемое приложение.
Вбейте в поиск по действиям "Настроить vpn" и выберите соответствующее действие.
В действие нажмите на поле "VPN" и выберите Loon.
Выключите "Спрашивать до запуска".
Теперь при открытии приложения Loon будет включаться автоматически. Не забудьте только отключать "Captured Session" во избежании повышенного расхода батареи.
Аналогично можно сделать автоматизацию на выключение Loon по закрытию приложения.
Но что делать, если ваша iOS ниже 16.4.0 и действия по настройке VPN нету? Тут в дело вступает Shadowrocket.
Введите любое название скрипта.
Нажмите на "i" напротив "Script Path"
В "Pattern" вставьте ссылку, на которую шёл запрос или регулярное выражение, как в Loon.
Откройте раздел "HTTPS Decryption".
Начните создавать автоматизацию, как с Loon.
При создании вбейте в поиск по действиям "Start Shadowrocket". Как мы можем наблюдать, у Shadowrocket есть своё собственное действие для включения (и выключения — "Stop Shadowrocket"), поэтому его можно использовать аж начиная с iOS 13 с появления автоматизаций.
Закончив чтение этого раздела, вы имеете представление о взломе через подмену ответа. Да, это не просто, однако, прочитав ещё несколько раз, попробовав сами, рано или поздно вы разберётесь. Главное — стремиться не сдаваться. У меня вот не было такой прекрасной статьи, и ничего, разобрался. Получить консультацию и ответы на вопросы от автора статьи или обсудить прочитанное с единомышленниками вы можете в чате канала M[i]TM[OS], приобретя к нему доступ.
Перенос кэша
Наконец мы подошли к финальной и самой части. Если после всех вышеописанных действий покупки не сбрасываются, значит они сохранились в кэш, и можно попробовать перенести их на другое устройство. Однако это отдельная большая история, нашедшая место в своей персональной статье.
А на этом всё, ставьте лайки, подписывайтесь на канал, оставляйте комментарии!
Отдельное спасибо t.me/el_zari за посвящение в подмену запросов! Без него не было бы самого значимого метода этой статьи. Спасибо также t.me/Mortem_off и t.me/yarmukhamedov за помощь в освоении этого метода.