
Proprio nei giorni scorsi, Group-IB l'attività del trojan Android Gustuff. Questo malware opera esclusivamente sui mercati internazionali, attaccando i clienti delle 100 maggiori banche straniere, utenti di 32 portafogli criptovalutari e anche grandi risorse di e-commerce. Il creatore di Gustuff è un criminale informatico di lingua russa con l'alias Bestoffer. Recentemente, ha elogiato il suo trojan come "un prodotto serio per persone con conoscenze ed esperienza".
L'esperto in analisi dei malware di Group-IB Ivan Pisariev nel suo studio spiega in dettaglio come funziona Gustuff e quali sono i suoi pericoli.
Chi sta cercando Gustuff
Gustuff appartiene a una nuova generazione di programmi dannosi con funzioni completamente automatizzate. Secondo il creatore, il trojan è diventata una nuova versione migliorata del malware AndyBot, che dal novembre 2017 attacca i telefoni con sistema operativo Android e ruba denaro attraverso moduli web di phishing, mascherati da applicazioni mobili di banche internazionali e sistemi di pagamento. Bestoffer ha dichiarato che il prezzo di affitto di "Gustuff Bot" era di $800 al mese.
L'analisi del campione di Gustuff ha mostrato che il trojan è potenzialmente rivolto ai clienti che utilizzano applicazioni mobili delle maggiori banche, come Bank of America, Bank of Scotland, J.P.Morgan, Wells Fargo, Capital One, TD Bank, PNC Bank, così come a portafogli criptovalutari come Bitcoin Wallet, BitPay, Cryptopay, Coinbase e altri.
Originariamente creato come un classico trojan bancario, nella versione attuale Gustuff ha notevolmente ampliato l'elenco degli obiettivi potenziali per l'attacco. Oltre alle applicazioni bancarie Android, società fintech e servizi di criptovaluta, Gustuff prende di mira gli utenti di applicazioni di marketplace, negozi online, sistemi di pagamento e messaggeri. In particolare, PayPal, Western Union, eBay, Walmart, Skype, WhatsApp, Gett Taxi, Revolut e altri.
Punto d'ingresso: mirare a un'infezione di massa
Gustuff si caratterizza per un vettore di infiltrazione "classico" sui smartphone Android tramite SMS che contengono link ad APK. Una volta infettato un dispositivo Android tramite il trojan, per comando del server, potrebbe avvenire una ulteriore diffusione di Gustuff tramite la rubrica dei contatti del telefono infettato o attraverso il database del server. Le funzionalità di Gustuff sono progettate per un'infezione di massa e per massimizzare la capitalizzazione del business dei suoi operatori: è presente una funzione unica di "auto-inserimento" nelle legittime applicazioni bancarie mobili e nei portafogli elettronici, che consente di accelerare e scalare il furto di denaro.
Lo studio del trojan ha mostrato che la funzione di auto-inserimento è implementata tramite il Accessibility Service, un servizio per persone con disabilità. Gustuff non è il primo trojan a superare con successo le protezioni contro l'interazione con gli elementi delle finestre di altre applicazioni usando questo servizio Android. Tuttavia, l'uso del Accessibility Service in combinazione con l'auto-inserimento rimane ancora un fenomeno piuttosto raro.
Dopo il download sul telefono della vittima, Gustuff, utilizzando il Accessibility Service, ottiene la possibilità di interagire con gli elementi delle finestre di altre applicazioni (bancarie, di criptovalute, così come applicazioni per lo shopping online, la messaggistica e altro), compiendo le azioni necessarie per i criminali. Ad esempio, su comando del server, il trojan può premere pulsanti e modificare i valori dei campi di testo nelle applicazioni bancarie. L'uso del meccanismo Accessibility Service consente al trojan di eludere i meccanismi di protezione adottati dalle banche contro i trojan mobili della vecchia generazione, nonché le modifiche nella politica di sicurezza implementate da Google nelle nuove versioni del sistema operativo Android. Così, Gustuff è in grado di disattivare la protezione di Google Protect: secondo quanto dichiarato dall'autore, questa funzionalità si attiva nel 70% dei casi.

Gustuff può anche mostrare notifiche PUSH fasulle con icone di legittime applicazioni mobili. L'utente clicca sulla notifica PUSH e vede una finestra di phishing caricata dal server, dove inserisce i dati richiesti della carta di credito o del portafoglio crypto. In un altro scenario di funzionamento di Gustuff si apre l'applicazione, a nome della quale è stata mostrata la notifica PUSH. In questo caso il malware, su comando del server tramite Accessibility Service, può compilare i campi del modulo dell'applicazione bancaria per una transazione fraudolenta.
Le funzionalità di Gustuff includono anche l'invio al server di informazioni sul dispositivo infetto, la possibilità di leggere/inviare messaggi SMS, inviare richieste USSD, avviare un proxy SOCKS5, seguire link, inviare file (inclusi fotoscansioni di documenti, screenshot, fotografie) al server, ripristinare il dispositivo alle impostazioni di fabbrica.
Analisi del malware
Prima dell'installazione dell'applicazione malevola, il sistema operativo Android mostra all'utente una finestra contenente un elenco dei permessi richiesti da Gustuff:

L'installazione dell'app avverrà solo dopo aver ottenuto il consenso dell'utente. Dopo aver avviato l'applicazione, il trojan mostrerà all'utente una finestra:

Dopodiché eliminerà la sua icona.
Gustuff è confezionato, secondo l'autore, con un pacchetto FTT. Dopo l'avvio, l'applicazione si connette periodicamente al server CnC per ricevere comandi. In alcuni file da noi analizzati è stato utilizzato come server di comando l'indirizzo IP 88.99.171[.]105 (d'ora in poi lo indicheremo come <%CnC%>).
Dopo l'avvio, il programma inizia a inviare messaggi al server http:///api/v1/get.php.
In risposta ci si attende un JSON del seguente formato:
{
"results" : "OK",
"command":{
"id": "",
"command":"",
"timestamp":"",
"params":{
},
},
}Ad ogni contatto, l'applicazione invia informazioni sul dispositivo infetto. Il formato del messaggio è riportato di seguito. Va notato che i campi full, extra, apps e permission sono opzionali e verranno inviati solo in caso di richiesta da parte del CnC.
{
"info":
{
"info":
{
"cell":,
"country":,
"imei":,
"number":,
"line1Number":,
"advertisementId":
},
"state":
{
"admin":,
"source":,
"needPermissions":,
"accesByName":,
"accesByService":,
"safetyNet":,
"defaultSmsApp":,
"isDefaultSmsApp":,
"dateTime":,
"batteryLevel":
},
"socks":
{
"id":,
"enabled":,
"active":
},
"version":
{
"versionName":,
"versionCode":,
"lastUpdateTime":,
"tag":,
"targetSdkVersion":,
"buildConfigTimestamp":1541309066721
},
},
"full":
{
"model":,
"localeCountry":,
"localeLang":,
"accounts":,
"lockType":
},
"extra":
{
"serial":,
"board":,
"brand":,
"user":,
"device":,
"display":,
"id":,
"manufacturer":,
"model":,
"product":,
"tags":,
"type":,
"imei":,
"imsi":,
"line1number":,
"iccid":,
"mcc":,
"mnc":,
"cellid":,
"lac":,
"androidid":,
"ssid":
},
"apps":{},
"permission":
} Memorizzazione dei dati di configurazione
Gustuff memorizza informazioni importanti per il funzionamento in un file di preferenze. Il nome del file, così come i nomi dei parametri al suo interno, è il risultato del calcolo dell'hash MD5 della stringa 15413090667214.6.1, dove <%name%> — il nome valore originale. Interpretazione Python della funzione di generazione del nome:
nameGenerator(input):
output = md5("15413090667214.6.1" + input) In seguito indicheremo come nameGenerator(input).
Pertanto, il nome del primo file: nameGenerator("API_SERVER_LIST"), contiene valori con i seguenti nomi:
| Nome della variabile | Valore |
|---|---|
| nameGenerator("API_SERVER_LIST") | Contiene un elenco di indirizzi CnC sotto forma di array. |
| nameGenerator("API_SERVER_URL") | Contiene l'indirizzo CnC. |
| nameGenerator("SMS_UPLOAD") | Il flag è impostato per default. Se il flag è impostato, invia messaggi SMS al CnC. |
| nameGenerator(«SMS_ROOT_NUMBER») | Il numero di telefono a cui verranno inviati gli SMS ricevuti dal dispositivo infetto. Di default è impostato su null. |
| nameGenerator(«SMS_ROOT_NUMBER_RESEND») | Il flag di default è disabilitato. Se attivato, quando il dispositivo infetto riceve un SMS, esso sarà inviato al numero principale. |
| nameGenerator(«DEFAULT_APP_SMS») | Il flag di default è disabilitato. Se questo flag è attivato, l'applicazione elaborerà i messaggi SMS in arrivo. |
| nameGenerator(«DEFAULT_ADMIN») | Il flag di default è disabilitato. Se attivato, l'applicazione avrà diritti da amministratore. |
| nameGenerator(«DEFAULT_ACCESSIBILITY») | Il flag di default è disabilitato. Se attivato, sarà avviato un servizio che utilizza il servizio di accessibilità. |
| nameGenerator(«APPS_CONFIG») | Oggetto JSON che contiene un elenco di azioni da eseguire quando si verifica un evento di accessibilità associato a un'app specifica. |
| nameGenerator(«APPS_INSTALLED») | Contiene un elenco delle applicazioni installate sul dispositivo. |
| nameGenerator(«IS_FIST_RUN») | Il flag viene reimpostato al primo avvio. |
| nameGenerator(«UNIQUE_ID») | Contiene un identificatore unico. Viene generato al primo avvio del bot. |
Modulo di elaborazione comandi dal server
L'applicazione memorizza gli indirizzi dei server CnC come un array di stringhe codificate in Base85 . L'elenco dei CnC può essere modificato quando si riceve un comando appropriato, in tal caso gli indirizzi saranno memorizzati nel file di preferenze. server In risposta alla richiesta, il server invia un comando all'applicazione. È importante notare che i comandi e i parametri sono presentati in formato JSON. L'applicazione può elaborare i seguenti comandi:
forwardStart
| Team | Descrizione |
|---|---|
| Iniziare l'invio degli SMS ricevuti dal dispositivo infetto al server CnC. | forwardStop |
| Fermare l'invio degli SMS ricevuti dal dispositivo infetto al server CnC. | ussdRun |
| Eseguire una richiesta USSD. Il numero su cui eseguire la richiesta USSD si trova nel campo JSON «number». | sendSms |
| Inviare un singolo SMS (se necessario, il messaggio sarà suddiviso in parti). Come parametro, il comando accetta un oggetto JSON contenente i campi «to» — numero di destinazione e «body» — corpo del messaggio. | sendSmsAb |
| Inviare SMS (se necessario, il messaggio sarà suddiviso in parti) a tutti i contatti dell'elenco del dispositivo infetto. L'intervallo tra l'invio dei messaggi è di 10 secondi. Il corpo del messaggio si trova nel campo JSON «body» | sendSmsMass |
| sendSmsMass | Invia SMS (se necessario, il messaggio "viene spezzato" in parti) ai contatti specificati nei parametri del comando. L'intervallo tra l'invio dei messaggi è di 10 secondi. Come parametro, il comando accetta un array JSON (campo "sms"), i cui elementi contengono i campi "to" — numero di destinazione e "body" — corpo del messaggio. |
| cambiaServer | Questo comando può accettare come parametro un valore con la chiave "url" — in tal caso il bot cambierà il valore di nameGenerator("SERVER_URL"), oppure "array" — in tal caso il bot registrerà un array in nameGenerator("API_SERVER_LIST"). In questo modo, l'applicazione modifica l'indirizzo dei server CnC. |
| numeroAdmin | Il comando è progettato per lavorare con il numero root. Il comando accetta un oggetto JSON con i seguenti parametri: "number" — modificare nameGenerator("ROOT_NUMBER") con il valore ricevuto, "resend" — modificare nameGenerator("SMS_ROOT_NUMBER_RESEND"), "sendId" — inviare a nameGenerator("ROOT_NUMBER") uniqueID. |
| aggiornaInfo | Invia al server informazioni sul dispositivo infetto. |
| cancellaDati | Il comando è progettato per eliminare i dati utente. A seconda del nome con cui è stata avviata l'applicazione, si eseguirà la cancellazione completa dei dati con il riavvio del dispositivo (utente principale) o la cancellazione solo dei dati utente (utente secondario). |
| avviaSocks | Avvia il modulo Proxy. Il funzionamento del modulo è descritto in una sezione separata. |
| fermaSocks | Ferma il funzionamento del modulo Proxy. |
| apriLink | Apri il link. Il link si trova nel parametro JSON con la chiave "url". Per aprire il link viene utilizzato "android.intent.action.VIEW". |
| caricaTuttiISms | Invia al server tutti gli SMS ricevuti dal dispositivo. |
| caricaTutteLeFoto | Invia all'URL le immagini dal dispositivo infetto. L'URL viene fornito come parametro. |
| caricaFile | Invia all'URL un file dal dispositivo infetto. L'URL viene fornito come parametro. |
| caricaNumeriDiTelefono | Invia al server i numeri di telefono dall'elenco dei contatti. Se come parametro arriva un oggetto JSON con la chiave "ab", l'applicazione ottiene l'elenco dei contatti dalla rubrica. Se come parametro arriva un oggetto JSON con la chiave "sms", l'applicazione legge l'elenco dei contatti dai mittenti degli SMS. |
| cambiaArchivio | L'applicazione scarica un file dall'indirizzo fornito come parametro con la chiave «url». Il file scaricato viene salvato con il nome «archive.zip». Successivamente, l'applicazione estrae il file, utilizzando la password per l'archivio «b5jXh37gxgHBrZhQ4j3D» se necessario. I file estratti vengono salvati nella directory [external storage]\/hgps. In questa directory, l'applicazione conserva web-fake (descritti di seguito). |
| azioni | Il comando è destinato a lavorare con Action Service, descritto in una sezione separata. |
| test | Non fa nulla. |
| download | Il comando è destinato a scaricare un file da un server remoto e salvarlo nella directory «Downloads». L'URL e il nome del file vengono forniti come parametri, rispettivamente nei campi del JSON-oggetto: «url» e «fileName». |
| remove | Rimuove un file dalla directory «Downloads». Il nome del file viene fornito nel parametro JSON con la chiave «fileName». Il nome standard del file è «tmp.apk». |
| notification | Mostra una notifica con i testi di descrizione e titolo definiti dal server di gestione. |
Formato del comando notification:
{
"results" : "OK",
"command":{
"id": ,
"command":"notification",
"timestamp":,
"params":{
"openApp":,
"array":[
{"title":,
"desc":,
"app":}
]
},
},
}La notifica creata dal file in esame appare identica alle notifiche generate dall'applicazione specificata nel campo app. Se il valore del campo openApp è True, all'apertura della notifica si avvia l'applicazione specificata nel campo app. Se il valore del campo openApp è False, allora:
- si apre una finestra di phishing, il cui contenuto viene caricato dalla directory \/hgps\/
- si apre una finestra di phishing, il cui contenuto viene caricato dal server ?id=&app=
- si apre una finestra di phishing mascherata da Google Play Card, con la possibilità di inserire i dati della carta.
Il risultato dell'esecuzione di qualsiasi comando viene inviato dall'applicazione a set_state.php sotto forma di un oggetto JSON del seguente formato:
{
"command":
{
"command":,
"id":,
"state":
}
"id":
} ActionsService
La lista dei comandi processati dall'applicazione include action. Quando viene ricevuto un comando, il modulo di elaborazione dei comandi si rivolge a questo servizio per eseguire il comando esteso. Come parametro, il servizio accetta un oggetto JSON. Il servizio può eseguire i seguenti comandi:
1. PARAMS_ACTION — ricevendo un tale comando, il servizio in primo luogo ottiene dal parametro JSON il valore della chiave Type, che può essere il seguente:
- serviceInfo – il sotto-comando ottiene dal parametro JSON il valore della chiave includeNotImportant. Se il flag è uguale a True — l'applicazione imposta il flag FLAG_ISOLATED_PROCESS sul servizio che utilizza il Servizio di Accessibilità. In questo modo, il servizio verrà avviato in un processo separato.
- root — ottenere e inviare al server informazioni sulla finestra che è attualmente in primo piano. L'applicazione ottiene informazioni utilizzando la classe AccessibilityNodeInfo.
- admin — richiedere i diritti di amministratore.
- delay — mettere in pausa il funzionamento di ActionsService per il numero di millisecondi specificato nel parametro con chiave «data».
- windows — inviare un elenco delle finestre visibili all'utente.
- install — installare l'applicazione su un dispositivo infetto. Il nome del pacchetto dell'archivio si trova nella chiave «fileName». L'archivio stesso si trova nella directory Downloads.
- global – il sotto-comando è destinato a effettuare il passaggio dalla finestra corrente:
- al menu Impostazioni Rapide
- indietro
- casa
- alle notifiche
- alla finestra delle applicazioni recentemente aperte
- launch — avviare l'applicazione. Il nome dell'applicazione viene passato come parametro nella chiave data.
- sounds — cambiare la modalità audio in silenzioso.
- unlock — accende la retroilluminazione dello schermo e della tastiera alla massima luminosità. L'applicazione esegue questa azione utilizzando WakeLock, specificando la stringa [Application lable]:INFO come tag
- permissionOverlay — funzione non implementata (risposta all'esecuzione del comando — {«message»:«Not support»} o {«message»:«low sdk»})
- gesture — funzione non implementata (risposta all'esecuzione del comando — {«message»:«Not support»} o {«message»:«Low API»})
- permissions — questo comando è necessario per richiedere i diritti per l'applicazione. Tuttavia, la funzione di richiesta non è implementata, quindi il comando non ha senso. L'elenco dei diritti richiesti viene fornito come array JSON con la chiave «permissions». Elenco 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 — visualizzare sullo schermo una finestra di phishing. A seconda del parametro ricevuto dal server, l'applicazione può mostrare le seguenti finestre di phishing:
- Mostra la finestra di phishing il cui contenuto è scritto nel file nella directory /hgps/. Il risultato dell'interazione dell'utente con la finestra sarà inviato all'indirizzo /records.php
- Mostra la finestra di phishing, il cui contenuto viene caricato in precedenza dall'indirizzo ?id=&app=. Il risultato dell'interazione dell'utente con la finestra sarà inviato all'indirizzo /records.php
- Mostra la finestra di phishing camuffata da Google Play Card.
- interactive — il comando è destinato a interagire con gli elementi delle finestre di altre applicazioni tramite AccessibilityService. Per l'interazione è implementato un servizio speciale. L'applicazione in esame può interagire con le finestre:
- Attivo in quel momento. In tal caso, il parametro contiene id o text (nome) dell'oggetto con cui si deve interagire.
- Visibili all'utente al momento dell'esecuzione del comando. L'applicazione seleziona le finestre in base all'id.
Ricevuti gli oggetti AccessibilityNodeInfo per gli elementi di interesse della finestra, l'applicazione può eseguire azioni in base ai parametri:
- focus — impostare il focus sull'oggetto.
- click — cliccare sull'oggetto.
- actionId — eseguire un'azione in base all'ID.
- setText — modificare il testo dell'oggetto. La modifica del testo può essere effettuata in due modi: eseguire l'azione ACTION_SET_TEXT (se la versione di Android del dispositivo infetto è inferiore o uguale a LOLLIPOP), oppure posizionando una stringa negli appunti e incollandola nell'oggetto (per le versioni successive). Questo comando può essere utilizzato per modificare i dati in un'app bancaria.
2. PARAMS_ACTIONS — è lo stesso di PARAMS_ACTION, solo che riceve un array JSON di comandi.
Sembra che a molti interesserà come appare la funzione di interazione con gli elementi della finestra di un'altra applicazione. Questa è l'implementazione di questa funzionalità in 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));
}Funzione di sostituzione del testo:
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;
}Pertanto, con la corretta configurazione del server di gestione, Gustuff è in grado di compilare i campi di testo nelle applicazioni bancarie e premere i pulsanti necessari per effettuare le transazioni. Il trojan non richiede nemmeno l'autenticazione nell'app — basta inviare un comando per visualizzare una notifica PUSH seguita dall'apertura dell'app bancaria precedentemente installata. L'utente completerà l'autenticazione, dopo di che Gustuff sarà in grado di effettuare un'operazione di riempimento automatico.
Modulo di elaborazione dei messaggi SMS
L'applicazione imposta un gestore eventi per la ricezione di messaggi SMS su dispositivi infetti. L'applicazione in esame può ricevere comandi dall'operatore che arrivano nel corpo dei messaggi SMS. I comandi arrivano nel formato:
7!5=
L'applicazione cerca all'interno di tutti i messaggi SMS in arrivo una stringa 7!5=, alla rilevazione della stringa – decodifica la stringa da Base64 con uno spostamento di 4 e esegue il comando. I comandi sono analoghi ai comandi CnC. Il risultato dell'esecuzione viene inviato al medesimo numero da cui è arrivato il comando. Formato della risposta:
7*5=
Facoltativamente, l'applicazione può inviare tutti i messaggi ricevuti al numero Root. A tal fine, nel file di preferenze deve essere specificato il numero Root e impostato il flag di reindirizzamento dei messaggi. Il messaggio SMS viene inviato al numero dell'aggressore nel formato:
—
L'applicazione può anche inviare messaggi a CnC. Il messaggio SMS viene inviato al server in formato JSON:
{
"id":,
"sms":
{
"text":,
"number":,
"date":
}
}Se è impostato il flag nameGenerator(«DEFAULT_APP_SMS») – l'applicazione interrompe l'elaborazione del messaggio SMS e svuota l'elenco dei messaggi in arrivo.
Modulo Proxy
Nell'applicazione esaminata è presente un modulo Backconnect Proxy (di seguito modulo Proxy), che ha una propria classe, contenente campi statici con la configurazione. I dati di configurazione sono memorizzati nel campione in chiaro:

Tutte le azioni effettuate dal modulo Proxy vengono registrate in file. A tal fine, l'applicazione crea nella memoria esterna una directory chiamata «logs» (campo ProxyConfigClass.logsDir nella classe di configurazione), in cui vengono conservati i file di log. La registrazione avviene in file con nomi:
- main.txt – in questo file viene registrato il lavoro della classe chiamata CommandServer. In seguito, registrare la stringa str in questo file sarà indicato come mainLog(str).
- session-.txt – in questo file vengono salvati i log relativi a una particolare sessione di proxy. In seguito, registrare la stringa str in questo file sarà indicato come sessionLog(str).
- server.txt – in questo file viene registrata tutta la documentazione scritta nei file sopra descritti.
Formato dei log:
[Thread[], id[]]: log-string
Le eccezioni che si verificano durante il funzionamento del modulo Proxy vengono anch'esse registrate in un file. A tal fine, l'applicazione forma un oggetto JSON nel seguente formato:
{
"uncaughtException":
"thread":
"message":
"trace": //Stack trace info
[
{
"ClassName":
"FileName":
"LineNumber":
"MethodName":
},
{
"ClassName":
"FileName":
"LineNumber":
"MethodName":
}
]
}Successivamente, lo converte in una rappresentazione di stringa e lo registra.
L'avvio del modulo Proxy avviene dopo il ricevimento del comando corrispondente. All'arrivo del comando per avviare il modulo Proxy, l'applicazione avvia il servizio chiamato MainService, responsabile della gestione del funzionamento del modulo Proxy: la sua attivazione e disattivazione.
Fasi di avvio del servizio:
1. Avvia un timer che si attiva ogni minuto e verifica l'attività del modulo Proxy. Se il modulo è inattivo, lo avvia.
Inoltre, al verificarsi dell'evento android.net.conn.CONNECTIVITY_CHANGE avviene l'avvio del modulo Proxy.
2. L'applicazione crea un wake-lock con il parametro PARTIAL_WAKE_LOCK e lo acquisisce. In questo modo, impedisce alla CPU del dispositivo di entrare in modalità sospensione.
3. Avvia la classe di elaborazione dei comandi del modulo Proxy, registrando preventivamente la stringa mainLog("start server") e
Server::start() host[], commandPort[], proxyPort[]
dove proxy_cnc, command_port e proxy_port sono parametri ottenuti dalla configurazione del server Proxy.
La classe di elaborazione dei comandi si chiama CommandConnection. Subito dopo l'avvio, esegue le seguenti azioni:
4. Si connette a ProxyConfigClass.host: ProxyConfigClass.commandPort e invia i dati sul dispositivo infetto in formato JSON:
{
"id":,
"imei":,
"imsi":,
"model":,
"manufacturer":,
"androidVersion":,
"country":,
"partnerId":,
"packageName":,
"networkType":,
"hasGsmSupport":,
"simReady":,
"simCountry":,
"networkOperator":,
"simOperator":,
"version":
}Dove:
- id è l'identificatore, cerca di ottenere dal file Shared Preferences con il nome "x" il valore del campo "id". Se non riesce a ottenere questo valore, genera uno nuovo. In questo modo, il modulo Proxy ha il proprio identificatore, generato in modo simile all'ID del Bot.
- imei è l'IMEI del dispositivo. Se si verifica un errore nel processo di acquisizione del valore, questo campo sarà sostituito da un messaggio di errore.
- imsi — Identità del sottoscrittore mobile internazionale del dispositivo. Se si è verificato un errore durante l'ottenimento del valore, verrà registrato un messaggio di errore in questo campo.
- model — Il nome visibile per l'utente finale del prodotto finale.
- manufacturer — Il produttore del prodotto/ hardware (Build.MANUFACTURER).
- androidVersion — stringa nel formato " (),"
- country — posizione attuale del dispositivo.
- partnerId – stringa vuota.
- packageName – nome del pacchetto.
- networkType — tipo di connessione di rete attuale (esempio: "WIFI", "MOBILE"). In caso di errore restituisce null.
- hasGsmSupport – true – se il telefono supporta GSM, altrimenti false.
- simReady – stato della SIM card.
- simCountry — codice ISO del paese (in base al fornitore della SIM card).
- networkOperator — nome dell'operatore. Se si è verificato un errore durante l'ottenimento del valore, verrà registrato un messaggio di errore in questo campo.
- simOperator — Il nome del fornitore di servizi (SPN). Se si è verificato un errore durante l'ottenimento del valore, verrà registrato un messaggio di errore in questo campo.
- version — questo campo è memorizzato nella classe di configurazione, per le versioni del bot esaminate era pari a "1.6".
5. Passa in modalità attesa per comandi dal server. I comandi dal server vengono inviati nel formato:
- 0 offset – comando
- 1 offset – sessionId
- 2 offset – lunghezza
- 4 offset — dati
Quando arriva un comando, l'applicazione esegue il log:
mainLog("Header { sessionId, type[], length[] }")
I seguenti comandi dal server sono possibili:
| Name | Comando | Dati | Descrizione |
|---|---|---|---|
| connectionId | 0 | ID connessione | Creare una nuova connessione |
| SLEEP | 3 | Tempo | Sospendere il modulo Proxy |
| PING_PONG | 4 | — | Inviare un messaggio PONG |
Il messaggio PONG consiste di 4 byte e appare nel seguente modo: 0x04000000.
Quando arriva il comando connectionId (per creare una nuova connessione) CommandConnection crea un'istanza della classe ProxyConnection.
- Nel proxy partecipano due classi: ProxyConnection e end. Durante la creazione della classe ProxyConnection viene stabilita una connessione all'indirizzo ProxyConfigClass.host: ProxyConfigClass.proxyPort e viene inviato l'oggetto JSON:
{
"id":
}In risposta, il server invia un messaggio SOCKS5, che contiene l'indirizzo del server remoto con cui stabilire una connessione. L'interazione con questo server avviene tramite la classe end. Schematizzando, la connessione può essere rappresentata nel seguente modo:

Interazioni di rete
Per prevenire l'analisi del traffico da parte di sniffer di rete, l'interazione tra il server CnC e l'applicazione può essere protetta tramite il protocollo SSL. Tutti i dati trasmessi sia dal server che verso il server sono presentati in formato JSON. Durante il suo funzionamento, l'applicazione esegue le seguenti richieste:
- http://<%CnC%>/api/v1/set_state.php — risultato dell'esecuzione del comando.
- http:///api/v1/get.php — ricezione del comando.
- http://<%CnC%>/api/v1/load_sms.php — scaricamento di messaggi SMS dal dispositivo compromesso.
- http://<%CnC%>/api/v1/load_ab.php — scaricamento della lista dei contatti dal dispositivo compromesso.
- http://<%CnC%>/api/v1/aevents.php – la richiesta viene effettuata durante l'aggiornamento dei parametri presenti nel file delle preferenze.
- http://<%CnC%>/api/v1/set_card.php — scaricamento dei dati ottenuti tramite una finestra di phishing che si maschera da Google Play Market.
- http://<%CnC%>/api/v1/logs.php – scaricamento dei dati di log.
- http://<%CnC%>/api/v1/records.php – scaricamento dei dati ottenuti tramite finestre di phishing.
- http://<%CnC%>/api/v1/set_error.php – notificazione di un errore verificatosi.
Raccomandazioni
Per proteggere i propri clienti dalla minaccia dei trojan mobili, le aziende devono utilizzare soluzioni complete che consentano di monitorare e prevenire attività dannose senza installare software aggiuntivo sui dispositivi degli utenti.
Per fare ciò, i metodi di rilevamento delle firme dei trojan mobili devono essere potenziati con tecnologie di analisi comportamentale sia del client che dell'applicazione stessa. Inoltre, la protezione dovrebbe includere una funzione di identificazione dei dispositivi utilizzando la tecnologia della firma digitale, il che consentirebbe di capire quando un account viene utilizzato da un dispositivo non riconosciuto e già in mano ai truffatori.
Un aspetto fondamentale è la possibilità di analisi cross-channel, che consente alle aziende di controllare i rischi che si presentano non solo sul canale internet, ma anche su quello mobile, ad esempio, nelle applicazioni di mobile banking, per operazioni con criptovalute e in qualsiasi altro contesto in cui possa avvenire una transazione finanziaria.
Regole di sicurezza per gli utenti:
- non installare applicazioni per dispositivi mobili con sistema operativo Android da fonti diverse da Google Play, prestando particolare attenzione ai diritti richiesti dall'applicazione;
- installare regolarmente aggiornamenti del sistema operativo Android;
- prestare attenzione alle estensioni dei file caricati;
- non visitare risorse sospette;
- non cliccare sui link ricevuti nei messaggi SMS.
Con la partecipazione di Semi di Rogachev, specialista junior nella ricerca di codice dannoso del Laboratorio di informatica forense Group-IB.
Fonte: habr.com
