Investigación del troyano Numando
¡Hola lectores!
Hoy os traemos el análisis del troyano bancario Numando, activo desde 2018 y bautizado por los investigadores de la compañía ESET, sumándose a la lista de familias de este tipo procedentes de Latinoamérica, junto a Guildma, Javali, Melcoz, Grandoreiro, Mekotio, Casbaneiro o Janeiro, entre otros, aunque con mucha menos actividad que estos.
Aunque reutiliza secciones de código vistas anteriormente también en dichas familias, también incorpora algunas funcionalidades y peculiaridades interesantes, como aprovecharse de la estructura de ficheros comprimidos de tipo ZIP o imágenes BPM para ocultar información o el uso de sitios web públicos como YouTube para almacenar la información de sus servidores de mando y control (C2).
Su principal área de actividad se centra en Brasil, aunque también se han detectado campañas en México y España. El principal objetivo de esta investigación es ampliar la información compartida por ESET y tratar de trazar patrones que permitan localizar nuevas campañas de esta familia.
Flujos de infección y relación entre las muestras
Muestras de Numando compartidas por ESET:
Nombre |
SHA1 |
Tipo |
Firma ESET |
muestra 1 |
e69e69fbf438f898729e |
MSI downloader del “decoy ZIP” |
Win32/TrojanDownloader.Delf.CQR |
muestra 2 |
4a1c48064167fc4ad5d9 |
Instalador MSI |
Win32/Spy.Numando.BA |
muestra 3 |
bb2bbca6ca318ac0abb |
Numando |
Win32/Spy.Numando.E |
muestra 4 |
bfda3eaab63e23802ea22 |
Numando |
Win32/Spy.Numando.AL |
muestra 5 |
9a7a192b67895f63f1afdf5 |
Numando |
Win32/Spy.Numando.AO |
muestra 6 |
7789c57dcc3520d714ec7 |
DLL con imágenes para la superposición de ventanas |
Win32/Spy.Numando.P |
La cuarta muestra, marcada en rojo, no es localizada inicialmente en ninguna fuente de inteligencia pública, por lo que se desconoce a priori su función. Sin embargo, más adelante se descubre ser otra librería DLL principal de Numando proveniente de una de las URL de descarga. Tras el descubrimiento, es subida a la plataforma VirusTotal para que pueda localizarse de forma pública.
Por otra parte, el malware utiliza aplicaciones legítimas para cargarse en memoria en forma de librería DLL. Algunas de las aplicaciones legítimas utilizadas son:
Nombre |
SHA1 |
DLL de Numando cargada |
Aplicación legítima 1 |
a852a99e2982df75842ccfc274ea3f9c54d22859 |
nvsmartmax.dll |
Aplicación legítima 2 |
f804db94139b2e1d1d6a3cd27a9e78634540f87c |
mpr.dll |
Aplicación legítima 3 |
65684b3d962fb3483766f9e4a9c047c0e27f055e |
Oleacc.dll |
Para comprender cómo se relacionan todas estas muestras se procede a analizar el flujo de infección descrito por los investigadores donde indican haber observado diferentes tipos de cadenas de distribución.
Destacan un primer flujo que comienza con ficheros como el de la muestra 1. Esta es un instalador Windows de tipo MSI que contiene en su interior diferentes ficheros binarios entre los que se encuentran dos librerías DLL, una llamada aicustact.dll, que es una librería legítima para detectar cualquier conexión a Internet disponible, y, otra llamada ESCOLA.dll, que es el downloader.
La función hash SHA1 de ESCOLA.dll es: 313fbffa0be37eaf62199ddc7e0217b6e855b077
Esta librería está programada en Delphi, un lenguaje de programación típicamente utilizado también por los actores detrás de otros troyanos bancarios latinoamericanos. La librería contiene una función exportada llamada “ESPORTE” que realiza la función principal de descarga.
Tras acceder al código de esta función, se observa una cadena de caracteres que se encuentra ofuscada.
Esta cadena es descifrada en tiempo de ejecución por la función sub_608324.
Analizando el código de esta, se puede implementar el algoritmo de descifrado utilizado mediante el lenguaje Python.
string = " Q33646600K37528900B37528900M36234800O37205375G1876
4450S15205675P15205675J35264225A32676025E38823000R
32028975G14882150G37205375Y16499775I14882150R37852
425Y37205375C14558625X32676025L31381925V37205375D3
7528900G14558625M16176250R14882150V31381925W352642
25J31381925X39470050M35911275K35587750Y31381925M38
499475B37205375J14882150C32028975G35911275P3526422
5S15205675I37205375A37852425N32028975T32676025H372
05375H37205375M32999550X37852425P34940700R34940700
B39146525G14882150R39470050U33970125L36234800G"
caps = False
result = ""
partial_result = ""
for index in range(0, len(string)):
if caps:
character = string[index]
if character < 'A' or character > 'Z':
partial_result += character
else:
caps = False
result += chr(int(partial_result) / 323525)
partial_result = ""
character = string[index]
if character >= 'A' and character <= 'Z':
caps = True
print(result)
Tras ejecutar el script se obtiene la URL de descarga utilizada por el downloader: hxxps://mexc[.]s3[.]us-east-2[.]amazonaws[.]com/sucessfully[.]zip
Desde esa URL se descarga el fichero sucessfully.zip cuya función hash SHA1 es 1cc1b75dc28261eebcf40777ebf3af750c19b1fc.
Este fichero ZIP es procesado por el downloader que, en lugar de tratarlo como un fichero comprimido, accede a él para buscar el primer carácter “{“ empezando por el final, que es un carácter utilizado como delimitador. A partir de aquí, extrae una cadena de caracteres que es descifrada utilizando el mismo algoritmo anterior para obtener una nueva URL de descarga.
La nueva URL es hxxps://mexc[.]s3[.]us-east-2[.]amazonaws[.]com/mexc[.]zip desde la cual se descarga otro fichero ZIP comprimido cuya función HASH SHA1 es a5d14fe4d43a6a6a77e788b029131268c0199df4.
Esta vez el fichero si es descomprimido y en su interior se encuentran otros tres ficheros: un binario llamado svchost.exe y dos librerías llamadas x86.dll y NVSMARTMAX.dll. Las funciones HASH de estos ficheros son:
bb2bbca6ca318ac0abba3cd53d097fa13db85ed0 |
NVSMARTMAX.dll |
muestra 3 |
a852a99e2982df75842ccfc274ea3f9c54d22859 |
svchost.exe |
Aplicación legítima 1 |
4b08ba3d1cc01638fafa49fd69b43e52d041b516 |
x86.dll |
DLL utilizada por muestra 3 |
La muestra 2 representa otro flujo de infección similar: un instalador MSI que, en este caso, no se trata de un downloader ya que incluye al malware en su interior directamente. Extrayendo los ficheros que contiene el instalador, se encuentran diferentes binarios.
Tanto libeay32.dll como ssleay32.dll son librerías legítimas pertenecientes a OpenSSL, como también lo es Cooperativa.exe, que se trata de la aplicación legítima 3. Este binario carga la librería DLL maliciosa Oleacc.dll, la cual se encarga de descifrar mediante un simple XOR el fichero Oleacc. La librería incluye información de depuración, por lo que se pueden observar los nombres de las funciones creadas por los desarrolladores del descifrador.
Una vez descifrado con la clave XOR “99871818”, se obtiene la librería DLL de Numando cuya función hash SHA1 es 5967aed040fabdb5645fc13a82df2c60d5efcdf3
La muestra 5 es otra librería DLL como la anterior, pero, en este caso, se encuentra empaquetada con el software de protección Themida. Por otra parte, la muestra 6 es una DLL como la x86.dll vista anteriormente que contiene imágenes utilizadas por la librería DLL principal de Numando.
URL de descarga adicionales
Desde ESET comparten URL de descarga de ficheros ZIP de Numando adicionales. Dado que en el momento del análisis dichas direcciones han sido deshabilitadas, se utiliza la plataforma VirusTotal para acceder a los ficheros descargados en su momento desde ahí.
URL |
SHA1 ZIP |
Clave XOR |
SHA1 DLL Numando descifrada |
hxxps://enjoyds[.]s3[.]us-east-2[.]amazonaws[.]com/H97FJNGD86R[.]zip |
a18328daae06739c0c61b8fe41860c3bf2eeda9a |
31369 |
bfda3eaab63e23802ea226c6a8a50359fe379e75 |
hxxps://lksluthe[.]s3[.]us-east-2[.]amazonaws[.]com/B876DRFKEED[.]zip |
ab861a48636561c5eeb81f75fd9d33fc18484096 |
84192 |
5412e926c90ea77073dc340b2c328bbaaa1e2f07 |
hxxps://procjdcals[.]s3[.]us-east-2[.]amazonaws[.]com/HN97YTYDFH[.]zip |
3dac71830be3f871e11631922b25df0ea9be77f5 |
52155 |
25b731cf9f9eee3349ff4640fe5c89ff16069276 |
hxxps://rmber[.]s3[.]ap-southeast-2[.]amazonaws[.]com/B97TDKHJBS[.]zip |
d7bc949b4d314322865637e292027c9ec23fe304 |
80416 |
9620a7cea45fe05e88e07c78d1b80ee4d65633ac |
hxxps://sucessmaker[.]s3[.]us-east-2[.]amazonaws[.]com/JKGHFD9807Y[.]zip |
ebaaf3bbded48f1860db0e4d99e122f2008ad0b3 |
29765 |
412b2de4e98f7be03fc7e902788ab4e550b6ca58 |
hxxps://trbnjust[.]s3[.]us-east-2[.]amazonaws[.]com/B97T908ENLK[.]zip |
85a4aec2d57fc81565bb8c22b6ea6c12a7a69451 |
76410 |
b9798bed8d59b495ebaec32ed16cb527d1391270 |
hxxps://webstrage[.]s3[.]us-east-2[.]amazonaws[.]com/G497TG7UDF[.]zip |
- |
- |
- |
La primera de las librerías DLL descifradas resulta ser la muestra 4 que, a priori, no pudo ser localizada en ninguna fuente de inteligencia pública.
Numando
Al igual que el resto de familias de troyanos latinoamericanos mencionadas, Numando está programado utilizando el lenguaje Delphi. Para analizar las capacidades del troyano se toma como referencia la muestra 3 que incluye información de depuración y permite identificar los nombres de las funciones utilizados por los desarrolladores del troyano y, por tanto, identificar más fácilmente su funcionalidad.
Las cadenas de caracteres del binario están cifradas mediante un algoritmo utilizado también en otras familias. El origen de este algoritmo es el libro titulado “Mestres da Espionagem Digital”. Dichas cadenas tienen forma de cadena hexadecimal pero en mayúsculas, es decir, dígitos entre el 0 y el 9 y letras entre la A y la F. La clave de cifrado tiene un formato similar pero, en su caso, puede contener dígitos entre el 0 y el 9 y letras entre la A y la Z.
La función Ucrypt::DC es la encargada de descifrar las cadenas. Para ello, el algoritmo utiliza instrucciones XOR y SUB. Comienza almacenando los dos primeros bytes de la cadena cifrada en una variable y los dos siguientes en otra.
Por ejemplo, para la cadena de la imagen, la primera variable valdría 0xBB y la segunda 0xBD. Mediante la primera se realiza la operación sub a partir del resultado obtenido de realizar un XOR con la segunda y el primero de los bytes de la clave. Tras esto, el resultado se convierte a ASCII y se almacena en una nueva variable moviendo el índice adelante en dos posiciones. En la siguiente iteración la primera variable toma el valor que previamente tenía la segunda y la segunda toma el siguiente par de caracteres de la cadena cifrada, y así sucesivamente, realizando tantas iteraciones como pares de caracteres tenga la cadena.
El siguiente código python equivale al algoritmo de cifrado utilizado:
def DecodeString(encodedString, key):
decodedString = []
if encodedString:
keyLen = len(key)
encStrLen = len(encodedString)
prevEncodedByte = 0
encStrList = []
keyList = []
encodedString = [encodedString[i:i+2] for i in range(0, encStrLen, 2)]
for byte in encodedString:
encStrList.append(int(byte, 16))
key = [key[i] for i in range(0, keyLen, 1)]
for byte in key:
keyList.append(ord(byte))
prevEncodedByte = encStrList[0]
encStrLen = len(encStrList)
keyLen = len(keyList)
keyOffset = 0
for i in range(1,encStrLen):
if(keyOffset>=keyLen):
keyOffset = 0
decodedByte = encStrList[i] ^ keyList[keyOffset]
if(decodedByte>prevEncodedByte):
decodedByte -= prevEncodedByte
else: decodedByte = decodedByte + 0xFF - prevEncodedByte
prevEncodedByte = encStrList[i]
decodedString.append(chr(decodedByte))
keyOffset += 1
return("".join(decodedString))
La clave de cifrado se encuentra dentro de la función de descifrado de cadenas, parece tener siempre una longitud de 250 caracteres y se encuentra almacenada como cadena de tipo Unicode. Para que la herramienta IDA la identifique, hay que forzarlo.
- Antes:
- Después:
La clave de cifrado utilizada en esta muestra es:
CR358ACDGJLMORUX1357ACEGJLNOSUVZ35UX2467BEG
JLNPRU2468BDGILNPSUX2479CFIKMORTVZ358BDGIKN
PRV1469BEGKNPSV146ADFILOQUZ369CFILX258BEHJO
RU147ADHLORUZ47BFILPSV25ADHKNRU148CFJMQU269
DHKOSX37AEILRV159DHLPTZ48CGLQU159DINRV26BFJ
NSZ49DIMQU27BGKPTAFJNTZ59EINSZ59EIO
Mediante la siguiente lógica es posible localizar la clave de la muestra a analizar:
import sys
from Strings import Strings
def is_key(string):
val = True
for c in string:
char = ord(c)
if (char < ord('0') or char > ord('9')) and (char < ord('A') or char > ord('Z')):
val = False
break
return val
def search_key(filepath):
possible_keys = set()
strings = Strings(filepath)
for cpStr in strings.extract_unicode_strings():
if is_key(cpStr) and len(cpStr)==250: # la clave tiene logitud 250
possible_keys.add(cpStr)
return list(possible_keys)
filepath = sys.argv[1]
possible_keys = search_key(filepath)
if len(possible_keys) == 1:
key = possible_keys[0]
print("[+] Key found: {}".format(key))
Numando actúa creando ventanas falsas que incitan al usuario a que introduzca sus datos bancarios. Para ello, monitoriza la navegación del usuario en búsqueda de ciertos títulos de página que contiene en sus cadenas cifradas. Tras descifrarlas, se obtiene el listado de entidades bancarias a las que afecta esta muestra.
Banco Bci Banco de Chile Banco Estado Banco Santander BICE Banco Falabella Scotiabank Bradesco Banco Condell Banco Internacional Banco Itaú Banco Ripley |
Banco Security Banco Azteca HSBC BBVA México Scotiabank Azul El Banco Fuerte de México Santander México Banco Mercantil Banestes Banese Banrisul |
En algunas muestras, las imágenes necesarias para llevar a cabo la suplantación se almacenan en un archivo ZIP cifrado dentro de la sección de recursos del binario, mientras que otras utilizan una librería DLL adicional para ello como las vistas anteriormente. En el caso de la muestra analizada, hace uso de la librería DLL x86.dll vista anteriormente, llamando a la función exportada “ADJUSTE” e indicando la imagen a extraer mediante un índice numérico.
En función de la imagen seleccionada, se mostrará una ventana con la información del banco en cuestión para tratar que el usuario introduzca sus datos de acceso.
El troyano además incluye funcionalidades de puerta trasera que permite a los atacantes realizar diferentes tareas bajo demanda. Estas opciones son manejadas mediante un gran bloque de instrucciones de tipo switch-case.
Algunas de las funcionalidades incluyen:
- Capturar el movimiento de ratón y pulsación de teclado
- Capturar la pantalla mediante la librería “Magnification.dll”.
- Apagar o reiniciar el equipo:
- Recopilación de información del Sistema Operativo:
- Auto-borrado automático:
Para comunicarse con sus servidores C2, el troyano hace uso de una sintaxis similar a la del resto de familias pero, en este caso, los comandos que puede recibir son especificados mediante números en lugar de cadenas de caracteres, seguramente para evitar detecciones a nivel de red. Esta utilización de números para los comandos es el motivo del nombre del troyano Numando.
En esta muestra, la dirección del C2 se encuentra escrita en el propio binario.
Sin embargo, en otras muestras se incluye una URL a sitios web públicos como YouTube o Pastebin en los que se almacena cifrada la IP y puerto del servidor C2.
Por último, para establecer persistencia, el malware renombra el binario legítimo que lo ha lanzado con una extensión nueva. En el caso de la muestra analizada: .scr.
Una vez renombrado crea un acceso directo (.lnk) en la ruta de Startup para que se inicie con el sistema.
Y aquí terminamos este artículo acerca del troyano Numando. Si os ha gustado y resultado de utilidad, os agradeceríamos mucho que lo compartierais :D
¡Nos vemos en el próximo post!
Referencias
- https://www.welivesecurity.com/la-es/2021/09/17/numando-nuevo-troyano-busca-datos-bancarios-afecta-brasil/
- https://www.basquecybersecurity.eus/archivos/202109/bcsc-malware-mekotio-tlpwhite816.pdf?1
IOC
e69e69fbf438f898729e0d99ef772814f7571728
4a1c48064167fc4ad5d943a54a34785b3682da92
bb2bbca6ca318ac0abba3cd53d097fa13db85ed0
bfda3eaab63e23802ea226c6a8a50359fe379e75
9a7a192b67895f63f1afdf5adf7ba2d195a17d80
7789c57dcc3520d714ec7ca03d00ffe92a06001a
313fbffa0be37eaf62199ddc7e0217b6e855b077
1cc1b75dc28261eebcf40777ebf3af750c19b1fc
4b08ba3d1cc01638fafa49fd69b43e52d041b516
bfda3eaab63e23802ea226c6a8a50359fe379e75
5412e926c90ea77073dc340b2c328bbaaa1e2f07
25b731cf9f9eee3349ff4640fe5c89ff16069276
9620a7cea45fe05e88e07c78d1b80ee4d65633ac
412b2de4e98f7be03fc7e902788ab4e550b6ca58
b9798bed8d59b495ebaec32ed16cb527d1391270