Для того чтобы понять причины уязвимости iPhone, вначале рассмотрим некоторые типичные приемы, которыми пользуются разработчики вредоносных приложений. Проведем разбор одной из наиболее распространенных атак путем переполнении буфера. Именно этот подход применяют разработчики вирусов для iPhone чаще всего.

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

Память устройства — это набор ячеек, в которые может быть записана информация размером, например, 1 байт. Ячейки имеют последовательные номера. Вся память делится на разделы, каждый из которых имеет собственную структуру и порядок обращения к ячейкам. Нас в этой связи интересуют три структуры: собственно память, где хранятся данные, буфер и стек.

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

Стек — это такая структура памяти, куда данные помещаются последовательно друг за другом. При этом приложение может получить быстрый доступ к последнему помещенному в стек значению. Чтобы извлечь предпоследнее значение, необходимо прежде извлечь последнее значение, записанное в стек. Для помещения значения в стек обычно используется инструкция PUSH, а для извлечения инструкция POP.

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

Адрес функции — это указатель на место в памяти, где расположен код функции.

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

До выполнения внутренней функции стек пустой [1]. Во время вызова внутренней функции в стеке хранится адрес возврата во внешнюю функцию [2]. В нашем случае — 0x00638. После выполнения внутренней функции из стека извлекается адрес внешней функции и осуществляется переход к исполнению команд по адресу 0x00638. Стек оказывается пустым [3].Содержание стека во время функционирования программы

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

Этим и пользуются программисты. В таком случае структура стека выглядит следующим образом.Содержание стека во время функционирования программы при использовании стека для хранения временных переменных

Как видно из рисунка, во время выполнения функции программист использует стек для временного хранения данных. В нашем случае это введенное пользователем имя. Данные временно помещаются в стек во время выполнения внутренней функции и извлекаются после [3].

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

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

Поясним, как переходит изменение хода выполнения программы. Предположим, пользователь скачал из Интернета официальное приложение Apple. Причем цензоры компании не увидели то, что в приложении нет проверки на длину вводимых пользователем данных. То есть, программа имеет потенциальную уязвимость переполнения буфера. Как мы помним, все запущенные приложения на iPhone выполняются с правами администратора.

Далее злоумышленник вводит в окно некоторые данные. Причем они имеют большую длину и имеют примерно следующий формат.

AAAAAAAAAAAAAA0x619300610efa2380aacdl089aabcdl028abd458eefl

Сначала идет информация, которая переполняет буфер (АААААААААААААААА), потом адрес некоторой ячейки памяти (0x6193 006), а далее команды вируса в бинарном виде (10efa2 3 80aacd 1089а abcdl028abd458eefl). Такие команды, если на них передать управление, приведут к выполнению вирусного кода. А так как проверки на длину вводимых данных нет, то подобных команд может быть много, а значит и вирус может быть весьма серьезным. Обычно такой вирус отправляет по Wi-Fi соединению все данные пользователя злоумышленнику. Хотя хакер с выгодой для себя может найти и другие возможности воспользоваться описанной уязвимостью.

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

Он также знает адрес стека и адрес той ячейки памяти стека, куда помещается содержимое буфера. Содержание стека при переполнении буфера

На рисунке выше показано, что происходит с памятью программы при переполнении буфера.

На рисунке приведена типичная ситуация переполнения буфера, когда объем данных оказался настолько велик, что фактически переполнил буфер, выделенный под локальные переменные. В данном случае это последовательность букв «А». Более того, избыточные данные затерли адрес возврата и заменили его на адрес следующей ячейки стека. Таким образом, при попытке выхода из функции программа с правами администратора передаст управление вирусу. То есть вирус получит права администратора.