Analisi del trojan bancario Hydra diffuso in Italia
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.
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:
text | Utilizzato per sottrarre ed inviare messaggi di testo SMS. |
ussd | Consente al malware di utilizzare i codici USSD. Nello specifico viene utilizzato il codice *101# utilizzato per monitorare il saldo residuo. |
locker | Blocco 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“. |
injects | Gestisce le notifiche push. |
socks | Consente di utilizzare SOCKS Proxy per redirigere il traffico. |
screencast | Effettuare screencast (Android >= 5). L’immagine viene convertita in Base64 ed inviata al C2. |
soundSwitcher | Controllo della suoneria On/Off (Android >= 6). Utilizzato con “locker” |
commands | Abilita 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:
- User-Agent Android
- 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