Как стать автором
Обновить

Комментарии 9

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

хороший вопрос. Кажется, что это возможно. Я не нашел информации, где именно сохраняется ключ, но подозреваю что в кейчейне, который можно сдампить.

Спасибо, очень интересно) А если сделать jailbreak и отключить ssl pining, ваш ключ для расшифровки будет виден в трафике ?

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

https://github.com/pjebs/Obfuscator-iOS 

https://github.com/UrbanApps/UAObfuscatedString

дешифруем модель, релизим из памяти ключ, разархивируем модель и сохраняем во временную папку, например:  NSTemporaryDirectory()/YourFolder/

Вот тут всё ваше шифрование модели разом потеряло смысл, так как на джейлбрейктнутом девайсе достаточно поднять что-то типа inotify на временную папку с коллбэком который будет тут же открывать и оставлять открытыми все появляющиеся во временной директории файлы (чтобы последующее их удаление не помешало прочесть файлы через уже открытые дескрипторы).

Ну или просто запустить ваше приложение под чем-то типа strace и оттрассировать все вызовыopen() и write() а затем отфильтровать их по пути, получив только вызовы связанные с временной директорией, а затем повторить их и получить полностью дубликат вашей временной директории с расшифрованной моделью.

Инициализируем модель и загружаем ее в память c помощью init метода MLModel

Ещё одно место которое можно немножко попячить (к примеру вставив в init что-то типа sleep(10000) или заменить вызов init на exit() и спокойненько вычитать за время сна (или после завершения приложения) всю временную директорию с расшифрованной моделью.

Удаляем временную папку.

Или просто заменить все вызовы удаления файлов на nop - первый же запуск приложения и временная директория с расшифрованной моделью останется.

То есть, предложенные методы защищают только от статического анализа, и полностью бессильны против динамического анализа (как активного, с модификацией кода приложения или OS, так и пассивного, просто наблюдая за работой приложения без его модификации).

таким не доводилось заниматься, интересные замечания, плюсанул карму, спасибо! Раз уж затронули тему, а есть мысли, как можно усложнить жизнь против динамического анализа?

а есть мысли, как можно усложнить жизнь против динамического анализа?

Есть немножко. Но не против всех атак.

Или просто заменить все вызовы удаления файлов на nop - первый же запуск приложения и временная директория с расшифрованной моделью останется.

Если защищаемся от ламеров - вот тут можно добавить что-то типа изменения размера файла (truncate) на 0 сразу после инициализации модели - в этом случае атакующий получит кучку пустых файлов.

Как противодействовать другим методам анализа - хз, так как они проводятся вне скоупа приложения, и требуют поддержки от MLModel в плане загрузки предварительно зашифрованной модели.

Использование временной директории + вызов MLModel.init явно является тупиковым путём тут, так как позволяет перехватить расшифрованные данные при любом сценарии работы.

Единственным возможным путём полной защиты модели в данном случае я вижу предварительную генерацию ключевой пары в TZ (приватный ключ никогда не покидает TZ), пересылку публичного ключа на сервер, после чего сервер шифрует модель полученным публичным ключом и отсылает обратно, затем происходит скармливание зашифрованных данных модели в TZ с объяснением какие именно данные (ID ключа) надо расшифровать, и TZ расшифрует модель и сохранит её внутри защищённой памяти, после чего MLModel должен будет как-то аутентифицироваться в TZ и затем авторизоваться в TZ что он может получить доступ к конкретной модели, после чего TZ отдаст ему модель (и вот тут как раз таки её можно будет поймать, так что MLModel должно будет работать в TZ полностью, но это увеличивает поверхность атаки на саму TZ).

TZ - TrustZone, или как там оно называется в iOS (не трогал её - не знаю терминов).

Далее нам нужно зашифровать наш файл. Для этого можно использовать популярный sha256 либо любой другой алгоритм.

Шифровать алгоритмом хэширования файл конечно можно, но будет очень-очень-очень трудно его расшифровать потом.

Может всё-таки лучше для шифрования выбрать что-то вроде AES256?

Шифровать алгоритмом хэширования файл конечно можно, но будет очень-очень-очень трудно его расшифровать потом.

ох боюсь человечество раньше закончится. Пофиксил, спасибо!

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории