So nutzt der Android-Trojaner Gustuff Ihre Konten für Fiat und Krypto

So nutzt der Android-Trojaner Gustuff Ihre Konten für Fiat und Krypto

Vor kurzem berichtete Group-IB über die Aktivitäten des mobilen Android-Trojaners Gustuff. Dieser Trojaner operiert ausschließlich auf internationalen Märkten und greift Kunden von 100 der größten ausländischen Banken, Nutzer von 32 mobilen Krypto-Wallets sowie große E-Commerce-Plattformen an. Der Entwickler von Gustuff ist ein russischsprachiger Cyberkrimineller mit dem Spitznamen Bestoffer. Noch vor kurzer Zeit lobte er seinen Trojaner als "ein ernstzunehmendes Produkt für Menschen mit Wissen und Erfahrung".

Der Malware-Analytiker bei Group-IB Ivan Pisarev erläutert in seiner Untersuchung ausführlich, wie Gustuff funktioniert und welche Gefahren von ihm ausgehen.

Wer ist das Ziel von Gustuff?

Gustuff gehört zur neuen Generation von Malware mit vollständig automatisierten Funktionen. Laut dem Entwickler stellt der Trojaner eine verbesserte Version der Malware AndyBot dar, die seit November 2017 Smartphones mit Android angreift und Geld über Phishing-Webformulare stiehlt, die sich als mobile Anwendungen bekannter internationaler Banken und Zahlungsdienstleister tarnen. Bestoffer gab an, dass die Mietpreise für den "Gustuff Bot" 800 $ pro Monat betrugen.

Die Analyse des Gustuff-Samples hat gezeigt, dass die potenzielle Trojaner-Zielgruppe Kunden sind, die mobile Anwendungen der größten Banken wie Bank of America, Bank of Scotland, J.P. Morgan, Wells Fargo, Capital One, TD Bank und PNC Bank nutzen, sowie auf Krypto-Wallets wie Bitcoin Wallet, BitPay, Cryptopay, Coinbase und weitere.

Ursprünglich als klassischer Bank-Trojaner entwickelt, hat Gustuff in der aktuellen Version die Liste der potenziellen Angriffsziele erheblich erweitert. Neben Android-Anwendungen von Banken, Fintech-Unternehmen und Krypto-Diensten zielt Gustuff auf Nutzer von Anwendungen von Marktplätzen, Online-Shops, Zahlungssystemen und Messengern ab. Insbesondere PayPal, Western Union, eBay, Walmart, Skype, WhatsApp, Gett Taxi, Revolut und weitere.

Einstiegspunkt: Die Absicht, massenhafte Infektionen zu erzielen.

Gustuff zeichnet sich durch einen „klassischen“ Angriffswinkel auf Android-Smartphones über SMS-Nachrichten mit Links zu APKs aus. Bei der Infektion eines Android-Geräts kann der Trojaner auf Befehl des Servers eine weitere Verbreitung von Gustuff in den Kontaktverzeichnissen des infizierten Telefons oder in der Datenbank des Servers auslösen. Die Funktionalitäten von Gustuff sind auf eine massenhafte Infektion und maximale Kapitalisierung der Geschäfte seiner Betreiber ausgelegt – es gibt eine einzigartige Funktion zum „Auto-Upload“ in legale mobile Banking-Apps und Krypto-Wallets, die den Diebstahl von Geld beschleunigt und skaliert.

Die Untersuchung des Trojaners ergab, dass die Auto-Upload-Funktion mithilfe des Accessibility Service implementiert wurde – einem Dienst für Menschen mit Behinderungen. Gustuff ist nicht der erste Trojaner, der erfolgreich den Schutz vor Interaktionen mit Elementen anderer Anwendungen über diesen Android-Dienst umgeht. Die Verwendung des Accessibility Service in Kombination mit Auto-Upload bleibt jedoch nach wie vor ein relativ seltenes Phänomen.

Nachdem Gustuff auf das Telefon des Opfers heruntergeladen wurde, kann es mithilfe des Accessibility Service mit den Elementen der Fenstern anderer Anwendungen (Banken, Kryptowährungen, Online-Shopping, Messaging usw.) interagieren und die für die Angreifer erforderlichen Aktionen ausführen. Zum Beispiel kann der Trojaner auf Befehl des Servers Knöpfe drücken und Werte in Textfeldern von Bankanwendungen ändern. Die Nutzung des Accessibility Service ermöglicht es dem Trojaner, die Schutzmechanismen zu umgehen, die Banken zur Bekämpfung von älteren mobilen Trojanern eingerichtet haben, sowie Änderungen in den Sicherheitsrichtlinien, die Google in neuen Versionen des Android-Betriebssystems implementiert hat. So kann Gustuff zum Beispiel Google Protect deaktivieren: Laut dem Entwickler funktioniert diese Funktion in 70% der Fälle.

So nutzt der Android-Trojaner Gustuff Ihre Konten für Fiat und Krypto

Gustuff kann gefälschte PUSH-Benachrichtigungen mit Icons legitimer mobiler Anwendungen anzeigen. Der Benutzer klickt auf die PUSH-Benachrichtigung und sieht ein vom Server geladenes Phishing-Fenster, in das er seine Bankkarten- oder Krypto-Wallet-Daten eingibt. In einem anderen Szenario wird die App geöffnet, von der die PUSH-Benachrichtigung angezeigt wurde. In diesem Fall kann die Malware auf Befehl des Servers über den Accessibility Service die Formularfelder der Bankanwendung für eine betrügerische Transaktion ausfüllen.

Zu den Funktionen von Gustuff gehört auch das Senden von Informationen über das infizierte Gerät an den Server, die Möglichkeit, SMS-Nachrichten zu lesen/zu senden, das Senden von USSD-Anfragen, das Starten eines SOCKS5-Proxys, das Klicken auf Links, das Senden von Dateien (einschließlich Fotokopien von Dokumenten, Screenshots, Fotos) an den Server sowie das Zurücksetzen des Geräts auf die Werkseinstellungen.

Analyse der Malware

Vor der Installation der schädlichen Anwendung zeigt das Android-Betriebssystem dem Benutzer ein Fenster mit einer Liste der von Gustuff angeforderten Berechtigungen an:

So nutzt der Android-Trojaner Gustuff Ihre Konten für Fiat und Krypto
Die Installation der Anwendung erfolgt erst nach Zustimmung des Nutzers. Nach dem Start zeigt die Anwendung dem Nutzer ein Fenster an:

So nutzt der Android-Trojaner Gustuff Ihre Konten für Fiat und Krypto
Anschließend entfernt sie ihr Symbol.

Laut dem Autor wird Gustuff von einem FTT-Packer verpackt. Nach dem Start kontaktiert die Anwendung regelmäßig den CnC-Server, um Befehle zu erhalten. In mehreren von uns untersuchten Dateien wurde die IP-Adresse als Steuerungsserver verwendet 88.99.171[.]105 (im Folgenden bezeichnen wir dies als <%CnC%>).

Nach dem Start beginnt das Programm, Nachrichten an den Server zu senden http:///api/v1/get.php.

Als Antwort wird JSON im folgenden Format erwartet:

{
    "results" : "OK",
    "command":{
        "id": "",
        "command":"",
        "timestamp":"",
        "params":{
		
        },
    },
}

Bei jedem Zugriff sendet die Anwendung Informationen über das infizierte Gerät. Das Format der Nachricht ist unten dargestellt. Es ist zu beachten, dass die Felder full, extra, Apps und permission – optional sind und nur im Falle eines Anforderungsbefehls vom CnC gesendet werden.

{
 "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":
} 

Speicherung von Konfigurationsdaten

Gustuff speichert wichtige Informationen in einer Preference-Datei. Der Dateiname sowie die Parameternamen sind das Ergebnis der Berechnung des MD5-Hashes der Zeichenfolge 15413090667214.6.1, wobei <%name%> — ursprünglicher Name-Wert. Python-Interpretation der Funktion zur Generierung des Namens:

 nameGenerator(input):
    output = md5("15413090667214.6.1" + input) 

Im Folgenden bezeichnen wir als nameGenerator(input).
Somit ist der Name der ersten Datei: nameGenerator(«API_SERVER_LIST»), sie enthält Werte mit den folgenden Namen:

VariablennameBedeutung
nameGenerator(«API_SERVER_LIST»)Enthält eine Liste der CnC-Adressen in Form eines Arrays.
nameGenerator(«API_SERVER_URL»)Enthält die CnC-Adresse.
nameGenerator(«SMS_UPLOAD»)Standardflag ist gesetzt. Wenn das Flag gesetzt ist, werden SMS-Nachrichten an CnC gesendet.
nameGenerator(«SMS_ROOT_NUMBER»)Die Telefonnummer, an die die vom infizierten Gerät empfangenen SMS-Nachrichten gesendet werden. Standardmäßig null.
nameGenerator(«SMS_ROOT_NUMBER_RESEND»)Das Standardflag ist zurückgesetzt. Wenn es gesetzt ist, wird die vom infizierten Gerät empfangene SMS an die Root-Nummer gesendet.
nameGenerator(«DEFAULT_APP_SMS»)Das Standardflag ist zurückgesetzt. Wenn dieses Flag gesetzt ist, verarbeitet die Anwendung eingehende SMS-Nachrichten.
nameGenerator(«DEFAULT_ADMIN»)Der Standard-Flag wurde zurückgesetzt. Wenn das Flag gesetzt ist, hat die Anwendung Administratorrechte.
nameGenerator(«DEFAULT_ACCESSIBILITY»)Der Standard-Flag wurde zurückgesetzt. Wenn das Flag gesetzt ist, wird der Dienst verwendet, der den Accessibility Service nutzt.
nameGenerator(«APPS_CONFIG»)JSON-Objekt, das eine Liste von Aktionen enthält, die bei einem Accessibility-Ereignis eines bestimmten Anwendungsprogramms durchgeführt werden müssen.
nameGenerator(«APPS_INSTALLED»)Enthält die Liste der auf dem Gerät installierten Anwendungen.
nameGenerator(«IS_FIST_RUN»)Das Flag wird beim ersten Start zurückgesetzt.
nameGenerator(«UNIQUE_ID»)Enthält eine eindeutige Kennung. Sie wird beim ersten Start des Bots generiert.

Modul zur Verarbeitung von Befehlen vom Server

Die Anwendung speichert die Adressen der CnC-Server als ein Array von codierten Strings gemäß Base85 Die Liste der CnC-Server kann bei Erhalt des entsprechenden Befehls geändert werden, wobei die Adressen dann in der Preference-Datei gespeichert werden. Server Als Antwort auf Anfragen sendet der Server einen Befehl an die Anwendung. Es ist zu beachten, dass Befehle und Parameter im JSON-Format dargestellt werden. Die Anwendung kann die folgenden Befehle verarbeiten:

forwardStart

Der BefehlBeschreibung
Beginnen Sie mit der Weiterleitung der vom infizierten Gerät empfangenen SMS-Nachrichten an den CnC-Server.Начать отправление получаемых зараженным устройством SMS-сообщений на CnC-сервер.
forwardStopStoppen Sie die Übermittlung von SMS-Nachrichten, die von infizierten Geräten an den CnC-Server gesendet werden.
ussdRunFühren Sie eine USSD-Anfrage aus. Die Nummer, an die die USSD-Anfrage gesendet werden soll, befindet sich im JSON-Feld „number“.
sendSmsSenden Sie eine SMS-Nachricht (bei Bedarf wird die Nachricht in Teile unterteilt). Der Befehl akzeptiert ein JSON-Objekt mit den Feldern „to“ – Zielnummer und „body“ – Nachrichtentext.
sendSmsAbSenden Sie SMS-Nachrichten (bei Bedarf wird die Nachricht in Teile unterteilt) an alle in der Kontaktliste des infizierten Geräts. Der Abstand zwischen den gesendeten Nachrichten beträgt 10 Sekunden. Der Nachrichteninhalt befindet sich im JSON-Feld „body“.
sendSmsMassSenden Sie SMS-Nachrichten (bei Bedarf wird die Nachricht in Teile unterteilt) an die in den Befehlsparametern angegebenen Kontakte. Der Abstand zwischen den gesendeten Nachrichten beträgt 10 Sekunden. Der Befehl akzeptiert ein JSON-Array (Feld „sms“), dessen Elemente die Felder „to“ – Zielnummer und „body“ – Nachrichtentext enthalten.
changeServerDieser Befehl kann einen Parameter mit dem Schlüssel „url“ annehmen – der Bot ändert dann den Wert von nameGenerator(„SERVER_URL“), oder „array“ – der Bot speichert dann ein Array in nameGenerator(„API_SERVER_LIST“). Auf diese Weise ändert die Anwendung die Adresse der CnC-Server.
adminNummerDer Befehl ist für die Arbeit mit der Root-Nummer gedacht. Er akzeptiert ein JSON-Objekt mit den folgenden Parametern: „number“ – ändert nameGenerator(„ROOT_NUMBER“) auf den erhaltenen Wert, „resend“ – ändert nameGenerator(„SMS_ROOT_NUMBER_RESEND“), „sendId“ – sendet an nameGenerator(„ROOT_NUMBER“) uniqueID.
updateInfoInformationen über das infizierte Gerät an den Server senden.
wipeDataDer Befehl ist zum Löschen von Benutzerdaten gedacht. Je nachdem, unter welchem Namen die Anwendung gestartet wurde, erfolgt entweder eine vollständige Löschung der Daten mit einem Neustart des Geräts (primary user) oder nur das Löschen des Benutzerdaten (secondary user).
socksStartProxy-Modul starten. Die Funktionsweise des Moduls ist in einem separaten Abschnitt beschrieben.
socksStopDen Betrieb des Proxy-Moduls stoppen.
openLinkZu dem Link gehen. Der Link befindet sich im JSON-Parameter mit dem Schlüssel „url“. Zum Öffnen des Links wird „android.intent.action.VIEW“ verwendet.
alleSmsHochladenSenden Sie alle SMS-Nachrichten, die vom Gerät empfangen wurden, an den Server.
uploadAllPhotosSenden Sie die URL eines Bildes von dem infizierten Gerät. Die URL wird als Parameter übermittelt.
uploadFileSenden Sie die URL einer Datei von dem infizierten Gerät. Die URL wird als Parameter übermittelt.
uploadPhoneNumbersSenden Sie die Telefonnummern aus der Kontaktliste an den Server. Wenn ein JSON-Objekt mit dem Schlüssel «ab» als Parameter übergeben wird, erhält die Anwendung die Kontaktliste aus dem Adressbuch. Wenn ein JSON-Objekt mit dem Schlüssel «sms» übergeben wird, liest die Anwendung die Kontaktliste von den Absendern der SMS-Nachrichten.
changeArchiveDie Anwendung lädt eine Datei von der Adresse, die als Parameter mit dem Schlüssel «url» übermittelt wird. Die heruntergeladene Datei wird unter dem Namen «archive.zip» gespeichert. Danach entpackt die Anwendung die Datei und verwendet dazu gegebenenfalls das Passwort «b5jXh37gxgHBrZhQ4j3D». Die entpackten Dateien werden im Verzeichnis [external storage]/hgps gespeichert. In diesem Verzeichnis speichert die Anwendung Web-Fakes (wie nachfolgend beschrieben).
AktionenDer Befehl ist für die Arbeit mit dem Action Service vorgesehen, der in einem separaten Abschnitt beschrieben ist.
testTut nichts.
downloadDer Befehl dient zum Herunterladen einer Datei von einem entfernten Server und zum Speichern in das Verzeichnis „Downloads“. URL und Dateiname werden als Parameter übergeben, im JSON-Objekt entsprechend den Feldern: „url“ und „fileName“.
removeLöscht eine Datei aus dem Verzeichnis „Downloads“. Der Dateiname wird im JSON-Parameter mit dem Schlüssel „fileName“ übergeben. Der Standard-Dateiname ist „tmp.apk“.
notificationZeigt eine Benachrichtigung mit Beschreibungstext und Titel an, die vom Steuerung-Server festgelegt werden.

Format des Befehls notification:

{
 "results" : "OK",
 "command":{
 "id": ,
 "command":"notification",
 "timestamp":,
 "params":{
 "openApp":,
 "array":[
 {"title":,
 "desc":,
 "app":}
 ]
 },
 },
}

Die Benachrichtigung, die durch die untersuchte Datei erstellt wird, sieht identisch aus mit den Benachrichtigungen, die von der in dem Feld angegebenen Anwendung erstellt werden. app. Wenn der Wert des Feldes openApp – True, wird beim Öffnen der Benachrichtigung die angegebene Anwendung im Feld gestartet. app. Wenn der Wert des Feldes openApp – False, dann:

  • öffnet sich ein Phishing-Fenster, dessen Inhalt aus dem Verzeichnis /hgps/
  • öffnet sich ein Phishing-Fenster, dessen Inhalt vom Server geladen wird. ?id=&app=
  • Es öffnet sich ein Phishing-Fenster, das sich als Google Play Card tarnt, mit der Möglichkeit, Kartendaten einzugeben.

Das Ergebnis der Ausführung eines beliebigen Befehls wird von der Anwendung an set_state.php in Form eines JSON-Objekts des folgenden Formats gesendet:

{
    "command":
    {
        "command":,
        "id":,
        "state":
    }
    "id":
}

ActionsService
Die Liste der Befehle, die die Anwendung verarbeitet, umfasst Aktion. Bei Erhalt eines Befehls ruft das Befehlsverarbeitungsmodul diesen Dienst auf, um den erweiterten Befehl auszuführen. Der Dienst erwartet ein JSON-Objekt als Parameter. Der Dienst kann folgende Befehle ausführen:

1. PARAMS_ACTION — Bei Erhalt eines solchen Befehls erhält der Dienst zunächst den Wert des Schlüssels Type aus dem JSON-Parameter, der Folgendes sein kann:

  • serviceInfo – Der Unterbefehl erhält den Wert des Schlüssels aus dem JSON-Parameter includeNotImportant. Wenn das Flag wahr ist, setzt die Anwendung das Flag FLAG_ISOLATED_PROCESS auf den Dienst, der den Accessibility Service verwendet. Dadurch wird der Dienst in einem separaten Prozess gestartet.
  • root — Informationen über das Fenster, das derzeit im Fokus ist, an den Server senden und von diesem empfangen. Die Anwendung erhält die Informationen über die Klasse AccessibilityNodeInfo.
  • admin — Administratorrechte anfordern.
  • verzögern — den Betrieb des ActionsService für die in dem Parameter mit dem Schlüssel „data“ angegebenen Millisekunden pausieren.
  • windows — eine Liste der für den Benutzer sichtbaren Fenster senden.
  • install — die Anwendung auf ein infiziertes Gerät installieren. Der Paketname des Archivs befindet sich im Schlüssel „fileName“. Das Archiv selbst befindet sich im Verzeichnis Downloads.
  • global – Unterbefehl, der für den Wechsel vom aktuellen Fenster gedacht ist:
    • zum Menü Schnelleinstellungen
    • zurück
    • nach Hause
    • zu den Benachrichtigungen
    • zum Fenster der zuletzt geöffneten Anwendungen

  • starten — die Anwendung starten. Der Name der Anwendung wird als Parameter unter dem Schlüssel übergeben. data.
  • geräusche — den Soundmodus auf lautlos ändern.
  • entsperren — aktiviert die Beleuchtung des Bildschirms und der Tastatur auf voller Helligkeit. Die Anwendung führt diese Aktion mittels WakeLock aus und gibt den Tag [Application lable]:INFO an.
  • berechtigungsoverlay — Funktion nicht implementiert (Antwort auf die Ausführung des Befehls — {„message“:„Nicht unterstützt“} oder {„message“:„niedriger sdk“})
  • geste — Funktion ist nicht implementiert (Antwort auf den Befehl - {«message»:«Nicht unterstützt»} oder {«message»:«Niedrige API»})
  • Berechtigungen — Dieser Befehl ist erforderlich, um Berechtigungen für die Anwendung anzufordern. Da die Funktion zur Anforderung jedoch nicht implementiert ist, macht der Befehl keinen Sinn. Die angeforderten Berechtigungen werden als JSON-Array mit dem Schlüssel „permissions“ übermittelt. Standardliste:
    • 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

  • öffnen — ein Phishing-Fenster anzeigen. Je nach Parameter vom Server kann die Anwendung folgende Phishing-Fenster anzeigen:
    • Phishing-Fenster anzeigen, dessen Inhalt in einer Datei im Verzeichnis gespeichert ist /hgps/. Das Ergebnis der Interaktion des Benutzers mit dem Fenster wird an die Adresse gesendet /records.php
    • Phishing-Fenster anzeigen, dessen Inhalt zuvor von folgender Adresse geladen wird ?id=&app=. Das Ergebnis der Interaktion des Benutzers mit dem Fenster wird an die Adresse gesendet /records.php
    • Phishing-Fenster anzeigen, das als Google Play Card getarnt ist.

  • interaktiv — Das Team ermöglicht die Interaktion mit Fensterelementen anderer Anwendungen durch den AccessibilityService. Für die Interaktion wurde ein spezieller Dienst implementiert. Die untersuchte Anwendung kann mit Fenstern interagieren:
    • Aktiv zum aktuellen Zeitpunkt. In diesem Fall enthält der Parameter die ID oder den Text (Bezeichnung) des Objekts, mit dem interagiert werden soll.
    • Für den Benutzer sichtbare Fenster zum Zeitpunkt der Ausführung des Befehls. Die Anwendung wählt Fenster anhand der ID aus.

    Nachdem die Objekte AccessibilityNodeInfo für die relevanten Fensterelemente erhalten wurden, kann die Anwendung je nach Parametern folgende Aktionen ausführen:

    • focus — den Fokus auf das Objekt setzen.
    • click — auf das Objekt klicken.
    • actionId — eine Aktion anhand ID ausführen.
    • setText — den Text des Objekts ändern. Die Änderung des Texts ist auf zwei Arten möglich: durch Ausführung der Aktion ACTION_SET_TEXT wenn die Version des infizierten Android-Geräts kleiner oder gleich LOLLIPOPist, oder indem ein Text in die Zwischenablage kopiert und in das Objekt eingefügt wird (für neuere Versionen). Dieser Befehl kann verwendet werden, um Daten in einer Bankanwendung zu ändern.

2. PARAMS_ACTIONS — das Gleiche wie PARAMS_ACTION, nur als JSON-Array von Befehlen.

Es könnte viele interessieren, wie die Interaktion mit Elementen in einem anderen Anwendungsfenster aussieht. So wurde diese Funktion in Gustuff umgesetzt:

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));
}

Text ersetzende Funktion:

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;
}

Wenn der Management-Server korrekt konfiguriert ist, kann Gustuff Textfelder in der Banking-App ausfüllen und die erforderlichen Schaltflächen für Transaktionen drücken. Der Trojaner benötigt nicht einmal eine Authentifizierung in der App – es genügt, einen Befehl zur Anzeige einer PUSH-Benachrichtigung zu senden, gefolgt von dem Öffnen der zuvor installierten Banking-App. Der Benutzer authentifiziert sich selbst, wonach Gustuff den Autorefill durchführen kann.

SMS-Nachrichtenverarbeitungsmodul

Die Anwendung setzt einen Ereignishandler für den Empfang von SMS-Nachrichten durch ein infiziertes Gerät. Die untersuchte Anwendung kann Befehle vom Operator empfangen, die im Text der SMS-Nachricht enthalten sind. Die Befehle kommen im Format:

7!5=

Die Anwendung sucht in allen empfangenen SMS-Nachrichten nach der Zeichenfolge 7!5=, beim Auffinden der Zeichenfolge dekodiert sie den Base64-String ab Verschiebung 4 und führt den Befehl aus. Die Befehle sind ähnlich den CnC-Befehlen. Das Ergebnis der Ausführung wird an die gleiche Nummer gesendet, von der der Befehl kam. Das Antwortformat lautet:

7*5=

Optional kann die Anwendung alle empfangenen Nachrichten an die Root-Nummer senden. Dazu muss im Präferenzdatei die Root-Nummer angegeben und das Nachrichtenweiterleitungsflag gesetzt werden. Die SMS-Nachricht wird an die Nummer des Angreifers im Format gesendet:

Zusätzlich kann die Anwendung optional Nachrichten an das CnC senden. Die SMS-Nachricht wird im JSON-Format an den Server gesendet:

{
    "id":,
    "sms":
    {
        "text":,
        "number":,
        "date":
    }
}

Wenn das Flag gesetzt ist nameGenerator(«DEFAULT_APP_SMS») – Die Anwendung stoppt die Verarbeitung von SMS-Nachrichten und leert die Liste der empfangenen Nachrichten.

Proxy-Modul

In der untersuchten Anwendung gibt es ein Backconnect Proxy-Modul (im Folgenden Proxy-Modul), das eine separate Klasse mit statischen Feldern zur Konfiguration umfasst. Die Konfigurationsdaten werden im Sample im offenen Format gespeichert:

So nutzt der Android-Trojaner Gustuff Ihre Konten für Fiat und Krypto

Alle Aktionen, die vom Proxy-Modul durchgeführt werden, werden in Dateien protokolliert. Zu diesem Zweck erstellt die Anwendung im External Storage ein Verzeichnis mit dem Namen „logs“ (Feld ProxyConfigClass.logsDir in der Konfigurationsklasse), in dem die Protokolldateien gespeichert werden. Die Protokollierung erfolgt in Dateien mit den Namen:

  1. main.txt – In diese Datei wird die Arbeit der Klasse CommandServer protokolliert. Die Protokollierung der Zeichenfolge str in diese Datei bezeichnen wir künftig als mainLog(str).
  2. session-<%id%>.txt — In diese Datei werden die Protokolldaten zu einer bestimmten Proxy-Sitzung gespeichert. Die Protokollierung der Zeichenfolge str in diese Datei bezeichnen wir künftig als sessionLog(str).
  3. server.txt – In diese Datei werden alle Daten protokolliert, die in die oben beschriebenen Dateien geschrieben werden.

Format der Protokolldaten:

<te%> [Thread[<%thread id%>], id[]]: log-string

Die während des Betriebs des Proxy-Moduls auftretenden Ausnahmen werden ebenfalls in eine Datei protokolliert. Zu diesem Zweck erstellt die Anwendung ein JSON-Objekt im folgenden Format:

{
 "uncaughtException":
 "thread":
 "message":
 "trace": //Stack-Traces-Information
 [
 {
 "ClassName":
 "FileName":
 "LineNumber":
 "MethodName":
 },
 {
 "ClassName":
 "FileName":
 "LineNumber":
 "MethodName":
 }
 ]
}

Anschließend wird es in eine Zeichenfolgendarstellung umgewandelt und protokolliert.

Der Start des Proxy-Moduls erfolgt nach Empfang des entsprechenden Befehls. Bei Erhalt des Startbefehls für das Proxy-Modul startet die Anwendung den Dienst mit dem Namen MainService, der für die Verwaltung des Betriebs des Proxy-Moduls – dessen Start und Stopp – verantwortlich ist.

Die Phasen des Dienststarts:

1. Ein Timer wird gestartet, der einmal pro Minute ausgelöst wird und die Aktivität des Proxy-Moduls überprüft. Wenn das Modul inaktiv ist, wird es gestartet.
Beim Auslösen des Ereignisses android.net.conn.CONNECTIVITY_CHANGE wird das Proxy-Modul gestartet.

2. Die Anwendung erstellt ein Wake-Lock mit dem Parameter PARTIAL_WAKE_LOCK und erwirbt es. So wird verhindert, dass die CPU des Geräts in den Schlafmodus wechselt.

3. Startet die Klasse für die Befehlsverarbeitung des Proxy-Moduls, nachdem die Zeile protokolliert wurde. mainLog("Server starten") und

Server::start() host[], commandPort[], proxyPort[]

wobei proxy_cnc, command_port und proxy_port – Parameter, die aus der Konfiguration des Proxy-Servers erhalten wurden.

Die Klasse für die Befehlsverarbeitung trägt den Namen CommandConnection. Unmittelbar nach dem Start führt sie die folgenden Aktionen aus:

4. Stellt eine Verbindung zu ProxyConfigClass.host: ProxyConfigClass.commandPort her und sendet die Daten über das infizierte Gerät im JSON-Format:

{
    "id":,
    "imei":,
    "imsi":,
    "model":,
    "manufacturer":,
    "androidVersion":,
    "country":,
    "partnerId":,
    "packageName":,
    "networkType":,
    "hasGsmSupport":,
    "simReady":,
    "simCountry":,
    "networkOperator":,
    "simOperator":,
    "version":
}

Wobei:

  • id – Identifikator, versucht den Wert mit dem Feld „id“ aus der Shared Preference-Datei mit dem Namen „x“ zu erhalten. Wenn dieser Wert nicht abgerufen werden kann, wird ein neuer generiert. Auf diese Weise hat das Proxy-Modul seine eigene Identifikation, die ähnlich wie die Bot-ID erzeugt wird.
  • imei — IMEI des Geräts. Wenn während der Abfrage des Wertes ein Fehler aufgetreten ist, wird an dieser Stelle eine Fehlermeldung angezeigt.
  • imsi — Internationale mobile Teilnehmeridentität des Geräts. Wenn während der Abfrage des Wertes ein Fehler aufgetreten ist, wird an dieser Stelle eine Fehlermeldung angezeigt.
  • model — Der für den Endbenutzer sichtbare Name des Endprodukts.
  • manufacturer — Der Hersteller des Produkts/Hardware (Build.MANUFACTURER).
  • androidVersion — Zeichenfolge im Format « (), »
  • country — Aktueller Standort des Geräts.
  • partnerId – leere Zeichenfolge.
  • packageName – Paketname.
  • networkType — Typ der aktuellen Netzwerkverbindung (Beispiel: «WIFI», «MOBILE»). Im Falle eines Fehlers wird null zurückgegeben.
  • hasGsmSupport – true – wenn das Telefon GSM unterstützt, andernfalls false.
  • simReady – Zustand der SIM-Karte.
  • simCountry — ISO-Code des Landes (basierend auf dem SIM-Kartenanbieter).
  • networkOperator — Name des Betreibers. Wenn während der Abfrage des Wertes ein Fehler aufgetreten ist, wird an dieser Stelle eine Fehlermeldung angezeigt.
  • simOperator — Der Dienstanbieternamen (SPN). Wenn während der Abfrage des Wertes ein Fehler aufgetreten ist, wird an dieser Stelle eine Fehlermeldung angezeigt.
  • Version — dieses Feld wird in der Konfigurationsklasse gespeichert, für die betrachteten Bot-Versionen war es gleich „1.6“.

5. Wechselt in den Wartemodus auf Befehle vom Server. Befehle vom Server werden im Format empfangen:

  • 0 offset – Befehl
  • 1 offset – sessionId
  • 2 offset – Länge
  • 4 offset — Daten

Bei Empfang eines Befehls protokolliert die Anwendung:
mainLog(„Header { sessionId<%id%>], type[<%command%>], length[<%length%>] }“)

Folgende Befehle vom Server sind möglich:

NameBefehlDataBeschreibung
connectionId0Verbindungs-IDEine neue Verbindung erstellen
SLEEP3ZeitDen Proxy-Modulbetrieb pausieren
PING_PONG4Sende PONG-Nachricht

Die PONG-Nachricht besteht aus 4 Bytes und sieht wie folgt aus: 0x04000000.

Beim Empfang des Befehls connectionId (zur Erstellung einer neuen Verbindung) CommandConnection wird eine Instanz der Klasse ProxyConnection.

  • Bei der Proxyschaltung sind zwei Klassen beteiligt: ProxyConnection und end. Bei der Erstellung der Klasse ProxyConnection wird eine Verbindung zur Adresse ProxyConfigClass.host: ProxyConfigClass.proxyPort hergestellt und ein JSON-Objekt übergeben:

 {
    "id":<%connectionId%>
}

Als Antwort sendet der Server eine SOCKS5-Nachricht, die die Adresse des Remote-Servers enthält, mit dem eine Verbindung hergestellt werden muss. Die Interaktion mit diesem Server erfolgt über die Klasse end. Schematisch kann die Verbindungsherstellung wie folgt betrachtet werden:

So nutzt der Android-Trojaner Gustuff Ihre Konten für Fiat und Krypto

Netzwerkinteraktionen

Um die Analyse des Datenverkehrs durch Netzwerk-Sniffer zu verhindern, kann die Interaktion zwischen dem CnC-Server und der Anwendung durch das SSL-Protokoll geschützt werden. Alle übertragenen Daten, sowohl vom Server als auch zum Server, werden im JSON-Format dargestellt. Während des Betriebs führt die Anwendung die folgenden Anfragen durch:

  • http:///api/v1/set_state.php — das Ergebnis der Ausführung des Befehls.
  • http:///api/v1/get.php — das Abrufen eines Befehls.
  • http:///api/v1/load_sms.php — das Herunterladen von SMS-Nachrichten vom infizierten Gerät.
  • http:///api/v1/load_ab.php — das Herunterladen der Kontaktliste vom infizierten Gerät.
  • http:///api/v1/aevents.php – die Anfrage wird bei der Aktualisierung der im Preference-File befindlichen Parameter ausgeführt.
  • http:///api/v1/set_card.php — das Herunterladen von Daten, die über ein Phishing-Fenster erhalten wurden, das sich als Google Play Market tarnt.
  • http:///api/v1/logs.php – das Herunterladen von Log-Daten.
  • http:///api/v1/records.php – das Herunterladen von Daten, die über Phishing-Fenster erlangt wurden.
  • http:///api/v1/set_error.php – Benachrichtigung über einen aufgetretenen Fehler.

Empfehlungen

Um ihre Kunden vor der Bedrohung durch mobile Trojaner zu schützen, müssen Unternehmen umfassende Lösungen einsetzen, die ohne Installation zusätzlicher Software auf den Endgeräten der Nutzer schädliche Aktivitäten überwachen und warnen können.

Dazu müssen die signaturbasierten Methoden zur Erkennung mobiler Trojaner durch Verhaltensanalysen sowohl des Clients als auch der Applikation verstärkt werden. Der Schutz sollte zudem eine Funktion zur Identifizierung von Geräten mithilfe der digitalen Fingerprint-Technologie umfassen, sodass erkannt werden kann, wenn ein Konto von einem atypischen Gerät genutzt wird, das bereits in die Hände von Betrügern gefallen ist.

Ein entscheidender Aspekt ist die Möglichkeit zur kanalübergreifenden Analyse, die es Unternehmen ermöglicht, Risiken zu kontrollieren, die nicht nur im Internet-, sondern auch im Mobilkanal entstehen, beispielsweise in mobilen Banking-Anwendungen, bei Kryptowährungstransaktionen und in allen anderen Bereichen, in denen finanzielle Transaktionen stattfinden können.

Sicherheitsregeln für Nutzer:

  • Installieren Sie keine Anwendungen für das Android-Betriebssystem aus anderen Quellen als Google Play und achten Sie besonders auf die angeforderten Berechtigungen der Apps.
  • Installieren Sie regelmäßig Updates für das Android-Betriebssystem.
  • Achten Sie auf die Dateierweiterungen heruntergeladener Dateien.
  • Besuchen Sie keine verdächtigen Websites.
  • Klicken Sie nicht auf Links, die Sie in SMS-Nachrichten erhalten.

Beteiligt an Semena Rogacheva, Junior Malware Research Specialist in der Computerforensik-Labor von Group-IB.

Quelle: habr.com

Kaufen Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Server 🔥 Kaufen Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Server | ProHoster