Добрый день!
Хочу поведать вам историю, которая чуть не спровоцировала поседение моей, еще молодой, головы.
Предыстория
Все началось с того, что я приобрел себе Highscreen Omega Prime S пару месяцев назад, был доволен как слон, никак не мог нарадоваться этому чудесному аппарату, который работал шустро и почти без нареканий. И все бы было отлично, если бы я однажды не увидел кучу нотификаций, которые выглядели как-то так:
И я уж начал думать — что же это такое, откуда оно взялось, может быть, мой телефон сломали, но как?! Но через несколько секунд паника стихла, я зажал одно из уведомлений, выбрал пункт «Информация о приложении», и был очень удивлен, увидев то, что уведомления вывело приложение «Обновление ПО»…
Еще больше меня удивило то, что этому приложению требуются разрешения для отправки SMS, определения местоположения, установка шорткатов и спаривание с Bluetooth устройствами.
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_LOGS"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.GET_TASKS"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="com.android.vending.BILLING"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.REBOOT"/>
Пока я думал, как бы мне избавиться от этого приложения, скачивал утилиту для рутования и просто размышлял о том, как такое вообще возможно — у меня появилось штук 5 шотркатов (точнее, я заметил их наличие, вероятно, они появились вместе с нотификациями):
Я сразу же утащил APK файл с телефона, разобрал его на составляющие части с помощью утилит apktool, dex2jar и jd-gui — и приступил к изучению.
Изучение
Изучение началось с анализа AndroidManifest.xml, и второе, что меня смутило в нём — это наличие сервисов и ресиверов, находящихся внутри пакета com.gmobi.trade (при том, что само приложение в com.redbend.dmClient).
<activity android:name="com.gmobi.trade.ActionActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<service android:name="com.gmobi.trade.ActionService"/>
<receiver android:enabled="true" android:name="com.gmobi.trade.ActionMonitor">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_REPLACED"/>
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
<data android:scheme="package"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
И тут виден очень подозрительный ресивер — зачем приложению, которое обновляет систему, отслеживать добавление/удаление приложений? А также при беглом просмотре кода было обнаружено то, что ActionMonitor запускает ActionService, который в свою очередь запускает TradeService, который же, в свою очередь, запускает что-то неведомое и обфусцированное. К сожалению, большинство кода, который мне выдал jd-gui, не поддается анализу на трезвую голову.
SMS
Да, и код для отправки SMS в этом приложении имеется: откуда-то приходит JSON, из которого создается AlertDialog, и в обработчике нажатия positive button происходит отправка SMS. Радует что хотя бы не в фоне это происходит. Но все равно неясно, зачем утилите для обновления ПО вообще отправлять куда-то SMS-сообщения.
AlertDialog.Builder localBuilder2 = new AlertDialog.Builder(this);
localBuilder2.setTitle(str14);
localBuilder2.setMessage(str15);
localBuilder2.setPositiveButton(str16, new DialogInterface.OnClickListener(locallqe, str1, str19, str18, localNotificationManager, i) {
public final void onClick(DialogInterface paramDialogInterface, int paramInt) {
b.b(c, 3);
SmsManager localSmsManager = SmsManager.getDefault();
dfe.a("Sending [" + d + "] to [" + e + "]");
localSmsManager.sendTextMessage(e, null, d, null, null);
f.cancel(g);
finish();
b.b(c, 5);
}
});
localBuilder2.setNegativeButton(str17, new DialogInterface.OnClickListener(locallqe, str1) {
public final void onClick(DialogInterface paramDialogInterface, int paramInt) {
b.b(c, 4);
finish();
}
});
localBuilder2.setCancelable(false);
localBuilder2.create().show();
Bluetooth, геокоординаты и прочее
Тут все более-менее безопасно. Ну, как “безопасно”… приложение всего лишь получает MAC-адрес bt-адаптера, получает геокоординаты, проверяет, включен ли Wi-Fi, получает MAC-адрес wifi-адаптера и отправляет эти данные в неизвестность :)
public final JSONObject f() {
JSONObject localJSONObject1 = new JSONObject();
try {
localJSONObject1.put("sdk", "go2sync");
localJSONObject1.put("sdk_v", "1.2");
localJSONObject1.put("sdk_b", "2014.03.06.1");
localJSONObject1.put("app", a.getPackageName());
localJSONObject1.put("ch", t);
localJSONObject1.put("app_v", opt.e(a));
localJSONObject1.put("imsi", q.j);
localJSONObject1.put("imei", q.k);
localJSONObject1.put("wifi", k);
localJSONObject1.put("gprs", l);
localJSONObject1.put("brand", g());
localJSONObject1.put("sd", opt.c());
localJSONObject1.put("id", c());
azw.lqe.azw localazw = opt.c(a);
StringBuilder localStringBuilder = new StringBuilder("ua:")
.append(opt.a(false))
.append("|imei:")
.append(localazw.a())
.append("|imsi:")
.append(localazw.b())
.append("|wmac:")
.append(opt.b(a))
.append("|bmac:");
localJSONObject1.put("cid", opt.a(opt.a() + "|sn:" + opt.a(a)))
localJSONObject1.put("ua", opt.a(false));
localJSONObject1.put("os", "android");
localJSONObject1.put("os_v", opt.b());
localJSONObject1.put("lang", Locale.getDefault().getLanguage())
localJSONObject1.put("country", opt.h(a));
localJSONObject1.put("gp", q.n);
localJSONObject1.put("wmac", opt.b(a));
localJSONObject1.put("bmac", opt.a());
localJSONObject1.put("sn", opt.a(a));
localJSONObject1.put("sa", opt.g(a));
localJSONObject1.put("sw", opt.j(a));
localJSONObject1.put("sh", opt.k(a));
Location localLocation = opt.f(a);
if (localLocation != null) {
JSONObject localJSONObject2 = new JSONObject();
localJSONObject2.put("lng", localLocation.getLongitude());
localJSONObject2.put("lat", localLocation.getLatitude());
localJSONObject1.put("loc", localJSONObject2);
}
localJSONObject1.put("roaming", opt.o(a));
return localJSONObject1;
} catch (JSONException localJSONException) {
dfe.a(localJSONException);
}
return localJSONObject1;
}
Итоги
Телефон пришлось рутануть, чтобы удалить это приложение. Как обновлять теперь систему — неизвестно.
P.S.
Это приложение было «искаробки», его нельзя было удалить или отключить. И приложения из источников, которым я не доверяю, я не устанавливаю, поэтому вероятность того, что все это произошло по моей вине, стремится к нулю.
Все файлы доступны для скачивания здесь.
Автор: POPSuL