El auge del ransomware ha ciertamente marcado un antes y un después en la historia del malware, determinando un nuevo rumbo en el modelo económico del cibercrimen. Esta amenaza ha evolucionado en los últimos años, expandiéndose a dispositivos de IoT –adquiriendo el nombre de jackware–, incorporando verdaderos centros de atención a la víctima y mutando lentamente hacia nuevas formas de extorsión masiva.
Los teléfonos y tabletas inteligentes no quedan exentos de contraer este tipo de infecciones. La mayor parte del ransomware para Android funciona simplemente como bloqueador de pantalla, es decir, sin cifrar los archivos del equipo. No obstante, las variantes basadas en algoritmos criptográficos causan grandes estragos.
Quienes vean su teléfono afectado pueden caer en la tentación de efectuar el pago del rescate para recuperar sus datos; sin embargo, corren el riesgo de acabar sin su dinero ni sus archivos. Afortunadamente, para la mayor parte del ransomware móvil existe una tercera opción: obtener las claves a través de ingeniería reversa.
A lo largo de este artículo veremos algunos ejemplos de cómo obtener las claves de descifrado partiendo del APK que infectó el terminal, de modo que cualquiera con sencillos conocimientos de programación pueda recuperar sus datos. ¡Manos a la obra!
Ransomware con claves dinámicas
El ransomware para Android usualmente cifra los archivos utilizando AES, un sistema de cifrado simétrico que –como tal– usa la misma clave para cifrar y descifrar los archivos. En algunas variantes, esta clave es única para cada equipo y se genera aleatoriamente cuando la aplicación maliciosa se ejecuta por vez primera.
Un ejemplo de este esquema de funcionamiento es Android/Lockerpin.A, sobre el cual basaremos nuestro análisis. Al ejecutar la muestra en un emulador, podremos ver cómo este malware finge ser una actualización del sistema, requiere permisos de administrador, realiza una petición web a un sitio de pornografía e inmediatamente muestra una falsa advertencia al usuario, indicando en nombre del FBI que se han visitado sitios de pornografía infantil y zoofilia. Finalmente, solicita el pago de una multa.
Mientras, los archivos que se encontraban en la unidad de almacenamiento externo han sido cifrados. Por cada archivo se ha creado un fichero extra de extensión .crypted_gaza
.
Vemos cómo todas las imágenes del dispositivo ya no pueden ser procesadas por las apps de visualización:
Ahora abriremos el APK en cuestión con jadx. En la barra de herramientas notarás un icono dedicado a la búsqueda de determinadas cadenas de texto entre el código. Al hacer clic se abrirá un cuadro de diálogo. Fíjate de tener activada la casilla de Code.
Esta herramienta tiene una intuitiva interfaz gráfica y te permitirá encontrar rápidamente líneas de código con palabras clave, como nombres de clases o métodos necesarios para operaciones de cifrado –como ser SecretKeySpec, Cipher o doFinal, entre otros–. De este modo, podrás buscar el momento en que la clave es creada y partir desde allí para identificar cómo se construye.
Si escribimos “AES” en el cuadro de texto, notaremos algunas ocurrencias; la segunda de ellas, inicializando la clave.
Al hacer doble clic, serás dirigido al segmento de código en cuestión. Dentro del método aes256Crypt()
veremos una llamada a generateKey
, donde la clave se inicializa de manera aleatoria e unívoca para cada equipo donde el malware se instala. Luego, el método putString()
guardará esa clave en el archivo de Shared Preferences.
Ahora que sabemos dónde está almacenada la clave, podemos dejar el emulador atrás y volver al equipo que ha sufrido la infección para descargar o ver el archivo de preferencias desde /data/data/<package_name>/shared_prefs
mediante el comando adb pull <origen> <destino>
, adb shell cat <ruta_preferencia_xml>
o el Android Device Monitor. Para esto, el terminal deberá estar rooteado.
A continuación vemos la información del archivo, con la clave recientemente generada.
Lo único que resta es copiar al computador todos los archivos que han sido cifrados y correr un script como el siguiente sobre dicha carpeta. Deberemos descifrar los datos utilizando ECB ya que es el modo de cifrado por defecto para AES en Android.
python decrypt.py <ruta_carpeta>
[python]
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import hashlib
import os
import sys
from Crypto import Random
from Crypto.Cipher import AES
key = 'D6C5E452A8F431AB27844AD935B38AA3454866333EF1F1E6842459F3FFF81F11'
def decrypt(key, enc):
return AES.new(key.decode('hex'), AES.MODE_ECB).decrypt(enc)
def decrypt_file(file_path, key):
"""
Recibe una clave en formato hexadecimal.
"""
print 'Descifrando archivo %s' % file_path
with open(file_path, 'rb') as fo:
ciphertext = fo.read()
dec = decrypt(key, ciphertext)
with open('%s%s%s' % (file_path[:-4], '_dec', file_path[-4:]), 'wb') as fo:
fo.write(dec)
if __name__ == '__main__':
"""
Recibe por parámetro la ruta absoluta de la carpeta que contiene los archivos cifrados o un archivo cifrado en particular.
"""
if len(sys.argv) > 2:
sys.exit('ERROR: No se especificó la ruta absoluta del archivo o directorio de archivos a descifrar.')
param_path = sys.argv[1]
if not os.path.exists(param_path):
sys.exit('ERROR: El archivo o directorio especificado no existe.')
if not os.path.isdir(param_path):
decrypt_file(param_path, key)
else:
for root,subdirs, files in os.walk(param_path):
for filename in files:
decrypt_file(os.path.join(root, filename), key)
[/python]
También podría crearse una aplicación para Android que realice el descifrado directamente en el smartphone.
Et voilà! Hemos recuperado nuestros archivos originales.
Claro que, en ocasiones, el análisis del código se ve obstaculizado por técnicas de evasión, como archivos manifiestos malformados, ofuscación, cifrado, reflexión o antiemulación.
Ransomware con claves hardcodeadas
Este tipo de malware criptográfico es aún más sencillo de analizar, dado que la clave de cifrado se genera de manera determinística con base en alguna cadena de texto almacenada en el código de la aplicación. Un ejemplo de este comportamiento es el histórico Android/Simplocker.A, que con el paso del tiempo ha evolucionado para enmascararse tras una variada lista de instituciones gubernamentales o aplicaciones pornográficas, y para el cual ESET desarrolló una herramienta de descifrado.
Para demostrarlo, tomaremos una muestra de esta familia y la dispondremos bajo la lupa. Del mismo modo que antes, abriremos la aplicación con jadx y buscaremos nuevamente la cadena “AES”. Encontraremos la entrada de inicialización de la clave.
Esto nos llevará a la clase AesCrypt
, la cual –como vemos en la siguiente imagen– genera la clave sobre el SHA-256 de una cadena de texto pasada por parámetro en el constructor. En ella también veremos el tipo de cifrado, modo y padding utilizado.
Si ahora buscamos el momento en que este constructor es utilizado, veremos un par de entradas con una variable de nombre CIPHER_PASSWORD
, perteneciente a la clase Constants
.
El ransomware con claves hardcodeadas ofrece mayor facilidad de estudio, no siendo necesario realizar análisis estático y pudiendo obtener las claves mediante el análisis dinámico con herramientas como MobSF.
¡Cuidado con estos códigos!
Con suerte, a lo largo de este artículo habrás descubierto algunos consejos para obtener las claves de descifrado del ransomware que ha tomado control de tu teléfono. Recuerda que, aunque tener una buena solución de seguridad ayuda a prevenir y desinfectar, los archivos que hayan sido cifrados se perderán a menos que consigas dar con la clave de descifrado o tengas una copia de respaldo actualizada en algún soporte digital.
En este video explicamos más sobre el funcionamiento del ransomware y cómo evitarlo:
Para conocer sobre la evolución de estos códigos para plataformas móviles, puedes acceder a nuestro artículo sobre la evolución del ransomware en Android.