Analisi del trojan bancario Hydra diffuso in Italia

21/09/2022

apk hydra

Recentemente D3Lab ha rilevato e condiviso con il CERT-AgID un campione di malware per dispositivi Android individuato in una campagna di smishing rivolta verso utenti italiani.

La campagna è veicolata tramite link riportato in un SMS e la pagina di download risulta visibile solo se visitata da un browser che si presenti con User-Agent Android. Come avviene in molti altri casi, il file malevolo, in questo caso un APK riconducibile a Hydra, viene scaricato dai server Discord.

Home page della pagina di download

Attraverso questa pagina la vittima viene invitata a scaricare (o aggiornare) l’app Coinbase. Se l’utente procede con il download, il dispositivo Android viene compromesso dal trojan bancario Hydra mettendo a rischio le password degli account bancari e i portafogli di criptovalute.

Il campione osservato dal CERT-AgID prende di mira 338 applicazioni bancarie e presenta funzionalità che gli consentono di prendere il controllo del dispositivo: dalla gestione completa degli SMS alla possibilità di accedere al device compromesso tramite TeamViewer, al furto del PIN ed all’interazione del bot con il C2 per ricevere comandi ed eseguire nuove istruzioni.

Nonostante questa campagna fosse rivolta ad utenti italiani, si è scoperto che il malware effettua un controllo sull’IP con cui il dispositivo è connesso a Internet per analizzarne il country code: gli unici paesi esclusi dalla compromissione sono Russia e Ucraina.

Analisi del file APK

Analizzando staticamente il codice del malware a partire dalla classe richiamata all’avvio dell’App “UYwGqFoHbXcXmZsDpMeMlPlIuCpNsFlDdXlTqQqHxQqBf“, ed in modo analogo per tutte le altre classi, è possibile osservare la presenza di una serie di funzioni più o meno simili ognuna delle quali restituisce una stringa.

In realtà, ogni funzione effettua operazioni del tutto inutili: lo scopo finale è invece quello di eseguire una operazione XOR tra due array di byte: bArr e bArr3, riportando il risultato nella variabile bArr2. In questo caso, ad esempio, la funzione advancepredict() può essere ridotta a qualcosa del tipo:

public class MyClass { public static void main(String args[]) { byte[] bArr = {94, 26, 70, 33, 86, 39, 112, 58, 93, 33, 86, 45, 71}; byte[] bArr3 = {51, 85}; byte[] bArr2 = new byte[bArr.length]; for (int i = 0; i < bArr.length; i++) { bArr2[i] = (byte) (bArr[i] ^ bArr3[i % bArr3.length]); } System.out.println(new String(bArr2)); } }

Così facendo per tutte le funzioni, ma automatizzando l’operazione con uno script python, è possibile ottenere tutte le stringhe in chiaro. In totale se ne individuano 67:

addAssetPath aaxxwdDFCxcds cxuudsjfjdfjdj read getClass plumb rescue vfsffjjjjjjjjjjjjj close vocodpsdps open close read hvchhfhddsds opdspclxldsqq vcpspdlsdlsdl Nchxydggvgd getClass wwysyahcxhgfGDG dfttrrcfsdVCv close gqFidvv getAssets vcosdYYDSHDnncx getClass write getBytes getClass rMl vcuufUUUDf cxoasjshdfhdfh vSEEEDEECEff 41122 getClass bnhfdcxfdfRRD cuvudshdhdfhdfh mOuterContext DynamicOptDex DynamicLib WH.json check the main aim mApplication mAllApplications mIniialApplicaion ok replace string bitch android.app.ConkvzGc~b story repeats android.app.ActivityThread mActivityT&U tree hash up attach mPackageInfo com.sdktools.android.App android.app.LoadedApk ivation actor tank android.app.ActivityThread android.app.LoadedApk cyyshdhvkvkckkkffd mClassLoader currentActivityThread ge get dfdfdsfdfgfgfg mPackages get order history lucky getClass get

Tra le stringhe potenzialmente interessanti, salta all’occhio “WH.json” di cui troviamo riscontro all’interno di “resources/assets” ma il contenuto del file risulta codificato.

La stringa “WH.json” è prodotta dalla funzione “demandfocus()” che viene richiamata da altre funzioni ed in fine assegnata alla variabile “RRbWcCgSuJtEyEwIsEnIbTk“. Seguendo questa variabile all’interno della classe iniziale si scopre che viene utilizzata dalla funzione makefancy e richiamata tramite sensetape.

Seguendo la funzione “sensetape()” a cui viene passata la variabile “RRbWcCgSuJtEyEwIsEnIbTk” si arriva alla funzione “taskvecome()” da cui si ottiene la stringa “rMl“, già rilevata tra le stringhe estratte in precedenza, che rappresenta la chiave RC4 da utilizzare per decodificare il file “WH.json“.

Con l’ausilio di una ricetta cyberchef è stato decodificato il file ottenendo un archivio ZIP contenente un file DEX.

Analisi del file DEX

Una volta convertito il DEX in JAR sarà possibile osservare le funzioni interne che per fortuna non presentano codifiche.

Controllo IP

Prima di dare inizio alle attività di raccolta di informazioni tipiche di Hydra, viene effettuata una richiesta verso http://ip-api.com/json per ottenere informazioni sull’IP ed in particolare sul country code del dispositivo in cui si trova in esecuzione. Queste vengono lavorate dalla funzione “DeviceInfo” che determina, tramite “isDeviceAcceptable()“, se proseguire con le operazioni successive solo se il country code è differente da “RU” o “UA“. Russia ed Ucraina sono gli unici paesi esclusi dalla compromissione.

Le componenti

Le componenti da attivare sono 8 e sono elencati all’interno della funzione “init“.

Il sample oggetto di analisi riporta come data di attivazione (unlockDate) “30-12-2016 16-00”, è la data a partire dalla quale il malware può dare inizio alle attività da infostealer ed è probabile sia stata volutamente portata indietro di sei anni poichè alcune delle funzionalità di seguito descritte sono state introdotte in Hydra di recente.

Lista delle componenti attive:

textUtilizzato per sottrarre ed inviare messaggi di testo SMS.
ussdConsente al malware di utilizzare i codici USSD. Nello specifico viene utilizzato il codice *101# utilizzato per monitorare il saldo residuo.
lockerBlocco del device. Se richiesto utilizza “soundSwhitcher” per mutare e mostra il messaggio “Android system corrupted files recovery <3e>\nKernel version 2.1.0.3\nDO NOT TURN THE SYSTEM OFF“.
injectsGestisce le notifiche push.
socksConsente di utilizzare SOCKS Proxy per redirigere il traffico.
screencastEffettuare screencast (Android >= 5). L’immagine viene convertita in Base64 ed inviata al C2.
soundSwitcherControllo della suoneria On/Off (Android >= 6). Utilizzato con “locker”
commandsAbilita il malware a ricevere comandi remoti dal C2.

Funzionalità

Le funzionalità previste di default, che abusano del servizio di accessibilità, sono le seguenti:

  • Collezione delle informazioni sul dispositivo.
  • Injection di pagine di phishing.
  • Keylogging.
  • Accesso tramite TeamViewer.
  • Acquisizione del PIN di sblocco tramite false richieste di inserimento PIN.
  • Send SMS per inviare singoli SMS o in modalità “Bulk” per inoltrali all’intera lista di contatti.
  • Gestione delle impostazioni WiFi.

I server di Command & Control

Il C2 è presente nel codice riportato in Base64 nella variabile “ADMIN_URL” all’interno della funzione “BotConfigs“.

“ADMIN_MIRRORS” decodificata da Base64 è “/api/mirrors“. Attraverso una richiesta GET il bot richiede altri C2 da contattare:

All’interno del codice è inoltre presente una funzione che riporta in chiaro 4 url relativi al pannello di amministrazione.

Comunicazione con il C2

Le informazioni inerenti le funzionalità da attivare che il malware scambia con il server sono strutturate in un file JSON il cui contenuto è codificato con una chiave XOR hardcoded.

La chiave XOR è “!8[`” ed è ottenuta estraendo i caratteri 8, 10, 16, 20 dalla stringa: “sorry!need8money[for`food“.

Per decifrare tutte le stringhe cifrate all’interno del sample è possibile utilizzare il seguente codice:

public class MyClass { private static boolean safeChar(char c) { return c <= ' ' || c > '~'; } private static char key(int i) { return "sorry!need8money[for`food".charAt(i); } public static String wrapConstant(String str) { char[] cArr = {key(5), key(10), key(16), key(20)}; StringBuilder sb = new StringBuilder(); for (int i = 0; i < str.length(); i++) { char charAt = str.charAt(i); if (safeChar(charAt)) { sb.append(charAt); } else { char c = (char) (cArr[i % 4] ^ charAt); if (safeChar(c)) { sb.append(charAt); } else { sb.append(c); } } } return sb.toString(); } public static void main(String args[]) { System.out.println(wrapConstant("TJ7")); // decoded: "url" } }

Di seguito la lista delle chiamate API al C2:

  • /api/v1/device/check
  • /api/v1/device/cookie
  • /api/v1/device/credentials
  • /api/v1/device/install
  • /api/v1/device/settings
  • /api/v1/device/update
  • /api/v1/device/server-log
  • /api/v1/device/tw-status
  • /api/v1/device/push-state
  • /api/v1/device/read-sms
  • /api/v1/device/sms
  • /api/v1/device/uusd-run
  • /api/v1/device/notification
  • /api/v1/device/lock
  • /api/v1/device/save-phone

Le azioni da compiere sono indicate all’interno del file JSON, ad esempio con la chiave “bulk_sms” viene richiesto al malware di inviare SMS alla lista di contatti.

Allo stesso modo “apks” viene utilizzato per ottenere la lista e le relative url delle app da scaricare, “remove_app_by_id” per disinstallare una app, e così via…

Lista delle App target

Il bot richiede al C2 la lista delle app target attraverso una richiesta POST a “/api/v1/device” ma, affinchè questa venga accettata dal server, l’header deve rispettare due requisiti:

  1. User-Agent Android
  2. Codice di autorizzazione

Quest’ultimo è hardcoded:

static final String PREFS_KEY_MAIN_API_URL = "sdccccsdsdcdscsdcsdcd";

La richiesta POST restituisce quindi la lista delle app target:

In totale si tratta di una lista di 338 app, per lo più app bancarie tra le quali sono presenti diverse applicazioni di istituti bancari italiani:

alior.bankingapp.android app.wizink.es ar.bapro ar.com.bcopatagonia.android ar.com.redlink.custom ar.com.santander.rio.mbanking ar.macro cash.klever.blockchain.wallet cgd.pt.caixadirectaparticulares co.bitx.android.wallet co.com.bbva.mb co.mona.android co.uk.Nationwide.Mobile com.acceltree.mtc.screens com.adcb.bank com.akbank.android.apps.akbank_direkt com.alahli.mobile.android com.alahli.quickpay com.albarakaapp com.alibaba.aliexpresshd com.alinma.retail.mobile com.ally.MobileBanking com.alrajhiretailapp com.amazon.mShop.android.shopping com.ambank.ambankonline com.americanexpress.android.acctsvcs.us com.arabbank.arabimobilev2 com.arkea.android.application.cmb com.avuscapital.trading212 com.axabanque.fr com.bancocajasocial.geolocation com.bancodebogota.bancamovil com.BankAlBilad com.BankAlBilad.EnjazApp com.bankia.wallet com.bankinter.launcher com.barclaycardus com.bbt.myfi com.bbva.bbvacontigo com.bbva.netcash com.bbva.nxt_peru com.bcp.bank.bcp com.binance.dev com.bitcoin.mwallet com.bitfinex.mobileapp com.Bither.one com.bitmarket.trader com.bitpay.wallet com.bmoharris.digital com.bnhp.payments.paymentsapp com.booking com.botw.mobilebanking com.breadwallet com.bsffm com.bsnebiz.cdb com.btcturk com.btcturk.pro com.caisseepargne.android.mobilebanking com.cajaingenieros.android.bancamovil com.cajasur.android com.cbd.mobile com.chase.sig.android com.cic_prod.bad com.cimbmalaysia com.citi.citimobile com.citi.mobile.ccc com.citibanamex.banamexmobile com.citibank.CitibankMY com.citizensbank.androidapp com.clairmail.fth com.cleverlance.csas.servis24 com.cm_prod.bad com.cmcmarkets.android.cfd com.coinbase.android com.comarch.mobile.banking.bgzbnpparibas.biznes com.comarch.security.mobilebanking com.compasssavingsbank.mobile com.conio.wallet com.connectivityapps.hotmail com.cooperativebank.bank com.db.mm.norisbank com.db.pwcc.dbmobile com.denizbank.mobildeniz com.dib.app com.discoverfinancial.mobile com.ebay.mobile com.electroneum.mobile com.engage.pbb.pbengage2my.release com.fab.personalbanking com.facebook.katana com.fi7026.godough com.fibabanka.Fibabanka.mobile com.fibi.nativeapp com.finansbank.mobile.cepsube com.finanteq.finance.bgz com.finanteq.finance.ca com.fullsix.android.labanquepostale.accountaccess com.garanti.cepsubesi com.gemini.android.app com.getingroup.mobilebanking com.goodbarber.ybrmalaysia com.google.android.gm com.grppl.android.shell.BOS com.grppl.android.shell.CMBlloydsTSB73 com.grppl.android.shell.halifax com.grupoavalav1.bancamovil com.grupoavaloc1.bancamovil com.grupocajamar.wefferent com.hittechsexpertlimited.hitbtc com.ideomobile.discount com.ideomobile.hapoalim com.ideomobile.mercantile com.ie.capitalone.uk com.iexceed.CBS com.indra.itecban.mobile.novobanco com.indra.itecban.triodosbank.mobile.banki com.indra.itecban.triodosbank.mobile.banking com.infonow.bofa com.infosys.alh com.ingbanktr.ingmobil com.key.android com.konylabs.capitalone com.konylabs.cbplpat com.konylabs.HongLeongConnect com.kraken.trade com.kubi.kucoin com.kutxabank.android com.kuveytturk.mobil com.latuabancaperandroid com.leumi.leumiwallet com.liberty.jaxx com.lynxspa.bancopopolare com.magiclick.odeabank com.mail.mobile.android.mail com.masad.nativeapp com.mbc.anb.keystore com.mcom.firstcitizens com.mediolanum com.mfoundry.mb.android.mb_136 com.microsoft.office.outlook com.MizrahiTefahot.nh com.mobillium.papara com.moneybookers.skrillpayments.neteller com.mootwin.natixis com.morganstanley.clientmobile.prod com.mtb.mbanking.sc.retail.prod com.mycelium.wallet com.myetherwallet.mewwallet com.nanooqit.economiaemail com.navyfederal.android com.nearform.ptsb com.netflix.mediaclient com.okinc.okcoin.intl com.okinc.okex.gp com.otsar.nativeapp com.pagi.nativeapp com.paribu.app com.paypal.android.p2pmobile com.plunien.poloniex com.Plus500 com.pnc.ecommerce.mobile com.polehin.android com.pozitron.iscep com.pttfinans com.rak com.rbs.mobile.android.natwest com.rbs.mobile.android.rbs com.rhbgroup.rhbmobilebanking com.riyadbank.strategic com.rsi com.sa.baj.aljazirasmart com.sabb.mobilebanking com.saib.banking.mobile.android com.saib.mobile.easypay com.samba.mb com.samsung.android.email.provider com.scb.ae.bmw com.schwab.mobile com.sella.BancaSella com.starfinanz.smob.android.sfinanzstatus com.suntrust.mobilebanking com.targo_prod.bad com.targoes_prod.bad com.tdbank com.teb com.teb.kurumsal com.tecnocom.cajalaboral com.thanksmister.bitcoin.localtrader com.tmobtech.halkbank com.todo1.davivienda.mobileapp com.todo1.mobile com.ubercab com.ubercab.eats com.ubs.swidKXJ.android com.unicredit com.uphold.wallet com.usaa.mobile.android.usaa com.vakifbank.mobile com.vakifkatilim.mobil com.vipera.chebanca com.vipera.ts.starter.MashreqAE com.wallet.crypto.trustapp com.wf.wellsfargomobile com.whatsapp com.woodforest com.wrx.wazirx com.yahoo.mobile.client.android.mail com.ykb.android com.yoox com.zellepay.zelle com.ziraat.ziraatmobil com.ziraatkatilim.mobilebanking com.zoluxiones.officebanking coop.bancocredicoop.bancamobile cz.airbank.android cz.csas.business24 cz.csas.georgego cz.csob.ceb cz.csob.smartbanking cz.csob.smartbanking.era cz.equabank.mobilebanking cz.fio.android.smartbroker cz.fio.sb2 cz.kb.mba.business cz.mbank cz.moneta.smartbanka cz.rb.app.smartphonebanking cz.seznam.email de.comdirect.android de.commerzbanking.mobil de.dkb.portalapp de.fiducia.smartphone.android.banking.vr de.ingdiba.bankingapp de.postbank.finanzassistent de.sdvrz.ihb.mobile.app enbd.mobilebanking es.bancosantander.apps es.bancosantander.empresas es.caixagalicia.activamovil es.caixaontinyent.caixaontinyentapp es.cecabank.ealia2103appstore es.cm.android es.evobanco.bancamovil es.ibercaja.ibercajaapp es.lacaixa.mobile.android.newwapicon es.liberbank.cajasturapp es.openbank.mobile es.pibank.customers es.santander.Criptocalculadora es.univia.unicajamovil eu.eleader.mobilebanking.invest eu.eleader.mobilebanking.pekao eu.inmite.prj.kb.mobilbank eu.netinfo.colpatria.system eu.unicreditgroup.hvbapptan exodusmovement.exodus finansbank.enpara finansbank.enpara.sirketim fr.banquepopulaire.cyberplus fr.bnpp.digitalbanking fr.cnaf.mobile.moncompte fr.creditagricole.androidapp fr.lcl.android.customerarea hr.asseco.android.jimba.mUCI.cz hr.asseco.android.jimba.mUCI.sme.cz huawei.settings.pin il.co.yahav.mobbanking il.co.yellow.app io.cex.app.prod io.metamask io.totalcoin.wallet it.bcc.iccrea.mycartabcc it.bnl.apps.banking it.carige it.copergmps.rt.pf.android.sp.bmps it.icbpi.mobile it.italiaonline.mail it.italiaonline.virgiliomailapp it.nogood.container it.popso.SCRIGNOapp mobile.santander.de my.com.hongleongconnect.mobileconnect my.com.hsbc.hsbcmalaysia my.com.maybank2u.m2umobile net.bitstamp.app net.bnpparibas.mescomptes net.inverline.bancosabadell.officelocator.android om.instagram.android org.electrum.electrum payumoney.merchantap pe.com.interbank.mobilebanking pe.com.scotiabank.blpm.android.client pe.pichincha.bm piuk.blockchain.android pl.aliorbank.aib pl.bph pl.bps.bankowoscmobilna pl.bzwbk.bzwbk24 pl.cinkciarz pl.envelobank.aplikacja pl.ideabank.mobilebanking pl.ing.mojeing pl.int.poczta pl.interia.poczta_next pl.mbank pl.nestbank.nestbank pl.noblebank.mobile pl.onet.mail pl.pkobp.iko pl.raiffeisen.nfc pl.sgb.wallet pl.wp.pocztao2 pl.wp.wppoczta posteitaliane.posteapp.appbpol posteitaliane.posteapp.apppostepay pt.bancobpi.mobile.fiabilizacao pt.novobanco.nbapp pt.santandertotta.mobileparticulares sa.alrajhibank.tahweelapp sa.com.se.alkahraba sa.com.stcpay samsung.settings.pass samsung.settings.pin softax.pekao.powerpay tr.com.hsbc.hsbcturkey tr.com.sekerbilisim.mbank tr.gov.turkiye.edevlet.kapisi tsb.mobilebanking uk.co.hsbc.hsbcukmobilebanking uk.co.mbna.cardservices.android uk.co.metrobankonline.mobile.android.production uk.co.santander.santanderUK uk.co.tescomobile.android uk.co.tsb.newmobilebank us.zoom.videomeetings wit.android.bcpBankingApp.millennium wit.android.bcpBankingApp.millenniumPL www.ingdirect.nativeframe

Per ogni App è disponibile un pacchetto contenente una icona (png) ed un file index.html utilizzato per sostituire la pagina originale con una falsa form di login.

Indicatori di compromissione (IoC)

Al fine di rendere pubblici i dettagli della campagna, si riportano di seguito gli IoC rilevati e già condivisi con le organizzazioni accreditate alla ricezione del flusso di IoC del CERT-AgID.

Link: Download IoC

Taggato  apk hydra