Блог программиста
не только о программировании

Дружественные ресурсы:

IntSystem.org | Веб-разработка, все о ней

DevOps-заметки |

21.02.2016

Реверс трояна под Сбербанк на Android. Рождественский образец.

Образец был получен перед рождественскими праздниками, но дошел до реверса я только сегодня. Работа, учеба и PS4 забирали все свободное время. Дед Мороз, кстати, скопирован из оригинальной иконки образца. Реверс под катом.

spam_message_1

Не прошло и недели, как я вновь получил заветную смс со ссылкой и коротким текстом в стиле: “Вам пришло ММС”. Причем получил я ее достаточно рано: в 4:35 по МСК. Но раннее утро не остановило меня, и я принялся прощупывать ссылки, пока они еще действительно, чтобы не получилось как в прошлый раз.

Что же я обнаружил?

wireshark_photo

На этот раз ссылка в сообщении является промежуточным звеном, который в зависимости от того, куда было обращение и с какого устройства (до сих пор определяют по User-Agent, наивные) перенаправляет либо на лендиг под загрузку apk-файла, либо на легитимный сайт. В данном случае, если обратиться в корень (http://da1net.ru), пользователь будет перенаправлен на авито. Если же ротатор определит desktop-версию клиента, то при обращении в каталоги, он будет перенаправлять пользователя на google. Опытным путем выяснено, что URL лендинга зависит от оператора. В моем случае ссылка http://da1net.ru/t приводит на лендинг для Теле2, в то время как обращение к каталогу m предназначено МТС (к сожалению, на момент исследования лендинг уже был недоступен).

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

<!DOCTYPE html&gt;
<html&gt;<head&gt;<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;
		<meta charset="utf-8"&gt;
		<meta name="viewport" content="width=device-width,initial-scale=1"&gt;
		<title&gt;Вам пришло ММС!</title&gt;
		<link rel="stylesheet" type="text/css" href="style.css"&gt;
	</head&gt;
	<body&gt;
		<div class="head"&gt;
			<img src="logo.png" alt=""&gt;
		</div&gt;
		<div class="text"&gt;
			<center&gt;
			Уважаемый пользователь,<br&gt;
			вам пришло ммс-сообщение!<br&gt;
			Просмотреть вы его можете<br&gt;
			по ссылке ниже.<br&gt;
			</center&gt;
		</div&gt;
		<a href="http://photo1img1.ru/foto/fotografiya_458434.apk"&gt;
		<div class="btn"&gt;
			<center&gt;
			<img src="btn.png" alt=""&gt;
			</center&gt;
		</div&gt;
		</a&gt;
	
</body&gt;</html&gt;

Загружая apk, я подозревал, что увижу очередной образец уже разобранного вдоль и поперек вредоноса, но на этот раз меня удивили. Итак, вес файла 37,0 kB (36 973 байт) с именем fotografiya_458434.apk и sha256 хешем bef10b003dbbc7edb8d7ceeecde8a1cf82ee449fd8fd0b08fcb46075e53fbd31. Без всяких проблем распаковывается стандартными средствами (dex2jar =&gt; jdgui). Я уже писал ранее как декомпилировать android-приложение. Количество кода достаточно небольшое, что несколько облегчает реверс.

apk_converted_to_jar

Что касается работы apk, то здесь все стандартно: клиент серверное приложение по принципу ”получили админа системы через фишинг, отправили все что только можно найти на устройстве, получили команды, выполняем”. Тоесть в общем ничего особенного, очередной бот, но хорошо что на этот раз новый образец. Кстати, продукт уже, судя по ссылкам в панель, пятой версии. Итак, в манифесте все стандартно, запрашивает доступ ко всему что можно и нельзя. Правда теперь еще добавили доступ к камере устройства и геолокацию.

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE">
    <uses-permission android:name="android.permission.RECORD_AUDIO">
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW">
    <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES">
    <uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS">
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED">
    <uses-permission android:name="android.permission.READ_SMS">
    <uses-permission android:name="android.permission.SEND_SMS">
    <uses-permission android:name="android.permission.WRITE_SMS">
    <uses-permission android:name="android.permission.READ_CONTACTS">
    <uses-permission android:name="android.permission.CAMERA">
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION">
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION">
    <uses-permission android:name="android.permission.WAKE_LOCK">
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE">
    <uses-permission android:name="android.permission.READ_PHONE_STATE">
    <uses-permission android:name="android.permission.INTERNET">
    <uses-permission android:name="android.permission.RECEIVE_SMS">
    <uses-permission android:name="android.permission.GET_TASKS">
    <uses-feature android:name="android.hardware.camera">
    <uses-feature android:name="android.hardware.location" android:required="true">
    <uses-feature android:name="android.hardware.location.gps" android:required="true">

Код написан полностью на Java, никакой обфускации нет. Ссылка на гейт панели в открытом виде:http://zdoroviedoma.in/tele2_dream_my/index.php. Данные передаются POST-запросом в json-формате, предварительно закодированном в base64. Json предварительно шифруется алгоритмом, похожим на RC4, ключом-константой 12321322869”.

import java.io.UnsupportedEncodingException;

public class j
{
  public int[] a = new int[256];

  public j(byte[] paramArrayOfByte) // "12321322869".getBytes("UTF-8")
  {
	int i = 0;
    int j = paramArrayOfByte.length;
    for (int k = 0; k < 256; k++)
      this.a[k] = k;
    for (int m = 0; m < 256; m++)
    {
      i = (256 + (i + this.a[m] + paramArrayOfByte[(m % j)])) % 256;
      int n = this.a[i];
      this.a[i] = this.a[m];
      this.a[m] = n;
    }
  }

  public byte[] a(String paramString) throws UnsupportedEncodingException
  {
    return a(paramString.getBytes("UTF-8"));
  }

  public byte[] a(byte[] paramArrayOfByte)
  {
    int i = 0;
    int j = paramArrayOfByte.length;
    byte[] arrayOfByte = new byte[j];
    int k = 0;
    int m = 0;
    while (i < j)
    {
      m = (m + 1) % 256;
      k = (k + this.a[m]) % 256;
      int n = this.a[k];
      this.a[k] = this.a[m];
      this.a[m] = n;
      arrayOfByte[i] = ((byte)(this.a[((this.a[m] + this.a[k]) % 256)] ^ paramArrayOfByte[i]));
      i++;
    }
    return arrayOfByte;
  }
}

Ответ от сервера приходит в точно таком же формате. Если убрать шифрование, общение между сервером и ботов выглядит следующим образом:

{"id":"e0ba05c3-0951-4013-a15f-7f00e9812cd8","type":"get","info":"imei:357242043237517, country:us, cell:Android, android:2.3.4, model:generic, phonenumber:15555215554, sim:89014103211118510720, app:null, ver:5.0.4"}
[{"command":"sent&amp;&amp;&amp;","params":{"to":"+79262000900","body":"\u0410\u0412\u0422\u041e\u041f\u041b\u0410\u0422\u0415\u0416 1000 50","timestamp":1453124123}}]
{"id":"e0ba05c3-0951-4013-a15f-7f00e9812cd8","type":"get","info":"imei:357242043237517, country:us, cell:Android, android:2.3.4, model:generic, phonenumber:15555215554, sim:89014103211118510720, app:null, ver:5.0.4"}
{"command":"pong","params":null}
{"id":"e0ba05c3-0951-4013-a15f-7f00e9812cd8","type":"get","info":"imei:357242043237517, country:us, cell:Android, android:2.3.4, model:generic, phonenumber:15555215554, sim:89014103211118510720, app:null, ver:5.0.4"}
{"command":"pong","params":null}
{"id":"e0ba05c3-0951-4013-a15f-7f00e9812cd8","type":"get","info":"imei:357242043237517, country:us, cell:Android, android:2.3.4, model:generic, phonenumber:15555215554, sim:89014103211118510720, app:null, ver:5.0.4"}
{"command":"pong","params":null}
{"id":"e0ba05c3-0951-4013-a15f-7f00e9812cd8","type":"get","info":"imei:357242043237517, country:us, cell:Android, android:2.3.4, model:generic, phonenumber:15555215554, sim:89014103211118510720, app:null, ver:5.0.4"}
[{"command":"sent&amp;&amp;&amp;","params":{"to":"+79262000900","body":"953","timestamp":"2465886"}}]

Полный список команд:

get_history
get_contacts
get_listapp
esms&amp;&amp;&amp;
get_allsms
change_redir
block_phone
send_ussd
update
GPS_track_current
camera_shot
sent&amp;&amp;&amp;
send_sms
network_protocol
pong

И снова, снова натыкаемся на уже упомянутую ранее команду sent&&&. На этом этапе пришло понимание, что за пятая версия и откуда вообще такое большое число. Оказалось все просто: давно бродившие по Интернет образцы либо исходный код модифицировали. На этом моменте я загрустил и закончил реверс.