Безопасность IOS-приложений (часть 23) – Как защититься от отладки приложений

Безопасность IOS-приложений (часть 23) – Как защититься от отладки приложений

В предыдущих статьях мы познакомились с отладчиками и утилитами наподобие Cycript, которые использовались для динамического анализа и манипуляций с IOS-приложениями. Мы рассматривали изменение логики работы методов во время выполнения приложения посредством изменения значений в регистрах, используя GDB, а также использовали технику method swizzling при помощи Cycript и ему подобными утилитами.

Автор: Пратик Джианчандани (Prateek Gianchandani)

В предыдущих статьях мы познакомились с отладчиками и утилитами наподобие Cycript, которые использовались для динамического анализа и манипуляций с IOS-приложениями. Мы рассматривали изменение логики работы методов во время выполнения приложения посредством изменения значений в регистрах, используя GDB, а также использовали технику method swizzling при помощи Cycript и ему подобными утилитами. При помощи этих утилит и копии бинарного файла приложения, злоумышленник, по сути, получает полный контроль над программой. Однако существуют определенные техники, которые может использовать разработчик, чтобы заметно затруднить жизнь хакера. В этой статье мы как раз и рассмотрим подобные техники, которые помогают защитить приложения от динамического анализа и манипуляций.

В Xcode существуют определенные проверки на предмет того, отлаживается приложение или нет. Следующий кусок кода как раз выполняет подобную проверку.

#ifndef DEBUG
SEC_IS_BEING_DEBUGGED_RETURN_NIL();
#endif

Как следует из имени, макрос возвращает константу nil, если приложение отлаживается. Вы можете вставить эту проверку в самые важные места вашей программы, где, по вашему мнению, осуществляется доступ к важным данным, или же важную информацию возвращает какая-либо функция. Если в этот момент приложение отлаживается, макрос вернет nil, и ваше приложение изменит логику работы, что затруднит задачу злоумышленнику. Вы также можете просто вызывать этот макрос по таймеру, и в случае отладки приложения, удалять важную информацию, файлы и так далее. Однако следует учитывать, что злоумышленник может изменить реализацию вашего метода и, следовательно, крайне желательно использовать отдельный макрос вместо использования этого макроса внутри метода. Обратите внимание, что макрос работает только в режиме Release Mode. Чтобы протестировать работу макроса, необходимо установить режим Release Mode в вашем билде. Для этого выберите вашу схему и кликните на Edit Scheme.

Рисунок 1: Редактирование схемы

Теперь во вкладке Info установите значение Release в параметре Build Configuration.

Рисунок 2: Выставляем режим Release

Теперь если вы запустите это приложение на вашем устройстве, используя Xcode, то увидите, что проверка на присутствие отладчика сработала. Такое произошло потому, что Xcode подцепляет отладчик, во время запуска приложения.

Однако следует оговориться еще раз о том, что подобная проверка не гарантирует полной защиты от отладки. Опытный злоумышленник может легко изменить все ассемблерные инструкции в бинарном файле, имеющие отношение к этому макросу. Вы лишь можете затруднить жизнь взломщику, если разместите подобные проверки во множестве мест своего кода.

Еще один метод защиты от отладчика – использование функции ptrace со специальным параметром, который запрещается подсоединения отладчика к вашему приложению. Функция ptrace используется многими отладчиками (например, GDB или LLDB) для подсоединения к процессу. Если использовать параметр PT_DENY_ATTACH, функция не разрешит отлаживать приложение. Ниже приводится скриншот из документации Apple с детальным описанием параметра PT_DENY_ATTACH.

Рисунок 3: Описание параметра PT_DENY_ATTACH

Давайте испробуем этот способ на практике. Создайте новый проект в Xcode, кликнув на Click File->New->Project->Single View Application. Затем, запустив проект в симуляторе, вы увидите чистое представление (view).

Рисунок 4: Тестовое приложение

Теперь в функцию main в файле main.m нужно добавить импорт файла ptrace.h и следующий кусок кода:

#ifndef DEBUG
ptrace(PT_DENY_ATTACH, 0, 0, 0);
#endif

Ваш файл main.m должен выглядеть так:

Рисунок 5: Обновленный файл main.m

Теперь, если вы попытаетесь запустить приложение, то у вас ничего не получится, поскольку при запуске проекта Xcode пытается подцепить отладчик (LLDB или GDB) к приложению. Из-за изменений в файле main.m отладка приложения запрещена, и оно сразу же завершает свою работу.

Чтобы убедиться, что все происходит именно так, в симуляторе дважды кликните по кнопке home и завершите работу тестового приложения. Теперь, если вновь запустить приложение, то все пройдет успешно, поскольку запуск происходит не через Xcode, и к приложению не подсоединяется отладчик.

Естественно, этот метод также не гарантирует полную защиту от отладки. Опытный злоумышленник может легко заменить нужный участок кода бинарного файла, после того, как расшифрует его. Как и в предыдущем случае, вы можете вставить этот код во множестве мест, тем самым затруднив жизнь взломщику.

Важно отметить, что оба вышеупомянутых метода лишь защищают от отладчиков, и не защищают от утилит наподобие Cycript. В этом случае как разработчик вы лишь можете затруднить работу злоумышленника, например, посредством использования ложных методов, которые могут привлечь внимание. Например, метод с именем userDidLogin:(BOOL)didLogin; естественно привлечет внимание взломщика, и он попробует запустить его при помощи Cycript. При реализации этого метода вы можете запрограммировать удаление всей важной информации из приложения и, возможно, отправку отчет на сервер о том, что приложение взломано. Для банковских приложений можно добавить специальную проверку на предмет того, на джейлбрейковом устройстве оно запущено или нет. Если на джейлбрейковом, то выставляется запрет на доступ к серверу и удаляется вся важная локальная информация. Подробнее о том, как определить джейлбрейковое устройство или нет, мы поговорим в следующей статье. Есть еще один метод проверки, взломано приложение или нет. Если взломано, то выполняются все необходимые шаги, чтобы затруднить злоумышленнику получение информации из приложения. В этом вам поможет очень простой класс. Конечно, злоумышленник может изменить логику работы этого метода, так что старайтесь придумать имя, не вызывающее подозрение.

Также вы можете маскировать имена методов, которые отвечают за безопасность приложения. Например, метод, проверяющий, происходит ли отладка приложения, не следует называть как -(BOOL)isAppBeingDebugged, поскольку это имя, конечно же, привлечет внимание злоумышленника, и он изменит логику его работы. Хорошие имена могли бы быть, например, такими: -(BOOL)didChangeColor или -(BOOL)didSetFont.

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

exit(-1);

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

Не ждите, пока хакеры вас взломают - подпишитесь на наш канал и станьте неприступной крепостью!

Подписаться