11.06.2014

Безопасность IOS-приложений (часть 28) – Патчинг приложений при помощи Hopper

image

В этой статье мы рассмотрим утилиту Hopper как более дешевую альтернативу IDA Pro.  

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

В двадцать шестой статье мы рассматривали утилиты IDA Pro и Hex Fiend, которые использовались для модификации бинарных файлов IOS-приложений. У патчинга есть неоспоримое преимущество (по сравнению с техникой method swizzling): не нужно выполнять его постоянно при каждом запуске приложения, а достаточно выполнить эту процедуру один раз. Однако для выполнения простейших манипуляций в IDA Pro нам приходилось делать много телодвижений (в основном из-за того, что мы пользовались демо версией). В этой статье мы рассмотрим утилиту Hopper как более дешевую альтернативу IDA Pro.

Вот что написано на сайте Hopperapp.com:

Hopper – утилита для реверс-инжиниринга под OS X, Linux и Windows, которая позволяет дизассемблировать, декомпилировать и отлаживать (доступно только для OS X) исполняемые файлы операционных систем 32/64bits Intel Mac, Windows и iOS (ARM).

Несмотря на то, что Hopper умеет дизассемблировать, по сути, любые исполняемые файлы, главная его специализация – получение полной информации о приложениях, написанных на Objective-C (селекторы, строки, сообщения и т. д.)

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

Рисунок 1: Внешний вид Hopper

Здесь мы также будем работать с тестовым приложением GDB-Demo, которое вы можете загрузить с моего аккаунта на github. Настоятельно рекомендую ознакомиться вам с двадцать шестой статьей этой серии. В качестве напоминания: приложение GDB-Demo представляет собой форму авторизации и выглядит так:

Рисунок 2: Внешний вид приложения GDB-Demo

Чтобы пройти процесс авторизации, необходимо ввести корректное имя пользователя и пароль. Наша задача сделать так, чтобы процесс авторизации заканчивался успешно вне зависимости от введенной информации на форме. Мы будем отлаживать и патчить приложение, скомпилированное под архитектуру x86, на ноутбуке, хотя вы можете сделать то же самое и для исполняемых файлов для ARM.

После загрузки приложения запустим его при помощи Xcode, после нам необходимо найти папку с программой. Симулятор Xcode создает подобные папки в директории /Users/$username/Library/Application Support/iPhone Simulator/$ios version of simulator/Applications/. В моем случае это директория /Users/Prateek/Library/Application Support/iPhone Simulator 6.1/Applications/. Зайдите в эту директорию и введите команду lsal, после чего появится список папок с датой последнего их изменения. Папка с самой крайней датой изменения и будет папкой с нужным нам приложением.

Рисунок 3: Перечень папок с датой последнего изменения

Далее используйте команду open DirectoryName, чтобы открыть директорию в приложении Finder.

Рисунок 4: Содержимое папки приложения GDB-Demo

Кликните правой кнопкой мыши на директории GDB-Demo.app (это пакет приложения) и выберите Show Package contents. Внутри этой папки вы найдете бинарный файл GDB-Demo, который мы будем патчить, используя Hopper.

Рисунок 5: Содержимое пакета приложения GDB-Demo

Теперь откройте Hopper и выберите пункт меню File->Read Executable To Disassemble, а затем укажите путь к бинарному файлу. Также не забудьте закрыть приложение в Xcode, но оставьте симулятор открытым.

После этого Hopper начнет дизассемблировать приложение.

Рисунок 6: Результаты дизассемблирования

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

Рисунок 7: Строковые константы, полученные из исполняемого файла

Если вы выберете раздел Labels, то увидите все методы, константы, классы и т. д.

Рисунок 8: Перечень всех методов, констант и классов приложения

Нам нужно найти метод loginButtonTapped, который, как вы помните, отвечает за процесс авторизации. Наберите слово «loginButtonTapped» в поисковой строке. Как только метод найден, необходимо кликнуть по нему, чтобы увидеть дизассемблированную версию.

Рисунок 9: Дизассемблированный метод loginButtonTapped

Одна из самых полезных функций Hopper – возможность увидеть псевдокод функции. Чтобы увидеть псевдокод, необходимо кликнуть на иконку Pseudo Code в правом верхнем углу.

Рисунок 10: Иконка Pseudo Code

Как видно из рисунка ниже, Hopper показал псевдокод функции.

Рисунок 11: Псевдокод метода loginButtonTapped

Это очень полезная возможность, значительно ускоряющая знакомство с логикой работы метода. В данном случае метод возвращает пароль. Еще одна прекрасная возможность Hopper – функция Show CFG, которая позволяет увидеть блок-схему приложения. Кликните на иконку Show CFG, находящуюся слева от иконки Pseudo code.

Рисунок 12: Блок-схема приложения

Если мы прокрутим чуть ниже, то увидим в левой ветке текст Incorrect Username or Password, а в правой - admin page. Наша задача - сделать так, чтобы выполнение всегда шло по правой ветке.

Рисунок 13: В зависимости от введенных данных, приложение идет под одной из веток

Теперь нам нужно найти проверку, после которой алгоритм решает, по какой ветке идти. Как видно из рисунка ниже, это инструкция test cl, 0x1. Если нулевой флаг не заполнен, алгоритм идет по правой ветке (инструкция jne 0xcbc).

Рисунок 14: Здесь решается, по какой ветке алгоритм будет работать дальше

Метка 0x2cbc связана с правой веткой. Если мы изменим инструкцию так, чтобы алгоритм всегда шел по правой ветке, наша задача будут решена.

Рисунок 15: Метка 0x2cbc связана с отображением страницы администратора

Решение задачи довольно простое: нам необходимо поменять инструкцию jne 0xcbc на jmp 0xcbc. Для этого необходимо кликнуть на Modify->Assemble instruction.

Рисунок 16: Для изменения инструкции выбираем соответствующий пункт меню

Далее мы указываем нужную инструкцию и кликаем на Assemble and Go Next.

Рисунок 17: Изменяем нужную инструкцию

Теперь сохраняем все изменения и заменяем предыдущий исполняемый файл. Выберите Go to File -> Produce New, а затем замените предыдущий бинарный файл.

Рисунок 18: Создаем новый исполняемый файл

Далее закройте в симуляторе все работающие экземпляры GDB-Demo и запустите приложение вновь. Нажав на кнопку Login, вы увидите, что процесс авторизации прошел успешно.

Рисунок 19: Успешное завершение процесса авторизации

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

В следующей статье мы рассмотрим уязвимости в алгоритмах шифрования. 

или введите имя

CAPTCHA