
Recent news from Group-IB about the activity of the mobile Android Trojan Gustuff. It exclusively operates in international markets, targeting customers of the 100 largest foreign banks, users of 32 mobile cryptocurrency wallets, as well as large e-commerce resources. The developer of Gustuff is a Russian-speaking cybercriminal known as Bestoffer. Just recently, he praised his Trojan as a 'serious product for people with knowledge and experience.'
Group-IB malware analysis specialist Ivan Pisariev in his study provides a detailed account of how Gustuff operates and what its dangers are.
Who is Gustuff targeting
Gustuff belongs to a new generation of malware with fully automated functions. According to the developer, the Trojan has become a new improved version of the malware AndyBot, which has been attacking Android phones since November 2017 and stealing money through phishing web forms disguised as mobile applications of well-known international banks and payment systems. Bestoffer reported that the rental price for the 'Gustuff Bot' was $800 per month.
An analysis of the Gustuff sample showed that the Trojan is potentially targeting customers using mobile applications of the largest banks, such as Bank of America, Bank of Scotland, J.P. Morgan, Wells Fargo, Capital One, TD Bank, PNC Bank, as well as cryptocurrency wallets like Bitcoin Wallet, BitPay, Cryptopay, Coinbase, and others.
Initially created as a classic banking Trojan, the current version of Gustuff has significantly expanded the list of potential attack targets. In addition to Android applications of banks, fintech companies, and crypto services, Gustuff is targeting users of marketplace applications, online stores, payment systems, and messengers. In particular, PayPal, Western Union, eBay, Walmart, Skype, WhatsApp, Gett Taxi, Revolut, and others.
Point of entry: relying on mass infection
Gustuff se caracterizează printr-o vectorizare „clasică” a infiltrării pe smartphone-urile Android prin campanii SMS cu linkuri către APK. Atunci când un dispozitiv Android este infectat cu un troian, la comanda serverului, poate avea loc o răspândire ulterioară a Gustuff prin baza de contacte a telefonului infectat sau prin baza de date a serverului. Capacitățile funcționale ale Gustuff sunt concepute pentru infecții masive și maximizarea capitalizării afacerii operatorilor săi – în el există o funcție unică de „autoinstalare” în aplicațiile mobile legitime de banking și portofelele cripto, ceea ce permite accelerarea și scalarea furtului de bani.
Cercetarea troianului a arătat că funcția de autoinstalare este implementată prin intermediul Accessibility Service – un serviciu pentru persoanele cu dizabilități. Gustuff nu este primul troian care ocolește cu succes protecția împotriva interacțiunii cu elementele ferestrelor altor aplicații utilizând acest serviciu Android. Cu toate acestea, utilizarea Accessibility Service în combinație cu autoinstalarea rămâne încă un fenomen destul de rar.
După descărcarea pe telefonul victimei, Gustuff, folosind Accessibility Service, obține posibilitatea de a interacționa cu elementele ferestrelor altor aplicații (bancare, cripto, precum și aplicații pentru cumpărături online, mesagerie etc.), efectuând acțiunile necesare pentru infractori. De exemplu, la comanda serverului, troianul poate apăsa butoane și modifica valorile câmpurilor text în aplicațiile bancare. Utilizarea mecanismului Accessibility Service permite troianului să ocolească mecanismele de protecție utilizate de bănci pentru a contracara troienii mobili din generația anterioară, precum și modificările în politicile de securitate implementate de Google în noile versiuni ale sistemului de operare Android. Astfel, Gustuff „știe” să dezactiveze protecția Google Protect: conform afirmațiilor autorului, această funcție se activează în 70% din cazuri.

De asemenea, Gustuff poate să afișeze notificări PUSH false cu pictogramele aplicațiilor mobile legitime. Utilizatorul face clic pe notificarea PUSH și vede un pop-up de phishing încărcat de pe server, unde introduce singur datele solicitate ale cardului bancar sau portofelului criptografic. În alt scenariu de funcționare a Gustuff, aplicația, de la care a fost afișată notificarea PUSH, se deschide. În acest caz, malware-ul poate umple câmpurile formularului aplicației bancare pentru o tranzacție frauduloasă, la comanda serverului prin intermediul Serviciului de Accesibilitate.
Funcțiile Gustuff includ, de asemenea, trimiterea de informații despre dispozitivul infectat către server, capacitatea de a citi/trimite mesaje SMS, trimiterea de cereri USSD, pornirea proxy-ului SOCKS5, navigarea pe linkuri, trimiterea de fișiere (inclusiv fotografii scanate ale documentelor, capturi de ecran, fotografii) către server, resetarea dispozitivului la setările din fabrică.
Analiza malware-ului
Înainte de instalarea aplicației malware, sistemul de operare Android arată utilizatorului o fereastră care conține o listă cu permisiunile solicitate de Gustuff:

Instalarea aplicației se va face doar după obținerea consimțământului utilizatorului. După lansarea aplicației, troianul va arăta utilizatorului o fereastră:

După care își va șterge pictograma.
Gustuff este împachetat, conform autorului, cu un pachet de la FTT. După lansare, aplicația se conectează periodic la serverul CnC pentru a primi comenzi. În câteva fișiere pe care le-am analizat, adresa IP utilizată ca server de comandă era 88.99.171[.]105 (denumită ulterior ca <%CnC%>).
După lansare, programul începe să trimită mesaje serverului http:///api/v1/get.php.
În calitate de răspuns, se așteaptă un JSON de următorul format:
{
"results": "OK",
"command":{
"id": "",
"command":"",
"timestamp":"",
"params":{
},
},
}La fiecare solicitare, aplicația trimite informații despre dispozitivul infectat. Formatul mesajului este prezentat mai jos. Este de remarcat că câmpurile full, extra, apps și permission sunt opționale și vor fi trimise doar în cazul unei comenzi-solicitare de la CnC.
{
"info":
{
"info":
{
"cell":<%Sim operator name%>,
"country":<%Country ISO%>,
"imei":<%IMEI%>,
"number":<%Phone number%>,
"line1Number":<%Phone number%>,
"advertisementId":<%ID%>
},
"state":
{
"admin":<%Has admin rights%>,
"source":<%String%>,
"needPermissions":<%Application needs permissions%>,
"accesByName":<%Boolean%>,
"accesByService":<%Boolean%>,
"safetyNet":<%String%>,
"defaultSmsApp":<%Default Sms Application%>,
"isDefaultSmsApp":<%Current application is Default Sms Application%>,
"dateTime":<%Current date time%>,
"batteryLevel":<%Battery level%>
},
"socks":
{
"id":<%Proxy module ID%>,
"enabled":<%Is enabled%>,
"active":<%Is active%>
},
"version":
{
"versionName":<%Package Version Name%>,
"versionCode":<%Package Version Code%>,
"lastUpdateTime":<%Package Last Update Time%>,
"tag":<%Tag, default value: "TAG"%>,
"targetSdkVersion":<%Target Sdk Version%>,
"buildConfigTimestamp":1541309066721
},
},
"full":
{
"model":<%Device Model%>,
"localeCountry":<%Country%>,
"localeLang":<%Locale language%>,
"accounts":<%JSON array, contains from "name" and "type" of accounts%>,
"lockType":<%Type of lockscreen password%>
},
"extra":
{
"serial":<%Build serial number%>,
"board":<%Build Board%>,
"brand":<%Build Brand%>,
"user":<%Build User%>,
"device":<%Build Device%>,
"display":<%Build Display%>,
"id":<%Build ID%>,
"manufacturer":<%Build manufacturer%>,
"model":<%Build model%>,
"product":<%Build product%>,
"tags":<%Build tags%>,
"type":<%Build type%>,
"imei":<%imei%>,
"imsi":<%imsi%>,
"line1number":<%phonenumber%>,
"iccid":<%Sim serial number%>,
"mcc":<%Mobile country code of operator%>,
"mnc":<%Mobile network codeof operator%>,
"cellid":<%GSM-data%>,
"lac":<%GSM-data%>,
"androidid":<%Android Id%>,
"ssid":<%Wi-Fi SSID%>
},
"apps":{<%List of installed applications%>},
"permission":<%List of granted permissions%>
} Stocarea datelor de configurare
Gustuff stochează informații esențiale în fișierul de preferințe. Numele fișierului, la fel ca și numele parametrilor din acesta, sunt rezultatul calculării sumei MD5 a șirului 15413090667214.6.1, unde <%name%> — numele original al valorii. Interpretarea Python a funcției de generare a numelui:
nameGenerator(input):
output = md5("15413090667214.6.1" + input) În continuare, ne vom referi la nameGenerator(input).
Astfel, numele primului fișier: nameGenerator(«API_SERVER_LIST»), conține valori cu următoarele nume:
| Numele variabilei | Valoare |
|---|---|
| nameGenerator(«API_SERVER_LIST») | Conține o listă de adrese CnC sub formă de matrice. |
| nameGenerator(«API_SERVER_URL») | Conține adresa CnC. |
| nameGenerator(«SMS_UPLOAD») | Flacul este setat pe implicit. Dacă flacul este activat - trimite SMS-uri către CnC. |
| nameGenerator(«SMS_ROOT_NUMBER») | Numărul de telefon la care vor fi trimise SMS-urile primite de dispozitivul infectat. Implicit, null. |
| nameGenerator(«SMS_ROOT_NUMBER_RESEND») | Flacul implicit este resetat. Dacă este activat, atunci la primirea unui SMS de către dispozitivul infectat, acesta va fi trimis la numărul root. |
| nameGenerator(«DEFAULT_APP_SMS») | Flacul implicit este resetat. Dacă acest flag este activat, aplicația va procesa mesajele SMS primite. |
| nameGenerator(«DEFAULT_ADMIN») | Flacul implicit este resetat. Dacă flagul este activat, aplicația are drepturi de administrator. |
| nameGenerator(«DEFAULT_ACCESSIBILITY») | Flacul implicit este resetat. Dacă flagul este activat, serviciul care utilizează Accessibility Service este activ. |
| nameGenerator(«APPS_CONFIG») | Obiect JSON care conține lista de acțiuni ce trebuie efectuate la activarea unui eveniment Accessibility asociat cu o anumită aplicație. |
| nameGenerator(«APPS_INSTALLED») | Păstrează lista aplicațiilor instalate pe dispozitiv. |
| nameGenerator(«IS_FIST_RUN») | Flacul este resetat la prima pornire. |
| nameGenerator(«UNIQUE_ID») | Conține un identificator unic. Este generat la prima pornire a botului. |
Modul de procesare a comenzilor de la server
Aplicația păstrează adresele serverelor CnC sub formă de matrice de șiruri codificate prin Base85 Listă CnC - servere poate fi modificată la primirea comenzii corespunzătoare, în acest caz adresele vor fi păstrate în fișierul de preferințe.
În răspuns la solicitare, serverul trimite o comandă aplicației. Este important de menționat că comenzile și parametrii sunt prezentați în format JSON. Aplicația poate procesa următoarele comenzi:
| Comanda | Descriere |
|---|---|
| forwardStart | Începe trimiterea SMS-urilor primite de dispozitivul infectat către serverul CnC. |
| forwardStop | Oprește trimiterea SMS-urilor primite de dispozitivul infectat către serverul CnC. |
| ussdRun | Efectuează o solicitare USSD. Numărul la care trebuie să fie efectuată solicitarea USSD se află în câmpul JSON „number”. |
| sendSms | Trimite un mesaj SMS (dacă este necesar, mesajul este „tăiat” în părți). Ca parametru, comanda acceptă un obiect JSON care conține câmpurile „to” - numărul de destinație și „body” - corpul mesajului. |
| sendSmsAb | Trimite mesaje SMS (dacă este necesar, mesajul este „tăiat” în părți) tuturor din lista de contacte a dispozitivului infectat. Intervalul dintre trimiterea mesajelor este de 10 secunde. Corpul mesajului se află în câmpul JSON „body” |
| sendSmsMass | Trimite mesaje SMS (dacă este necesar, mesajul este împărțit în părți) către contactele specificate în parametrii comenzii. Intervalul dintre trimiterea mesajelor este de 10 secunde. Ca parametru, comanda acceptă un array JSON (câmpul „sms”), unde elementele conțin câmpurile „to” — numărul de destinație și „body” — corpul mesajului. |
| changeServer | Această comandă poate accepta ca parametru o valoare cu cheia „url” — atunci botul va schimba valoarea nameGenerator(“SERVER_URL”), sau „array” — atunci botul va scrie un array în nameGenerator(“API_SERVER_LIST”). Astfel, aplicația schimbă adresa serverelor CnC. |
| adminNumber | Comanda este destinată lucrului cu numărul root. Comanda acceptă un obiect JSON cu următorii parametri: „number” — schimbă nameGenerator(“ROOT_NUMBER”) la valoarea primită, „resend” — schimbă nameGenerator(“SMS_ROOT_NUMBER_RESEND”), „sendId” — trimite pe nameGenerator(“ROOT_NUMBER”) uniqueID. |
| updateInfo | Trimite informații despre dispozitivul infectat pe server. |
| wipeData | Comanda este destinată ștergerii datelor utilizatorului. În funcție de ce nume a fost utilizat la lansarea aplicației, se poate face fie ștergerea completă a datelor cu repornirea dispozitivului (utilizator principal), fie ștergerea doar a datelor utilizatorului (utilizator secundar). |
| socksStart | Lansează modul Proxy. Funcționarea modulului este descrisă într-o secțiune separată. |
| socksStop | Oprește funcționarea modulului Proxy. |
| openLink | Accesează linkul. Linkul se află în parametrul JSON cu cheia „url”. Pentru deschiderea linkului se folosește „android.intent.action.VIEW”. |
| uploadAllSms | Trimite pe server toate mesajele SMS primite de dispozitiv. |
| uploadAllPhotos | Trimite pe URL imaginea de pe dispozitivul infectat. URL-ul vine ca parametru. |
| uploadFile | Trimite pe URL un fișier de pe dispozitivul infectat. URL-ul vine ca parametru. |
| uploadPhoneNumbers | Trimite pe server numerele de telefon din lista de contacte. Dacă ca parametru vine un obiect JSON cu valoarea cheii „ab”, aplicația obține lista de contacte din agenda telefonică. Dacă ca parametru vine un obiect JSON cu cheia „sms”, aplicația citește lista de contacte din expeditorii mesajelor SMS. |
| changeArchive | Aplicația încarcă un fișier de la o adresă, care vine ca parametru prin cheia „url”. Fișierul descărcat este salvat cu numele „archive.zip”. Apoi, aplicația dezarhivează fișierul, folosind, dacă este necesar, parola pentru arhivă „b5jXh37gxgHBrZhQ4j3D”. Fișierele dezarhivate sunt salvate în directorul [external storage]\/hgps. În acest director, aplicația stochează web-fake-uri (descris ulterior). |
| actions | Comanda este destinată pentru a lucra cu Action Service, care este descris într-o secțiune separată. |
| test | Nu face nimic. |
| download | Comanda este destinată pentru a descărca un fișier de pe un server la distanță și a-l salva în directorul „Downloads”. URL-ul și numele fișierului vin ca parametru, câmpurile în obiectul JSON având parametrii „url” și „fileName”. |
| remove | Șterge un fișier din directorul „Downloads”. Numele fișierului vine în parametrul JSON cu cheia „fileName”. Numele standard al fișierului este „tmp.apk”. |
| notification | Afișează o notificare cu textele descrierii și titlului, definite de serverul de control. |
Formatul comenzii notification:
{
"results" : "OK",
"command":{
"id": <%id%>,
"command":"notification",
"timestamp":<%Server Timestamp%>,
"params":{
"openApp":<%Open original app or not%>,
"array":[
{"title":<%Title text%>,
"desc":<%Description text%>,
"app":<%Application name%>}
]
},
},
}Notificarea creată de fișierul analizat arată identic cu notificările generate de aplicația menționată în câmpul app. Dacă valoarea câmpului openApp — True, la deschiderea notificării se lansează aplicația specificată în câmpul app. Dacă valoarea câmpului openApp — False, atunci:
- se deschide o fereastră phishing, al cărei conținut este încărcat din directorul \/hgps\/
- se deschide o fereastră phishing, al cărei conținut este încărcat de pe server ?id=&app=
- se deschide o fereastră phishing, mascată sub Google Play Card, cu posibilitatea de a introduce datele cardului.
Rezultatul execuției oricărei comenzi aplicația îl trimite la set_state.php sub formă de obiect JSON cu următorul format:
{
"command":
{
"command":,
"id":,
"state":
}
"id":
} ActionsService
Lista comenzilor pe care aplicația le обработает include action. La primirea comenzii, modul de procesare a comenzilor se adresează acestui serviciu pentru a executa comanda extinsă. Ca parametru, serviciul primește un obiect JSON. Serviciul poate executa următoarele comenzi:
1. PARAMS_ACTION — la primirea unei astfel de comenzi, serviciul obține mai întâi valoarea din parametrul JSON pentru cheia Type, care poate fi următoarea:
- serviceInfo – subcomanda obține valoarea din parametrul JSON pentru cheia includeNotImportant. Dacă flagul este egal cu True — aplicația setează flagul FLAG_ISOLATED_PROCESS pe serviciul care folosește Accessibility Service. Astfel, serviciul va fi pornit într-un proces separat.
- root — obțineți și trimiteți pe server informațiile despre fereastra care este acum în focus. Aplicația obține informațiile folosind clasa AccessibilityNodeInfo.
- admin — solicitați drepturi de administrator.
- delay — suspendați funcționarea ActionsService pentru numărul de milisecunde specificat în parametrul pentru cheia „data”.
- windows — trimiteți lista ferestrelor vizibile utilizatorului.
- install — instalați aplicația pe un dispozitiv infectat. Numele pachetului arhivei se află în cheia „fileName”. Arhiva în sine se află în directorul Downloads.
- global – subcomanda este destinată pentru realizarea tranzitului de la fereastra curentă:
- la meniul Quick Settings
- înapoi
- acasă
- la notificări
- la fereastra aplicațiilor recent deschise
- launch — porniți aplicația. Numele aplicației vine ca parametru pentru cheia data.
- sounds — schimbați modul de sunet în silențios.
- unlock — aprindeți iluminarea ecranului și a tastaturii la intensitate maximă. Aplicația execută această acțiune folosind WakeLock, specificând în calitate de tag șirul [Application lable]:INFO
- permissionOverlay — funcția nu este implementată (răspunsul la execuția comenzii — {„message”:„Not support”} sau {„message”:„low sdk”})
- gesture — funcția nu este implementată (răspunsul la execuția comenzii — {„message”:„Not support”} sau {„message”:„Low API”})
- permissions — această comandă este necesară pentru a solicita drepturi pentru aplicație. Cu toate acestea, funcția de solicitare nu este implementată, astfel că comanda nu are sens. Lista drepturilor solicitate vine ca un array JSON cu cheia „permissions”. Lista standard:
- android.permission.READ_PHONE_STATE
- android.permission.READ_CONTACTS
- android.permission.CALL_PHONE
- android.permission.RECEIVE_SMS
- android.permission.SEND_SMS
- android.permission.READ_SMS
- android.permission.READ_EXTERNAL_STORAGE
- android.permission.WRITE_EXTERNAL_STORAGE
- open — afișați pe ecran o fereastră phishing. În funcție de parametrii primiți de la server, aplicația poate demonstra următoarele feronțe phishing:
- Afișați fereastra phishing, conținutul căreia este specificat în fișierul din directorul /hgps/Rezultatul interacțiunii utilizatorului cu fereastra va fi trimis la adresa /records.php
- Afișați fereastra de phishing, al cărei conținut este încărcat preliminar de la adresa ?id=&app=Rezultatul interacțiunii utilizatorului cu fereastra va fi trimis la adresa /records.php
- Afișați fereastra de phishing, mascată ca Google Play Card.
- interactiv — comanda este destinată interacțiunii cu elementele ferestrelor altor aplicații prin intermediul AccessibilityService. Pentru interacțiune, programul are implementat un serviciu special. Aplicația examinată poate interacționa cu ferontele:
- Active în momentul dat. În acest caz, parametrul conține id sau text (numele) obiectului cu care trebuie interacționat.
- Vizibile utilizatorului în momentul executării comenzii. Aplicația alege ferontele după id.
Obținând obiectele AccessibilityNodeInfo pentru elementele de interes din fereastră, aplicația poate efectua acțiuni în funcție de parametrii:
- focus — a plasa focusul pe obiect.
- click — a face clic pe obiect.
- actionId — a executa o acțiune după ID.
- setText — a modifica textul obiectului. Modificarea textului se poate face în două moduri: executând acțiunea ACTION_SET_TEXT (dacă versiunea Android a dispozitivului infectat este mai mică sau egală cu LOLLIPOP), sau plasând în clipboard un șir și inserându-l în obiect (pentru versiunile mai noi). Această comandă poate fi utilizată pentru a modifica datele dintr-o aplicație bancară.
2. PARAMS_ACTIONS — același lucru ca și PARAMS_ACTION, doar că vine ca un array JSON de comenzi.
Se pare că multora le-ar fi interesant cum arată funcția de interacțiune cu elementele ferestrei unei alte aplicații. Așa este implementată această funcționalitate în Gustuff:
boolean interactiveAction(List aiList, JSONObject action, JsonObject res) {
int count = action.optInt("repeat", 1);
Iterator aiListIterator = ((Iterable)aiList).iterator();
int count = 0;
while(aiListIterator.hasNext()) {
Object ani = aiListIterator.next();
if(1 <= count) {
int index;
for(index = 1; true; ++index) {
if(action.has("focus")) {
if(((AccessibilityNodeInfo)ani).performAction(1)) {
++count;
}
}
else if(action.has("click")) {
if(((AccessibilityNodeInfo)ani).performAction(16)) {
++count;
}
}
else if(action.has("actionId")) {
if(((AccessibilityNodeInfo)ani).performAction(action.optInt("actionId"))) {
++count;
}
}
else if(action.has("setText")) {
customHeader ch = CustomAccessibilityService.a;
Context context = this.getApplicationContext();
String text = action.optString("setText");
if(performSetTextAction(ch, context, ((AccessibilityNodeInfo)ani), text)) {
++count;
}
}
if(index == count) {
break;
}
}
}
((AccessibilityNodeInfo)ani).recycle();
}
res.addPropertyNumber("res", Integer.valueOf(count));
}Funcția de înlocuire a textului:
boolean performSetTextAction(Context context, AccessibilityNodeInfo ani, String text) {
boolean result;
if(Build$VERSION.SDK_INT >= 21) {
Bundle b = new Bundle();
b.putCharSequence("ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE", ((CharSequence)text));
result = ani.performAction(0x200000, b); // ACTION_SET_TEXT
}
else {
Object clipboard = context.getSystemService("clipboard");
if(clipboard != null) {
((ClipboardManager)clipboard).setPrimaryClip(ClipData.newPlainText("autofill_pm", ((CharSequence)text)));
result = ani.performAction(0x8000); // ACTION_PASTE
}
else {
result = false;
}
}
return result;
}Astfel, cu o configurare corectă a serverului de control, Gustuff poate completa câmpurile de text într-o aplicație de banking și apăsa pe butoanele necesare pentru efectuarea tranzacțiilor. Trojanul nu trebuie nici măcar să se autentifice în aplicație — este suficient să trimită comanda pentru a demonstra notificarea PUSH cu o deschidere ulterioară a aplicației bancare preinstalate. Utilizatorul va trece de la sine prin autentificare, după care Gustuff va putea efectua autoîncărcarea.
Modul de procesare a SMS-urilor
Aplicația instalează un handler de eveniment pentru primirea SMS-urilor de către dispozitivul infectat. Aplicația cercetată poate primi comenzi de la operator, care vin în corpul mesajului SMS. Comenzile vin în formatul:
7!5=<%Base64 encoded command%>
Aplicația caută în toate mesajele SMS primite șirul 7!5=, la detectarea unei string-uri - decodifică din Base64 stringul prin deplasarea 4 și execută comanda. Comenzile sunt similare cu comenzile CnC. Rezultatul execuției este trimis la același număr de la care a venit comanda. Formatul răspunsului:
7*5=<%Base64 encode of «result_code command»%>
Opțional, aplicația poate trimite toate mesajele primite pe un număr Root. Pentru aceasta, în fișierul de preferințe trebuie să fie specificat numărul Root și să fie activat flag-ul de redirecționare a mesajelor. Mesajul SMS este trimis către numărul atacatorului în formatul:
—
De asemenea, opțional, aplicația poate trimite mesaje către CnC. Mesajul SMS este trimis către server în format JSON:
{
"id":,
"sms":
{
"text":,
"number":,
"date":
}
}Dacă este activat flag-ul nameGenerator(«DEFAULT_APP_SMS») – aplicația oprește procesarea mesajului SMS și curăță lista mesajelor primite.
Modul Proxy
În aplicația examinată există un modul Backconnect Proxy (în continuare Modul Proxy), care are o clasă separată, incluzând câmpuri statice cu configurația. Datele de configurare sunt păstrate în semplu în formă deschisă:

Toate acțiunile efectuate de Modul Proxy sunt înregistrate în fișiere. Pentru aceasta, aplicația creează în External Storage un director numit „logs” (câmpul ProxyConfigClass.logsDir în clasa de configurare), în care sunt păstrate fișierele jurnal. Înregistrarea se face în fișiere cu numele:
- main.txt – în acest fișier se face înregistrarea funcționării clasei numite CommandServer. În continuare, înregistrarea stringului str în acest fișier va fi denumită mainLog(str).
- session-.txt — în acest fișier sunt salvate datele de jurnal legate de o anumită sesiune de proxy. În continuare, înregistrarea stringului str în acest fișier va fi denumită sessionLog(str).
- server.txt – în acest fișier se face înregistrarea tuturor datelor scrise în fișierele descrise mai sus.
Formatul datelor de jurnal:
<%Date%> [Thread[<%thread id%>], id[]]: log-string
Excepțiile apărute în timpul funcționării Modulului Proxy sunt de asemenea înregistrate în fișier. Pentru aceasta, aplicația formează un obiect JSON în format:
{
"uncaughtException":<%short description of throwable%>
"thread":<%thread%>
"message":<%detail message of throwable%>
"trace": //Stack trace info
[
{
"ClassName":
"FileName":
"LineNumber":
"MethodName":
},
{
"ClassName":
"FileName":
"LineNumber":
"MethodName":
}
]
}Apoi, acesta este convertit într-o reprezentare în format text și este logat.
Activarea modulului Proxy se face după primirea comenzii corespunzătoare. La primirea comenzii de activare a modulului Proxy, aplicația inițiază serviciul intitulat MainService, care este responsabil pentru gestionarea funcționării modulului Proxy – activarea și oprirea acestuia.
Pașii pentru activarea serviciului:
1. Activează un timer care se declanșează o dată pe minut și verifică activitatea modulului Proxy. Dacă modulul nu este activ – îl activează.
De asemenea, la declanșarea evenimentului android.net.conn.CONNECTIVITY_CHANGE activarea modulului Proxy are loc.
2. Aplicația creează un wake-lock cu parametrul PARTIAL_WAKE_LOCK și îl capturează. Astfel, previne trecerea CPU-ului dispozitivului în modul de așteptare.
3. Activează clasa de procesare a comenzilor modulului Proxy, logând anterior șirul mainLog("start server") și
Server::start() host[], commandPort[], proxyPort[]
unde proxy_cnc, command_port și proxy_port sunt parametrii obținuți din configurația serverului Proxy.
Clasa de procesare a comenzilor se numește CommandConnection. Imediat după activare, execută următoarele acțiuni:
4. Se conectează la ProxyConfigClass.host: ProxyConfigClass.commandPort și trimite acolo informațiile despre dispozitivul compromis în format JSON:
{
"id":,
"imei":,
"imsi":,
"model":,
"manufacturer":,
"androidVersion":,
"country":,
"partnerId":,
"packageName":,
"networkType":,
"hasGsmSupport":,
"simReady":,
"simCountry":,
"networkOperator":,
"simOperator":,
"version":
}Unde:
- id – identificatorul, încearcă să obțină din fișierul Shared Preference numit „x” valoarea câmpului „id”. Dacă această valoare nu a putut fi obținută– generează una nouă. Astfel, modulul Proxy are propriul său identificator, care este generat similar cu ID-ul Bot.
- imei – IMEI-ul dispozitivului. Dacă în procesul obținerii valorii a apărut o eroare – acest câmp va conține un mesaj text despre eroare.
- imsi — Identitatea Mobilă Internațională a Abonatului. Dacă a apărut o eroare în timpul obținerii valorii, acest câmp va conține un mesaj text de eroare.
- model — Numele vizibil pentru utilizatorul final al produsului finit.
- manufacturer — Producătorul produsului/hardware-ului (Build.MANUFACTURER).
- androidVersion — un șir în formatul „ (),”
- country — locația curentă a dispozitivului.
- partnerId – șir gol.
- packageName – numele pachetului.
- networkType — tipul conexiunii rețelei curente (exemplu: „WIFI”, „MOBILE”). În cazul unei erori, returnează null.
- hasGsmSupport – true – dacă telefonul suportă GSM, altfel false.
- simReady – starea SIM-ului.
- simCountry — codul ISO al țării (pe baza furnizorului de SIM).
- networkOperator — numele operatorului. Dacă a apărut o eroare în timpul obținerii valorii, acest câmp va conține un mesaj text de eroare.
- simOperator — Numele Furnizorului de Servicii (SPN). Dacă a apărut o eroare în timpul obținerii valorii, acest câmp va conține un mesaj text de eroare.
- version — acest câmp este stocat în clasa de configurare, pentru versiunile analizate ale botului a fost egal cu „1.6”.
5. Trece în modul de așteptare a comenzilor de la server. Comenzile de la server vin în format:
- 0 offset – comandă
- 1 offset – sessionId
- 2 offset – lungime
- 4 offset — date
La primirea unei comenzi, aplicația loghează:
mainLog("Header { sessionId, type[], length[] }")
Următoarele comenzi de la server sunt posibile:
| Name | Comandă | Data | Description |
|---|---|---|---|
| connectionId | 0 | ID-ul Conexiunii | Crează o nouă conexiune |
| SLEEP | 3 | Timp | Suspendă activitatea modulului Proxy |
| PING_PONG | 4 | — | Trimite un mesaj PONG |
Mesajul PONG constă din 4 octeți și arată astfel: 0x04000000.
La primirea comenzii connectionId (pentru crearea unei noi conexiuni) CommandConnection creează o instanță a clasei ProxyConnection.
- În procesul de proxy, sunt implicate două clase: ProxyConnection și end. Când este creată clasa ProxyConnection se conectează la adresa ProxyConfigClass.host: ProxyConfigClass.proxyPort și transmite un obiect JSON:
{
"id":
}Ca răspuns, serverul trimite un mesaj SOCKS5, care conține adresa serverului la distanță, cu care trebuie să se stabilească conexiunea. Interacțiunea cu acest server se realizează prin intermediul clasei end. Schema stabilirii conexiunii poate fi reprezentată astfel:

Interacțiuni de rețea
Pentru a preveni analiza traficului de către snifferii de rețea, interacțiunea dintre serverul CnC și aplicație poate fi protejată prin protocolul SSL. Toate datele transmise, atât de la server, cât și la server, sunt prezentate în format JSON. Aplicația execută următoarele cereri în timpul funcționării sale:
- http:///api/v1/set_state.php — rezultatul executării comenzii.
- http:///api/v1/get.php — obținerea comenzii.
- http:///api/v1/load_sms.php — descărcarea mesajelor SMS de pe dispozitivul infectat.
- http:///api/v1/load_ab.php — descărcarea listei de contacte de pe dispozitivul infectat.
- http:///api/v1/aevents.php – cererea este efectuată la actualizarea parametrilor aflați în fișierul de preferințe.
- http:///api/v1/set_card.php — descărcarea datelor obținute printr-o fereastră de phishing, care se maschează sub Google Play Market.
- http:///api/v1/logs.php – descărcarea datelor de log.
- http:///api/v1/records.php – descărcarea datelor obținute prin feronieturi de phishing.
- http:///api/v1/set_error.php – notificare despre o eroare apărută.
Recomandări
Pentru a-și proteja clienții de amenințarea troienilor mobili, companiile trebuie să utilizeze soluții cuprinzătoare care să permită urmărirea și prevenirea activității rău intenționate fără instalarea de software suplimentar pe dispozitivele utilizatorilor.
În acest scop, metodele de detectare bazate pe semnături pentru troienii mobili trebuie întărite prin tehnologii de analiză comportamentală atât a clientului, cât și a aplicației în sine. În plus, protecția ar trebui să includă o funcție de identificare a dispozitivelor folosind tehnologia de amprentare digitală, ceea ce va permite înțelegerea când un cont este utilizat de pe un dispozitiv neobișnuit și a căzut deja în mâinile fraudelor.
Un aspect esențial – disponibilitatea analizei trans-canal, care oferă companiilor posibilitatea de a controla riscurile apărute nu doar în canalul de internet, ci și în canalul mobil, de exemplu, în aplicații de banking mobil, pentru operațiuni cu criptomonede și orice altele unde pot avea loc tranzacții financiare.
Reguli de securitate pentru utilizatori:
- nu instalați aplicații pentru dispozitivele mobile cu sistem de operare Android din alte surse decât Google Play, acordând o atenție deosebită permisiunilor cerute de aplicație;
- instalați actualizări regulate pentru sistemul de operare Android;
- atenție la extensiile fișierelor încărcate;
- nu vizitați resurse suspecte;
- nu accesați link-uri primite în mesajele SMS.
Participând Semințele Rogacev, specialist junior în cercetarea codului malware din Laboratorul de criminalistică informatică Group-IB.
Sursa: habr.com
