
Erst neulich
berichtete Group-IB
ĂŒber die AktivitĂ€ten des Android-Handys Trojan Gustuff. Es funktioniert ausschlieĂlich auf internationalen MĂ€rkten und greift Kunden der 100 gröĂten auslĂ€ndischen Banken, Benutzer von 32 mobilen Krypto-Geldbörsen sowie groĂe E-Commerce-Ressourcen an. Aber der Entwickler von Gustuff ist ein russischsprachiger Cyberkrimineller unter dem Spitznamen Bestoffer. Bis vor kurzem lobte er seinen Trojaner als "ein ernstes Produkt fĂŒr Menschen mit Wissen und Erfahrung".
Ivan Pisarev, ein Spezialist fĂŒr die Analyse von Group-IB-Schadcode, berichtet in seiner Forschung ausfĂŒhrlich darĂŒber, wie Gustuff funktioniert und welche Gefahr es birgt.
FĂŒr wen jagt Gustuff?
Gustuff ist eine neue Generation von Malware mit vollautomatischen Funktionen. Laut dem Entwickler ist der Trojaner eine neue, verbesserte Version der AndyBot-Malware, die seit November 2017 Android-Telefone angreift und Geld durch Phishing-Webformulare stiehlt, die sich als mobile Anwendungen bekannter internationaler Banken und Zahlungssysteme tarnen. Bestoffer berichtete, dass der Mietpreis fĂŒr Gustuff Bot 800 USD pro Monat betrug.
Die Analyse der Gustuff-Stichprobe ergab, dass der Trojaner potenziell auf Kunden ausgerichtet ist, die mobile Anwendungen der gröĂten Banken wie der Bank of America, der Bank of Scotland, JP Morgan, Wells Fargo, Capital One, der TD Bank, der PNC Bank sowie der Bitcoin Wallet- und BitPay-Krypto-Geldbörsen verwenden , Cryptopay, Coinbase usw.
UrsprĂŒnglich als klassischer Bankentrojaner entwickelt, hat die aktuelle Version von Gustuff die Liste der potenziellen Angriffsziele erheblich erweitert. Neben Android-Anwendungen von Banken, Fintech-Unternehmen und Kryptodiensten richtet sich Gustuff an Benutzer von Marktplatzanwendungen, Online-Shops, Zahlungssystemen und Instant Messenger. 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-Mailing mit Links zu APKs aus. Wenn das Android-GerĂ€t auf Befehl des Servers mit einem Trojaner infiziert ist, 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 hat die einzigartige Funktion, legitime Mobile-Banking-Anwendungen und Crypto-Wallets automatisch auszufĂŒllen, wodurch Sie den Diebstahl von Geld beschleunigen und skalieren können.
Die Studie des Trojaners zeigte, dass die Auto-Fill-Funktion mithilfe des Accessibility Service - eines Dienstes fĂŒr Menschen mit Behinderungen - implementiert wurde. Gustuff ist nicht der erste Trojaner, der den Schutz vor Interaktion mit Fensterelementen anderer Anwendungen mithilfe dieses Android-Dienstes erfolgreich umgeht. Die Verwendung des Eingabehilfedienstes in Verbindung mit dem automatischen Laden ist jedoch immer noch recht selten.
Nach dem Herunterladen des Opfers auf das Telefon erhĂ€lt Gustuff ĂŒber den Accessibility Service die Möglichkeit, mit Fensterelementen anderer Anwendungen (Banking, KryptowĂ€hrung sowie Anwendungen fĂŒr Online-Shopping, Messaging usw.) zu interagieren und die erforderlichen Aktionen fĂŒr die Angreifer auszufĂŒhren. Auf Befehl des Servers kann der Trojaner beispielsweise auf SchaltflĂ€chen klicken und die Werte von Textfeldern in Bankanwendungen Ă€ndern. Durch die Verwendung des Accessibility Service-Mechanismus kann der Trojaner die Schutzmechanismen umgehen, mit denen Banken mobilen Trojanern der vorherigen Generation entgegenwirken, sowie Ănderungen der Sicherheitsrichtlinien, die Google in neuen Versionen des Android-Betriebssystems eingefĂŒhrt hat. Gustuff "weiĂ also", wie man den Google Protect-Schutz deaktiviert: Laut Autor funktioniert diese Funktion in 70% der FĂ€lle.

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 das er selbst die angeforderten Daten einer Bankkarte oder einer Krypto-Brieftasche eingibt. In einem anderen Gustuff-Szenario wird eine Anwendung geöffnet, fĂŒr die eine PUSH-Benachrichtigung angezeigt wurde. In diesem Fall kann das Schadprogramm 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ören auch das Senden von Informationen ĂŒber ein infiziertes GerĂ€t an den Server, das Lesen / Senden von SMS-Nachrichten, das Senden von USSD-Anforderungen, das Starten von SOCKS5 Proxy, das Folgen des Links sowie das Senden von Dateien (einschlieĂlich Fotoscans von Dokumenten, Screenshots, Fotos) an den Server Setzen Sie das GerĂ€t auf die Werkseinstellungen zurĂŒck.
Malware-Analyse
Vor der Installation einer schÀdlichen Anwendung zeigt das Android-Betriebssystem dem Benutzer ein Fenster mit einer Liste der von Gustuff angeforderten Rechte an:
Die Installation der Anwendung erfolgt erst nach Zustimmung des Benutzers. Nach dem Start der Anwendung zeigt der Trojaner dem Benutzer ein Fenster:
Dann wird das Symbol gelöscht.
Gustuff wird laut Autor von einem FTT-Packer verpackt. Nach dem Start greift die Anwendung regelmĂ€Ăig auf den CnC-Server zu, um Befehle zu empfangen. In mehreren untersuchten Dateien wurde die IP-Adresse
88.99.171 [.] 105 als Steuerungsserver verwendet (im Folgenden wird sie als
<% CnC%> bezeichnet ).
Nach dem Start sendet das Programm Nachrichten an den Server
http: // <% CnC%> /api/v1/get.php .
Als Antwort wird JSON im folgenden Format erwartet:
{ "results" : "OK", "command":{ "id": "<%id%>", "command":"<%command%>", "timestamp":"<%Server Timestamp%>", "params":{ <%Command parameters as JSON%> }, }, }
Jedes Mal, wenn die Anwendung Informationen ĂŒber ein infiziertes GerĂ€t sendet. Das Format der Nachricht ist unten dargestellt. Es ist zu beachten, dass die
vollstÀndigen ,
zusÀtzlichen ,
Apps- und
Berechtigungsfelder optional sind und nur im Falle eines Anforderungsbefehls von 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%> }
Konfigurationsdatenspeicher
Gustuff speichert wichtige Arbeitsinformationen in einer Einstellungsdatei. Der Dateiname sowie die darin enthaltenen Parameternamen sind das Ergebnis der Berechnung der MD5-Summe aus der Zeile
15413090667214.6.1 <% name%> , wobei
<% name%> der ursprĂŒngliche Namenswert ist. Python-Interpretation der Namensgenerierungsfunktion:
nameGenerator(input): output = md5("15413090667214.6.1" + input)
Im Folgenden werden wir es als
nameGenerator (Eingabe) bezeichnen .
Daher lautet der Name der ersten Datei:
nameGenerator ("API_SERVER_LIST") und enthÀlt Werte mit den folgenden Namen:
Variablenname | Wert |
---|
nameGenerator ("API_SERVER_LIST") | EnthÀlt eine Liste von CnC-Adressen als Array. |
nameGenerator ("API_SERVER_URL") | EnthÀlt eine CnC-Adresse. |
nameGenerator ("SMS_UPLOAD") | Das Flag ist standardmĂ€Ăig gesetzt. Wenn das Flag gesetzt ist - sendet SMS-Nachrichten an CnC. |
nameGenerator ("SMS_ROOT_NUMBER") | Die 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 gelöscht. Wenn ein infiziertes GerĂ€t installiert ist und eine SMS empfĂ€ngt, wird diese an die Stammnummer gesendet. |
nameGenerator ("DEFAULT_APP_SMS") | Das Flag ist standardmĂ€Ăig gelöscht. Wenn dieses Flag gesetzt ist, verarbeitet die Anwendung eingehende SMS-Nachrichten. |
nameGenerator ("DEFAULT_ADMIN") | Das Flag ist standardmĂ€Ăig gelöscht. Wenn das Flag gesetzt ist, verfĂŒgt die Anwendung ĂŒber Administratorrechte. |
nameGenerator ("DEFAULT_ACCESSIBILITY") | Das Flag ist standardmĂ€Ăig gelöscht. Wenn das Flag gesetzt ist, wird ein Dienst gestartet, der den Eingabehilfedienst verwendet. |
nameGenerator ("APPS_CONFIG") | Das JSON-Objekt enthĂ€lt eine Liste von Aktionen, die ausgefĂŒhrt werden mĂŒssen, wenn das einer bestimmten Anwendung zugeordnete Accessibility-Ereignis ausgelöst wird. |
nameGenerator ("APPS_INSTALLED") | Speichert eine 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. Es wird beim ersten Start des Bots generiert. |
Serverbefehlsverarbeitungsmodul
Die Anwendung speichert die Adressen von CnC-Servern als Array von
Base85- codierten Zeichenfolgen. 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 Anforderung sendet der Server einen Befehl an die Anwendung. Es ist erwÀhnenswert, dass die Befehle und Parameter im JSON-Format dargestellt werden. Eine Anwendung kann die folgenden Befehle verarbeiten:
Das Team | Beschreibung |
---|
forwardStart | Beginnen Sie mit dem Senden von SMS-Nachrichten, die vom infizierten GerÀt empfangen wurden, an den CnC-Server. |
forwardStop | Senden Sie keine vom infizierten GerÀt empfangenen SMS-Nachrichten mehr an den CnC-Server. |
ussdRun | FĂŒhren Sie die USSD-Anforderung aus. Die Nummer, an die Sie eine USSD-Anfrage stellen möchten, befindet sich im JSON-Feld "Nummer". |
sendSms | Senden Sie eine SMS-Nachricht (falls erforderlich, wird die Nachricht in Teile "aufgeteilt"). Als Parameter verwendet der Befehl ein JSON-Objekt, das die Felder "to" - die Zielnummer und "body" - den Nachrichtentext enthÀlt. |
sendSmsAb | Senden Sie SMS-Nachrichten (falls erforderlich, die Nachricht wird in Teile aufgeteilt) an alle Personen aus 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 (falls erforderlich, die Nachricht wird in Teile aufgeteilt) an die in den Befehlsparametern angegebenen Kontakte. Das Intervall zwischen dem Senden von 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 Textkörper der Nachricht enthalten. |
changeServer | Dieser Befehl als Parameter kann einen Wert mit dem SchlĂŒssel "url" annehmen - dann Ă€ndert der Bot den Wert von nameGenerator ("SERVER_URL") oder "array" - dann schreibt der Bot das Array in nameGenerator ("API_SERVER_LIST"). Daher Ă€ndert die Anwendung die Adresse von CnC-Servern. |
adminNumber | Der Befehl arbeitet mit der Stammnummer. 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"), "sendId" - an nameGenerator ("ROOT_NUMBER") senden. |
updateInfo | Senden Sie Informationen zu einem infizierten GerÀt an den Server. |
wipeData | Der Befehl dient zum Löschen von Benutzerdaten. Je nachdem, unter welchem ââNamen die Anwendung gestartet wurde, werden entweder die Daten beim Neustart des GerĂ€ts vollstĂ€ndig gelöscht (primĂ€rer Benutzer) oder nur Benutzerdaten werden gelöscht (sekundĂ€rer Benutzer). |
socksStart | Starten Sie das Proxy-Modul. Die Funktionsweise des Moduls wird in einem separaten Abschnitt beschrieben. |
socksStop | Stoppen Sie das Proxy-Modul. |
openLink | Folgen Sie dem Link. Der Link befindet sich im JSON-Parameter ĂŒber den SchlĂŒssel "url". Verwenden Sie "android.intent.action.VIEW", um den Link zu öffnen. |
uploadAllSms | Senden Sie alle vom GerÀt empfangenen SMS-Nachrichten an den Server. |
uploadAllPhotos | Senden Sie Bilder von einem infizierten GerÀt an die URL. Die URL kommt als Parameter. |
uploadFile | Senden Sie die Datei vom infizierten GerÀt an die URL. Die URL kommt als Parameter. |
uploadPhoneNumbers | Senden Sie Telefonnummern aus der Kontaktliste an den Server. Wenn ein JSON-Objekt mit dem SchlĂŒssel âabâ als Parameter angegeben wird, erhĂ€lt die Anwendung die Liste der Kontakte aus dem Telefonbuch. Wenn ein JSON-Objekt mit dem SchlĂŒssel "sms" als Parameter kommt, liest die Anwendung die Kontaktliste von den Absendern von SMS-Nachrichten. |
changeArchive | Die Anwendung lĂ€dt die Datei von der Adresse herunter, die als Parameter mit dem SchlĂŒssel "url" geliefert wird. Die heruntergeladene Datei wird unter dem Namen "archive.zip" gespeichert. Danach entpackt die Anwendung die Datei bei Bedarf mit dem Kennwort fĂŒr das Archiv âb5jXh37gxgHBrZhQ4j3Dâ. Entpackte Dateien werden im Verzeichnis [externer Speicher] / hgps gespeichert. In diesem Verzeichnis speichert die Anwendung Web-FĂ€lschungen (spĂ€ter beschrieben). |
Aktionen | Der Befehl funktioniert mit dem Aktionsdienst, der in einem separaten Abschnitt beschrieben wird. |
Test | Es macht nichts. |
herunterladen | Der Befehl dient zum Herunterladen einer Datei von einem Remote-Server und zum Speichern im Download-Verzeichnis. Die URL und der Dateiname werden als Parameter angegeben, die Felder im JSON-Objektparameter: "url" und "fileName". |
entfernen | Löscht eine Datei aus dem Download-Verzeichnis. Der Dateiname kommt im JSON-Parameter mit dem SchlĂŒssel "Dateiname". Der Standarddateiname lautet "tmp.apk". |
Benachrichtigung | Zeigen Sie eine Benachrichtigung mit vom Verwaltungsserver definierten Beschreibungs- und Titeltexten an. |
Das Format des
Benachrichtigungsbefehls lautet:
{ "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 aus mit den Benachrichtigungen, die von der im Feld "
App" angegebenen Anwendung erstellt wurden. Wenn der Wert des
openApp- Felds True ist, wird beim Ăffnen der Benachrichtigung die im
App- Feld angegebene Anwendung
gestartet . Wenn der Wert des
openApp- Felds False ist, gilt
Folgendes :
- Es öffnet sich ein Phishing-Fenster, dessen Inhalt aus dem Verzeichnis <% external storage%> / hgps / <% filename%> heruntergeladen wird
- Es öffnet sich ein Phishing-Fenster, dessen Inhalt vom Server heruntergeladen wird. <% url%>? id = <% Bot id%> & app = <% Anwendungsname%>
- Ein als Google Play Card getarntes Phishing-Fenster mit der Möglichkeit, Karteninformationen einzugeben, wird geöffnet.
Die Anwendung sendet das Ergebnis der AusfĂŒhrung eines
Befehls als JSON-Objekt im folgenden Format an
<% CnC%> \ set_state.php :
{ "command": { "command":<%command%>, "id":<%command_id%>, "state":<%command_state%> } "id":<%bot_id%> }
ActionsServiceDie Liste der Befehle, die die Anwendung verarbeitet, enthÀlt
Aktionen . Nach Erhalt eines Befehls greift das Befehlsverarbeitungsmodul auf diesen Dienst zu, um einen erweiterten Befehl auszufĂŒhren. Der Dienst akzeptiert ein JSON-Objekt als Parameter. Ein Dienst kann die folgenden Befehle ausfĂŒhren:
1. PARAMS_ACTION - Nach Erhalt eines solchen Befehls empfĂ€ngt der Dienst zunĂ€chst vom JSON-Parameter den Wert ĂŒber den TypschlĂŒssel.
Dies kann wie folgt sein:
- serviceInfo - Der Unterbefehl empfĂ€ngt vom JSON-Parameter den Wert des SchlĂŒssels includeNotImportant . Wenn das Flag True ist, setzt die Anwendung das FLAG_ISOLATED_PROCESS- Flag auf einen Dienst, der den Accessibility Service verwendet. Daher wird der Dienst in einem separaten Prozess gestartet.
- root - Informationen ĂŒber das Fenster abrufen und an den Server senden, das jetzt im Fokus steht. Eine Anwendung ruft Informationen mithilfe der AccessibilityNodeInfo-Klasse ab.
- admin - Administratorrechte anfordern.
- delay - Unterbricht den ActionsService fĂŒr die Anzahl der Millisekunden, die im Parameter mit dem SchlĂŒssel "data" angegeben sind.
- Windows - Senden Sie eine Liste der fĂŒr den Benutzer sichtbaren Fenster.
- install - Installiert die Anwendung auf einem infizierten GerĂ€t. Der Name des Paketarchivs befindet sich im SchlĂŒssel "Dateiname". Das Archiv selbst befindet sich im Download-Verzeichnis.
- global - Der Unterbefehl dient zum Ăbergang vom aktuellen Fenster:
- im MenĂŒ Schnelleinstellungen
- zurĂŒck
- nach Hause
- zu Benachrichtigungen
- zum Fenster der kĂŒrzlich geöffneten Anwendungen
- Starten - Starten Sie die Anwendung. Der Name der Anwendung wird vom DatenschlĂŒssel als Parameter angegeben.
- Sounds - Ăndern Sie den Soundmodus in Stille.
- entsperren - schaltet die Hintergrundbeleuchtung des Bildschirms und der Tastatur bei voller Helligkeit ein. Die Anwendung fĂŒhrt diese Aktion mit WakeLock aus, der Zeichenfolge [Application lable]: INFO
- BerechtigungsĂŒberlagerung - Die Funktion ist nicht implementiert (die Antwort auf die BefehlsausfĂŒhrung lautet {"message": "Not support"} oder {"message": "low sdk"}).
- Geste - Die Funktion ist nicht implementiert (die Antwort auf die AusfĂŒhrung des Befehls lautet {"message": "Not support"} oder {"message": "Low API"}).
- Berechtigungen - Dieser Befehl ist erforderlich, um Berechtigungen fĂŒr die Anwendung anzufordern. Die Abfragefunktion ist jedoch nicht implementiert, sodass der Befehl keinen Sinn ergibt. Die Liste der angeforderten Rechte wird als JSON-Array mit dem SchlĂŒssel "Berechtigungen" 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
- Ăffnen - Zeigt ein Phishing-Fenster an. AbhĂ€ngig vom vom Server kommenden Parameter zeigt die Anwendung möglicherweise die folgenden Phishing-Fenster an:
- Zeigen Sie ein Phishing-Fenster an, dessen Inhalt in die Datei im Verzeichnis <% externes Verzeichnis%> / hgps / <% param_filename%> geschrieben ist . Das Ergebnis der Benutzerinteraktion mit dem Fenster wird an <% CnC%> / records.php gesendet
- Zeigen Sie ein Phishing-Fenster an, dessen Inhalt von der Adresse <% url_param%> vorinstalliert ist . Id = <% bot_id%> & app = <% packagename%> . Das Ergebnis der Benutzerinteraktion mit dem Fenster wird an <% CnC%> / records.php gesendet
- Phishing-Fenster als Google Play Card verkleidet anzeigen.
- Interaktiv - Der Befehl dient zur Interaktion mit Fensterelementen anderer Anwendungen mithilfe von AcessibilityService. FĂŒr die Interaktion ist ein spezieller Service im Programm implementiert. Die untersuchte Anwendung kann mit den Fenstern interagieren:
- Im Moment aktiv. In diesem Fall enthÀlt der Parameter die ID oder den Text (Namen) des Objekts, mit dem interagiert werden muss.
- Sichtbar fĂŒr den Benutzer zum Zeitpunkt der AusfĂŒhrung des Befehls. Die Anwendung wĂ€hlt Fenster anhand ihrer ID aus.
Nachdem die Anwendung AccessibilityNodeInfo- Objekte fĂŒr interessierende Fensterelemente erhalten hat, kann sie abhĂ€ngig von den Parametern folgende Aktionen ausfĂŒhren:
- Fokus - Setzen Sie den Fokus auf das Objekt.
- Klicken - Klicken Sie auf ein Objekt.
- actionId - fĂŒhrt eine Aktion nach ID aus.
- setText - Ăndert den Text des Objekts. Sie können den Text auf zwei Arten Ă€ndern: FĂŒhren Sie die Aktion ACTION_SET_TEXT aus (wenn die Android-Version des infizierten GerĂ€ts jĂŒnger oder gleich LOLLIPOP ist ) oder indem Sie eine Zeile in die Zwischenablage einfĂŒgen und in das Objekt einfĂŒgen (fĂŒr Ă€ltere Versionen). Mit diesem Befehl können Sie Daten in einer Bankanwendung Ă€ndern.
2. PARAMS_ACTIONS - Wie bei
PARAMS_ACTION wird nur das JSON-Befehlsarray
geliefert .
Es scheint, dass viele 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);
Wenn der Steuerungsserver korrekt konfiguriert ist, kann Gustuff die Textfelder in der Bankanwendung ausfĂŒllen und auf die fĂŒr die Transaktion erforderlichen SchaltflĂ€chen klicken. Der Trojaner muss nicht einmal in der Anwendung autorisiert sein. Senden Sie einfach einen Befehl, um die PUSH-Benachrichtigung zu demonstrieren, und öffnen Sie anschlieĂend die zuvor installierte Bankanwendung. Der Benutzer durchlĂ€uft eine Autorisierung, nach der Gustuff automatisch ausfĂŒllen kann.
SMS-Verarbeitungsmodul
Die Anwendung legt fest, dass der Ereignishandler SMS-Nachrichten vom infizierten GerÀt akzeptiert. Die untersuchte Anwendung kann Befehle vom Bediener empfangen, die in SMS-Nachrichten enthalten sind. Befehle kommen im Format:
7! 5 = <% Base64-codierter Befehl%>Die Anwendung sucht in allen eingehenden SMS-Nachrichten nach der Zeichenfolge
7! 5 = Wenn sie eine Zeichenfolge erkennt, dekodiert sie eine Base64-Zeichenfolge mit Offset 4 und fĂŒhrt den Befehl aus. Befehle Ă€hneln Befehlen mit CnC. Das Ergebnis der AusfĂŒhrung wird an dieselbe Nummer gesendet, von der der Befehl stammt. Antwortformat:
7 * 5 = <% Base64-Codierung des Befehls "result_code"%>Optional kann die Anwendung alle empfangenen Nachrichten an die Stammnummer senden. Dazu muss in der Voreinstellungsdatei eine Stammnummer angegeben und das Flag fĂŒr die Nachrichtenumleitung gesetzt sein. Eine SMS-Nachricht wird im folgenden Format an die Angreifernummer gesendet:
<% Von Nummer%> - <% Zeit, Format: TT / MM / JJJJ HH: MM: SS%> <% SMS-Text%>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
nameGenerator ("DEFAULT_APP_SMS") gesetzt ist, beendet die Anwendung die Verarbeitung von SMS-Nachrichten und löscht die Liste der eingehenden Nachrichten.
Proxy-Modul
In der untersuchten Anwendung gibt es ein Backconnect-Proxy-Modul (im Folgenden als Proxy-Modul bezeichnet), das eine separate Klasse enthÀlt, die statische Felder mit Konfiguration enthÀlt. Die Konfigurationsdaten werden in offener Form im Beispiel gespeichert:
Alle vom Proxy-Modul ausgefĂŒhrten Aktionen werden in Dateien protokolliert. Zu diesem Zweck erstellt die Anwendung im externen Speicher ein Verzeichnis mit dem Namen "logs" (das Feld ProxyConfigClass.logsDir in der Konfigurationsklasse), in dem die Protokolldateien gespeichert werden. Die Protokollierung erfolgt in Dateien mit Namen:
- main.txt - Diese Klasse protokolliert den Betrieb der Klasse mit dem Namen CommandServer. Die weitere Protokollierung des Strings str in dieser Datei wird als mainLog (str) bezeichnet.
- session - <% id%>. txt - Die einer bestimmten Proxy-Sitzung zugeordneten Protokolldaten werden in dieser Datei gespeichert. Die weitere Protokollierung der Zeichenfolge str in dieser Datei wird als sessionLog (str) bezeichnet.
- server.txt - Diese Daten protokollieren alle Daten, die in die oben genannten Dateien geschrieben wurden.
Protokolldatenformat:
<% Date%> [Thread [<% Thread-ID%>], ID []]: Protokollzeichenfolge
Ausnahmen, die wÀhrend des Betriebs des Proxy-Moduls auftreten, werden ebenfalls in einer Datei protokolliert. Hierzu generiert die Anwendung ein JSON-Objekt im 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 konvertiert und protokolliert.
Das Proxy-Modul wird nach Erhalt des entsprechenden Teams gestartet. Wenn ein Befehl zum Starten des Proxy-Moduls
eingeht , startet die Anwendung einen Dienst namens
MainService , der fĂŒr die Steuerung des Betriebs des Proxy-Moduls verantwortlich ist - dessen Start und Stopp.
Phasen des Starts des Dienstes:
1. Startet einen Timer, der einmal pro Minute arbeitet und die AktivitĂ€t des Proxy-Moduls ĂŒberprĂŒft. Wenn das Modul nicht aktiv ist, wird es gestartet.
Wenn das Ereignis
android.net.conn.CONNECTIVITY_CHANGE ausgelöst wird, wird das Proxy-Modul
gestartet .
2. Die Anwendung erstellt mit dem Parameter
PARTIAL_WAKE_LOCK eine
Wecksperre und erfasst diese. Daher kann die CPU des GerÀts nicht in den Ruhemodus wechseln.
3. Startet die Befehlsverarbeitungsklasse fĂŒr das Proxy-Modul, indem zuerst die mainLog-Zeile
(âServer startenâ) und protokolliert werden
Server :: start () Host [<% proxy_cnc%>], commandPort [<% command_port%>], proxyPort [<% proxy_port%>]Dabei sind
proxy_cnc, command_port und proxy_port die Parameter, die aus der Proxy-Server-Konfiguration erhalten werden.
Die Befehlsverarbeitungsklasse heiĂt
CommandConnection . Unmittelbar nach dem Start werden die folgenden Aktionen ausgefĂŒhrt:
4. Stellt eine Verbindung zu
ProxyConfigClass.host :
ProxyConfigClass.commandPort her und sendet dort die 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, der versucht, den Wert mit dem Feld "id" aus der Shared Preference-Datei mit dem Namen "x" abzurufen. Wenn dieser Wert nicht erhalten werden konnte, wird ein neuer generiert. , Proxy- Ì , Ì Bot ID.
- imei â IMEI Ì. â .
- imsi â International Mobile Subscriber Identity Ì. â .
- model â The end-user-visible name for the end product.
- manufacturer â The manufacturer of the product/hardware (Build.MANUFACTURER).
- androidVersion â "<%release_version%> (<%os_version%>),<%sdk_version%>"
- country â Ì.
- partnerId â .
- packageName â package name.
- networkType â (: «WIFI», «MOBILE»). null.
- hasGsmSupport â true â GSM, false.
- simReady â SIM-.
- simCountry â ISO- ( Ì -).
- networkOperator â . â .
- simOperator â The Service Provider Name (SPN). â .
- version â -, Ì Â«1.6».
5. . :
- 0 offset â command
- 1 offset â sessionId
- 2 offset â length
- 4 offset â data
:
mainLog(«Header { sessionId<%id%>], type[<%command%>], length[<%length%>] }»):
Name | Command | Daten | Beschreibung |
---|
connectionId | 0 | Connection ID | |
SLEEP | 3 | Zeit | Proxy- |
PING_PONG | 4 | - - | PONG- |
PONG- 4 :
0x04000000 .
connectionId ( )
CommandConnection ProxyConnection .
- : ProxyConnection end . ProxyConnection ProxyConfigClass.host : ProxyConfigClass.proxyPort JSON-:
{ "id":<%connectionId%> }
SOCKS5-, , . Ì
end . :
Ì
Ì CnC- SSL. JSON-. :
- http://<%CnC%>/api/v1/set_state.php â .
- http://<%CnC%>/api/v1/get.php â .
- http://<%CnC%>/api/v1/load_sms.php â SMS-Ì Ì.
- http://<%CnC%>/api/v1/load_ab.php â Ì.
- http://<%CnC%>/api/v1/aevents.php â , preference-Ì.
- http://<%CnC%>/api/v1/set_card.php â , -, Google Play Market.
- http://<%CnC%>/api/v1/logs.php â -.
- http://<%CnC%>/api/v1/records.php â , .
- http://<%CnC%>/api/v1/set_error.php â Ì .
Empfehlungen
, , .
, . , , .
â - , , -, , , , , .
:
- Android - , Google Play;
- ;
- Android;
- ;
- ;
- , SMS-.
, Group-IB.