Когда мы говорим о плагинах и модульных приложениях, то в первую очередь имеем в виду обычный пользовательский софт. Однако модульный дизайн может быть не менее полезен при разработке руткитов и бэкдоров. Обычными средствами обновлять такой софт слишком палевно, да и не всегда возможно, а вот незаметно подгрузить модуль с новой функциональностью по сети — это пожалуйста. А если вынести ключевую функциональность в модули и удалять их сразу после загрузки, то можно серьезно подпортить жизнь реверсеру.
В классической Java есть класс под названием java.lang.ClassLoader. Его задача — загружать байт-код указанного класса (файл с расширением .class) в виртуальную машину во время исполнения приложения. Затем можно создать объект этого класса и вызывать его методы с помощью рефлексии. Такой вот способ динамической загрузки кода, который можно использовать для написания приложений с расширяемой функциональностью, или, попросту говоря, поддержкой плагинов.
В Android нет виртуальной машины Java и нет класса ClassLoader, но есть его аналог DexClassLoader, выполняющий ровно ту же функцию, но в отношении байт-кода Dalvik (и файлов .dex вместо .class соответственно). И, в отличие от настольной Java, где проще положить нужный jar-файл в CLASSPATH и не возиться с динамической загрузкой, в Android такой подход дает действительно много преимуществ, главное из которых в том, что функциональность приложения можно расширять и обновлять незаметно для пользователя и ни о чем его не спрашивая. В любой момент твое приложение может скачать файл с классом с сервера, загрузить, а затем удалить файл.
[ad name=»Responbl»]
Кроме этого, классы можно хранить прямо в пакете APK и загружать во время старта приложения. Профит здесь в том, что код загружаемых классов будет отделен от кода самого приложения и находиться в APK «не по адресу»; инструменты типа apktool, которыми так любят пользоваться реверсеры, их просто не увидят. С другой стороны, это скорее защита от дурака, так как нормальный реверсер быстро смекнет, что к чему.
Как бы там ни было, динамическая загрузка классов — очень полезная штука при написании не совсем «белых» приложений, поэтому любой security-специалист должен знать, как этот механизм работает и как он используется в троянах.
Чтобы все написанное далее было проще понять, сразу приведу пример рабочего загрузчика классов:
В целом здесь все просто: код загружает jar-архив /sdcard/myapp/module. jar с нашим классом, загружает из него класс com.example.modules.simple. Module, создает объект и вызывает метод run(). Обрати внимание на три момента:
Чтобы проверить данный код на работоспособность, создадим простейший модуль:
Не торопись создавать новый проект в Android Studio, можешь накидать этот код в блокноте и собрать его в jar-архив прямо из командной строки:
javac -classpath /путь/до/SDK/platforms/android-23/android.jar Module.java
/путь/до/SDK/build-tools/23.0.3/dx --dex --output=module.jar Module.class
Удостоверься, что каталоги platforms/android-23 и build-tools/23.0.3 существуют, в твоем случае их имена могут отличаться.
[ad name=»Responbl»]
Если все пройдет гладко, на выходе ты получишь файл module.jar. Останется только добавить код загрузчика в приложение, положить module.jar на карту памяти, собрать и запустить приложение.
Рефлексия — хорошая штука, но в данном случае она только мешает. Один метод без аргументов с ее помощью вызвать нетрудно, однако, если мы хотим, чтобы наше приложение имело развитый API модулей с множеством методов, принимающих несколько параметров, нужно придумать что-то более удобное. Например, использовать заранее определенный интерфейс, который будет реализовывать каждый модуль.
Применив такой подход к приведенному выше примеру, мы получим следующие три файла:
Файл ModuleInterface.java с описанием API:
2. Файл Module.java с реализацией нашего модуля:
3.Новый загрузчик модуля (помести в свое приложение):
С одним модулем разобрались, но что, если их будет много? Как вести учет этих модулей и не потеряться среди них? На самом деле все просто — для этого можно использовать hashmap. Еще раз изменим загрузчик:
[ad name=»Responbl»]
Например, приведенный ранее модуль принадлежит пакету com.example. modules.simple (см. директиву package), поэтому его необходимо включить в jar-архив simple.jar (меняем —output=module.jar на —output=simple. jar в команде сборки). Когда придет время создать новый модуль (к примеру, remote_shell), первой строчкой в его исходниках ты укажешь package com. example.modules.remote_shell.Module; и запакуешь скомпилированный байт-код в jar-архив remote_shell.jar.
Имя jar-файла (без расширения) используется также в качестве ключа в хешмапе, поэтому, зная имя модуля, всегда можно запустить его методы:
На данном этапе у нас уже есть приложение, способное загружать неограниченное количество модулей из указанного каталога и с удобством работать с ними. Осталось разобраться с тем, как распространять эти модули. Самый очевидный вариант — загружать их с сервера, пусть наш «троян» делает это раз в день, а после скачивания модулей запускает загрузчик модулей, чтобы подгрузить их в приложение. Рассказывать, как сделать это, я не буду, здесь все элементарно, и решение этой задачи ты найдешь в любой вводной статье или книге про разработку для Android.
Еще один вариант — включить модули в пакет с приложением. В этом случае наш троян будет иметь доступ к необходимым модулям сразу после первого запуска, что защитит от проблем с выходом в сеть. Когда же сеть появится, он сможет догружать модули с сервера, если это необходимо.
Чтобы включить модули в APK, их необходимо поместить в каталог assets внутри проекта (в нашем случае в assets/modules), а затем реализовать распаковщик модулей в нужный нам каталог. В коде это будет выглядеть примерно так:
ВЫВОДЫ
Создать приложение для Android, которое сможет обновлять само себя и расширять свою функциональность незаметно для пользователя, довольно легко, и автор этих строк неоднократно видел применение такого метода в реальных троянах. Для чего эту технику будешь использовать ты — решать только тебе, однако я хотел бы напомнить, что наш журнал не поощряет любые незаконные действия, а автор статьи будет совсем не рад узнать, что научил кого-то писать трояны, которых для Android и так уже слишком много.
Чтобы взломать сеть Wi-Fi с помощью Kali Linux, вам нужна беспроводная карта, поддерживающая режим мониторинга…
Работа с консолью считается более эффективной, чем работа с графическим интерфейсом по нескольким причинам.Во-первых, ввод…
Конечно, вы также можете приобрести подписку на соответствующую услугу, но наличие SSH-доступа к компьютеру с…
С тех пор как ChatGPT вышел на арену, возросла потребность в поддержке чата на базе…
Если вы когда-нибудь окажетесь в ситуации, когда вам нужно взглянуть на спектр беспроводной связи, будь…
Elastic Security стремится превзойти противников в инновациях и обеспечить защиту от новейших технологий злоумышленников. В…
View Comments
Получилось у кого рабочий сделать?