Ломаем софт для Android: Часть 2

Ломаем софт для Android: Часть 2

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

Напомню, что с прошлого набега на чужой софт у тебя должны были остаться несколько инструментов, а также алиасы в ~/.bashrc, необходимые для их быстрого запуска. Все это пригодится тебе и сегодня. Кроме того, в этот раз тебе понадобится среда разработки Android Studio. В статье я буду исходить из предположения, что сама Android Studio  установлена   в   каталог  ~/Android/android-studio, а SDK, то есть набор компиляторов и инструментов сборки,  —  в  каталог ~/Android/android-sdk-linux.

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

ИЩЕМ ТОЧКУ ВХОДА

Как и в прошлый раз, идем на apkpure.com, вбиваем в строку поиска адрес WhatsApp в Google Play и скачиваем пакет APK. Для удобства переименовываем его в whatsapp.apk и перемещаем в каталог ~/tmp. Всю дальнейшую работу мы будем вести в нем.

Следующий шаг — найти наилучшее место для внедрения нашего зловредного кода. По объективным причинам такое место — это самое начало кода приложения, и если бы мы имели дело с обычной настольной Java, то это был бы метод main() главного класса приложения. Однако в Android исполнение приложения начинается не с main(). Фактически у здешнего софта вообще нет единой точки входа, оно состоит из множества компонентов, каждый из которых может получить управление при возникновении того или иного события. Если мы хотим, чтобы наш код запускался при старте приложения с рабочего стола, нам нужно вставить его в класс, получающий управление при возникновении события (если быть точным, это называется «интент») android. intent.action.MAIN категории android.intent.category.LAUNCHER. Чтобы найти этот класс, придется дизассемблировать WhatsApp с помощью apktool

и прочитать файл AndroidManifest.xml:

$ apktool d whatsapp.apk
$ less whatsapp/AndroidManifest.xml

Искомый класс носит имя com.whatsapp.Main. Открываем ~/tmp/whatsapp/ smali/com/whatsapp/Main.smali и ищем метод OnCreate():

Это и есть искомая точка входа. C этого метода начинается исполнение графического Android-приложения, когда оно получает интент android.intent. action.MAIN, другими словами — когда юзер тапает по иконке приложения пальцем. В этот метод мы будем внедрять наш payload.

ПИШЕМ PAYLOAD

Какой же код мы  внедрим  в  WhatsApp?  Для  начала  заставим  его  вывести на экран сообщение «Hi from malware!». Очень простая в реализации функция, которая позволит быстро проверить, что все работает так, как мы и рассчитывали. Если ты читал прошлую часть, то уже должен догадаться, как это сделать. Но не стоит торопиться, в этот раз мы не будем вставлять в код отдельные куски smali-кода, а вместо этого создадим отдельный класс, методы которого    уже и будем вызывать из кода WhatsApp. Такой подход гораздо более удобен   и позволяет как угодно расширять функциональность приложения, внося в его оригинальный код минимальные  изменения.

Итак, открываем Android Studio, создаем новый проект, в поле Application name пишем Whatsapp, а в поле Company domain — com. Таким образом среда разработки сама разместит наш класс в пакете com.whatsapp, точно так же, как в оригинальном приложении. При выборе типа активности (Add an activity) выбираем Add No Activity. В левой части экрана разворачиваем список app java com.whatsapp и с помощью правой кнопки мыши создаем новый класс Payload. Добавляем в него следующие строки:

Это и есть наш класс с единственным статическим методом, выводящим на экран сообщение. Теперь класс необходимо скомпилировать и транслировать в байт-код Dalvik. С помощью среды разработки без танцев с бубном это не получится, поэтому сделаем все из командной строки.

Для начала создадим в ~/tmp структуру каталога, аналогичную оригинальному приложению, и скопируем в нее исходный код класса:

$ mkdir -p com/whatsapp                                           
$ cp ~/AndroidstudioProjects/Whatsapp/app/src/main/java/com/         
    whatsapp/Payload.java com/whatsapp                            

Теперь скомпилируем его и транслируем в код Dalvik:

$ javac -classpath ~/Android/android-sdk-linux/platforms/         
    android-23/android.jar com/whatsapp/*.java                    
$ ~/Android/android-sdk-linux/build-tools/23.0.3/dx --dex         
    --output=Payload.dex com/whatsapp/*.class                     

Обрати  внимание  на  android-23  и  23.0.3  в  путях:  чтобы  они  существовали, у тебя должен быть установлен SDK для Android 6.0 и соответствующие инструменты сборки (при первом запуске Android Studio предложит установить    их сама).

В текущем каталоге (~/tmp) должен появиться файл Payload.dex. Его необходимо дизассемблировать:


$ baksmali Payload.dex                                            

И скопировать в каталог с ранее дизассемблированным кодом WhatsApp:

$ cp out/com/whatsapp/*.smali whatsapp/smali/com/whatsapp

ВЫЗЫВАЕМ PAYLOAD


Теперь в дизассемблированном коде WhatsApp есть наш класс, осталось только вызвать его статический метод run(). Чтобы это сделать, достаточно добавить следующую строку куда-то в начало метода onCreate():

На Java этот код выглядел бы так:

То есть инструкция invoke-static, по сути, имеет такой вид:

invoke-static {аргумент}, Lимя_класса;->имя_метода(тип_аргумента;)  
         тип_возвращаемого_значения                                   

Регистр p0, который мы передали в качестве аргумента, всегда ссылается на текущий объект и эквивалентен ключевому слову this в Java. Текущий объект в данном случае имеет класс Activity, мы передаем его методу run() нашего класса, чтобы он смог использовать его для вывода сообщения на экран.

Все, осталось только собрать WhatsApp обратно в APK и подписать тестовым ключом:

$ cd ~/tmp/whatsapp             
$ apktool b                     
$ cd ..                         
$ cp whatsapp/dist/whatsapp.apk   
    whatsapp-payload.apk        
$ sign whatsapp-payload.apk

Полученный файл whatsapp-payload.s.apk закидываем на карту памяти и устанавливаем.

Сработало!

ИДЕМ ДАЛЬШЕ


Какой же это зловред, если вместо кражи личной информации он только и делает, что сообщает о себе? Полностью согласен, поэтому сейчас мы существенно расширим возможности нашего payload. Он никак не будет выдавать своего присутствия, а вместо этого просто скинет все входящие СМС в файл на карте памяти:

Данный код читает базу данных СМС и записывает на карту памяти красивый текстовый файл sms.txt, содержащий СМС в формате:

From: номер      
Date: дата         
Body: текст        

При необходимости код можно дополнить, чтобы файл сразу сливался на удаленный сервер, а затем уничтожался, дабы не оставлять следов. Чтобы код заработал, в манифест приложения (~/tmp/whatsapp/AndroidManifest.xml) необходимо добавить разрешение на чтение СМС:

Далее остается только скомпилировать класс, перегнать в smali, скопировать в приложение, собрать и подписать его, так же как мы делали это в предыдущем разделе. Организовать отправку СМС на короткий номер и того проще:

Причем в этом случае даже не надо править AndroidManifest.xml  —  права  на  отправку СМС у WhatsApp уже есть.

В целом все просто, но есть одно большое но! Дело в том, что два приведенных выше куска кода будут отлично работать только до тех пор, пока ты  не установишь хакнутый WhatsApp на смартфон под управлением Android 6.0 и выше. А тогда приложение упадет на старте, и причина в том, что «шестерка» требует явного запроса прав (в том числе на чтение СМС и запись на карту памяти) перед тем, как функции, защищенные этими правами, будут использованы.

И здесь мы попадаем в одну не очень приятную ситуацию. Запросить-то права мы можем, вот только сама система запроса права реализована не в нашу пользу, потому как событие  «Пользователь  нажал на „Да“» может быть обработано только активностью

приложения с помощью колбэка onRequestPermissionsResult(). Другими словами, придется вносить изменения в сам Main.smali.
Но есть способ проще и тупее. На самом деле нам совсем необязательно дожидаться, пока юзер нажмет кнопку «Да» или «Нет», после нажатия система так или иначе либо даст разрешение на выполнение операции, либо запретит, поэтому мы можем просто подождать и после этого проверить, есть ли у нас нужные права:

Данный код проверяет, запущен ли он в Android 6 или выше (API 23), и если да, то запускает код запроса разрешений на чтение СМС и запись на карту памяти, затем засыпает на десять секунд, а просыпаясь, проверяет, есть ли права  (то есть нажал ли юзер «Да»). Если есть — отрабатывает уже знакомый нам код, нет — ничего не происходит.

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

ПЕРИОДИЧЕСКИЕ  ЗАДАЧИ

Проблема текущей реализации payload в том, что он будет запущен только во время холодного старта приложения, то есть при первом запуске, запуске после перезагрузки либо после того, как приложение будет вытеснено из памяти системой. Для одноразовой задачи это нормально, но что, если нам необходимо, чтобы наш зловред работал в фоне?
Для этого можно использовать сервис, то есть специальный поток, который будет висеть в фоне и делать нужную нам работу. Однако для нашей задачи это слишком избыточное решение. Гораздо удобнее использовать AlarmManager — специальную подсистему Android, позволяющую запускать нужный код через определенные интервалы. В отличие от сервисов AlarmManager не требует модификации AndroidManifest, достаточно просто привести код класса Payload к следующему виду:

Метод run() устанавливает Alarm, который должен срабатывать каждую минуту (60 * 1000 мс) и запускать код, указанный в методе onReceive(). Красота этого подхода в том, что после установки Alarm’а он будет срабатывать вне зависимости от того, запущено ли приложение. То есть, если пользователь запустил хакнутый WhatsApp, а затем закрыл его, а система завершила WhatsApp при нехватке памяти, он вновь будет запущен в фоне, когда сработает Alarm.

ВЫВОДЫ

Как видишь, внедрить собственный код в чужое приложение не просто реально, а реально настолько, что с этой задачей справится даже ребенок. Все, что нужно, — знать основы программирования для Android и чуть-чуть понимать код smali. И тогда открываются просто безграничные возможности модификации других приложений. К примеру, можно реализовать систему загрузки полноценных плагинов, о чем я уже писал, или даже получить root, скачать и установить APK с вирусом в системный раздел.

Поделиться
Плюсануть
Отправить

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

2 2Rabbit Android / Статьи 2 373 28 декабрь 2016

Рекомендуем также

Ломаем софт для Android
Ломаем софт для Android

Ни один разговор о взломе и модификации приложений не обходится без упоминания дизассемблера,...

Новый Android-зловред распространяется через SMS-спам
Новый Android-зловред распространяется через SMS-спам

Стало известно о появлении нового зловреда, атакующего Android-устройства. По свидетельству Heimdal...

Android ID changer
Android ID changer

Меняем andoid ID на устройстве с root....

[Bugtroid] Сборник инструментов для разных видов взлома [root]
[Bugtroid] Сборник инструментов для разных видов взлома [root]

Основной особенностью этого АПК, является то, что оно имеет более чем 200 Android и Linux...


Комментарии (0)


Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.

iOS cydia small iconRepo [cydia.shlyahten.ru]

G iconGAPPS (все версии)