Análisis Forense Digital: Soluciones Técnicas Detalladas 2025

Análisis del Sistema Informático

En la primera fase de la investigación sobre la evidencia digital número 2, se procedió a examinar la integridad del sistema de archivos. Para determinar el valor hash SHA256 de la partición del sistema en el equipo identificado como "neo4chen", se aisló la partición principal cifrada y se calculó su suma de comprobación correspondiente.

Respecto a la actividad de red, se identificó una dirección IP externa asociada a intentos de control remoto. Tras revisar los registros de acceso y sesiones de escritorio remoto, se confirmó que la dirección 192.168.3.14 fue utilizada para conexiones no locales.

En cuanto a la recuperación de credenciales, se localizó un mecanismo de protección basado en una frase mnemotécnica. El formato de la contraseña seguía un patrón matemático específico (2025=(20+25)^2). Utilizando esta clave junto con herramientas de descifrado de contenedores volumétricos, se logró acceder al sistema cifrado sin necesidad del PIM.

Para localizar el archivo completo que contenía la frase de recuperación, se examinó el sistema de archivos montado. Aunque existían múltiples archivos de imagen, el análisis comparativo indicó que un archivo JPG específico en la carpeta de imágenes contenía la información íntegra. El valor MD5 de este archivo fue extraído para validación.

Se realizó un proceso de descifrado de la frase mnemotécnica en chino. Los datos binarios extraídos de la imagen fueron sometidos a una operación XOR con el valor 1988 para obtener los índices correctos. El siguiente script automatiza la recuperación de las palabras:

def recuperar_palabras(indices_binarios, archivo_diccionario, valor_xor):
    palabras = []
    with open(archivo_diccionario, 'r', encoding='utf-8') as f:
        lineas = f.readlines()
        for binario in indices_binarios:
            indice_decimal = int(binario, 2)
            indice_real = (indice_decimal ^ valor_xor) - 1
            palabras.append(lineas[indice_real].strip())
    return palabras

lista_binaria = [
    "11100111101", "11000000001", "11111010110",
    "01101010000", "11000110110", "00000000101",
    "10001001000", "11001111010", "00001111000",
    "00001100001", "00000011001", "10001011011"
]

resultado = recuperar_palabras(lista_binaria, 'bip39_chinese_simplified.txt', 1988)
print("".join(resultado))

Se identificó un archivo de audio que contenía una confesión. El análisis de metadatos reveló la fecha de última modificación. Dentro del audio, se detectaron patrones de código Morse que, al ser decodificados, proporcionaron una dirección IP de servidor (114.51.41.91). Además, el contenido auditivo mencionaba actividades al aire libre como la pesca.

En el sistema Linux asociado, se encontró un contenedor cifrado dentro de un directorio sospechoso. El nombre del archivo sugería su contenido relacionado con deudas. La contraseña para montar este contenedor se derivó de números de teléfono encontrados en evidencias previas, combinando dos secuencias numéricas específicas.

El análisis del sistema de archivos reveló una imagen ISO de Ubuntu. Al montar la imagen, se verificó que la versión del kernel era la 4.15.0, información corroborada también en el directorio de firmware.

El estado actual del sistema Linux se determinó como "hibernación". Esto se dedujo tras recomponer el array RAID (configurado como RAID 0) y observar que no existían registros de apagado correcto en los logs de sesión. Al intentar el arranque, fue necesario reparar el gestor de arranque GRUB mediante los comandos insmod normal y normal para acceder a la interfaz y verificar los últimos ingresos.

Se investigó un plugin de Chrome protegido por contraseña. El código fuente del plugin reveló el uso de Argon2 para el hash de la contraseña y AES para el cifrado de datos. Se desarrolló un script para fuerza bruta del prefijo conocido:

import argon2
from Crypto.Cipher import AES
import base64

hash_objetivo = "$argon2id$v=19$m=16384,t=1,p=1$k6EZEDdQYyn+/0GlJtZGpg$hicAuwJorE73Moj+Po2Txda8hyoPPGYa"
cifrado_base64 = "U2FsdGVkX18Tb9IA8UF4TbpMQjOs4IqZBTIkldDlgn9vw1gIF9ltOirI/lf1SCGh9hAskbnb7cIsoJL6mNii7pQ1SDSt9R7vzF3Y+/d/fPtKXHMisjbQK/U6t+3wREAuoKQ4yZ24iuw+KZ6CW9bl6ULp3nVx0B8QpueW95sw0KOtmOMpmD19nO6gkFvMohcB"
prefijo = "chewhaoN@"

verificador = argon2.PasswordHasher()

for i in range(10000):
    candidato = f"{prefijo}{str(i).zfill(4)}"
    try:
        datos_cifrados = base64.b64decode(cifrado_base64)
        # Lógica simplificada de descifrado para validación
        # En un escenario real, se usaría la clave derivada para intentar descifrar
        # y luego verificar el hash con argon2
        if verificador.verify(hash_objetivo, candidato):
            print(f"Contraseña encontrada: {candidato}")
            break
    except:
        continue

La contraseña recuperada fue chewhaoN@6087, lo que permitió acceder al token almacenado, identificado como chenhaoren. Al ajustar la zona horaria del entorno virtual a Asia/Shanghái, se pudo visualizar el token válido para la fecha específica solicitada.

Investigación del Dispositivo Móvil

En la evidencia móvil (检材 1), se extrajo la dirección MAC Bluetooth mediante herramientas de análisis forense. La versión del kernel Linux del dispositivo se identificó como 4.14.186 tras buscar cadenas de texto en la imagen del sistema.

Se localizó una base de datos de gestión de contraseñas asociada al paquete design.codeux.authpass.fdroid. La contraseña maestra para abrir el archivo .kdbx se encontró en una nota adhesiva digital: Save my P Ass.. Dentro de esta base de datos, la credencial para GitHub correspondía a una entrada específica identificada por su URL.

El dispositivo contenía un entorno Linux desplegado mediante Linux Deploy. Los archivos de configuración en shared_prefs indicaban que la distribución era Debian con el entorno de escritorio XFCE. La contraseña de usuario Android asociada se recuperó buscando hashes en el sistema, resultando en 99c26da5.

Dentro del contenedor Linux, se halló un archivo ejecutable descargado llamado reshacker_setup.exe. El análisis de los comandos históricos reveló el uso de un dominio proxy para acceder a repositorios de GitHub. Un programa específico para manejar frases mnemotécnicas (recphrase) estaba protegido con UPX. Tras desempacar y descompilar el bytecode de Python, se ejecutó el script para obtener las palabras de recuperación, identificando "village" en la segunda columna, tercera fila. Las primeras ocho posiciones de la semilla de la billetera derivada fueron e08478b0.

Se analizó un sitio web de phishing alojado en el contenedor. El código fuente reveló que las contraseñas se almacenaban utilizando el algoritmo pbkdf2_sha256. La cuenta de administrador utilizaba una contraseña débil que permitió el acceso tras un intento de fuerza bruta. El panel de control宝塔 (Baota) fue accesible mediante el historial del navegador, y los logs de errores indicaron un archivo .so problemático en arquitecturas aarch64.

Forense en Servidor y Contenedores

La evidencia del servidor (检材 3) correspondía a una instalación de Ubuntu. El nombre del host y la configuración de red (netplan) permitieron identificar la IP de la interfaz ens33. El sistema utilizaba autenticación PAM mediante pam_pwdfile, con contraseñas hashadas usando bcrypt. El archivo que contenía las credenciales del usuario "king" se nombraba my_two_factor_pwdfile.

Mediante herramientas de auditoría de hashes, se recuperó la contraseña del usuario king probando combinaciones numéricas. La configuración de Docker reveló la dirección del servidor MySQL. Un archivo de captura de tráfico (test.pcap) generado desde la interfaz de red mostró tres intentos de inicio de sesión exitosos para el usuario admin. El último producto consultado antes de actividades mlaiciosas fue una cámara modelo hx-101.

Para acceder a los contenedores, fue necesario configurar la red en modo DHCP y habilitar SSH. El contenedor principal ejecutaba un servicio backend basado en NodeJS. La configuración de Nginx dentro de otro contenedor reveló el dominio asociado y los archivos de log de acceso. Se identificaron rutas API específicas para obtener flags y verificar el estado del servicio.

El análisis de seguridad mostró que la base de datos estaba cifrada mediante un archivo de objeto compartido (.so). La ingeniería inversa de este archivo indicó que fue compilado con GCC y utilizaba AES-256-CBC. La función de generación de clave fue recreada en Python para extraer el valor correcto:

def generar_clave_aes(constante_base):
    # Simulación de la lógica de generación de clave extraída del binario
    buffer_v9 = bytearray(96)
    buffer_v9[0:16] = constante_base
    buffer_v9[16:32] = constante_base
    
    # Relleno inicial
    for i in range(32):
        buffer_v9[32 + i] = (35 + i) & 0xFF
        
    # Permutación y XOR simplificados para demostración
    clave_final = bytearray(32)
    for k in range(32):
        clave_final[k] = buffer_v9[64 + k] ^ 0x44
        
    return bytes(clave_final[0:16])

# Valor constante extraído del análisis estático
constante = int(46741931963535420569491455081441471550).to_bytes(16, 'little')
clave_recuperada = generar_clave_aes(constante)
print(f"Clave AES Parcial: {clave_recuperada.hex()}")

Con la clave y el vector de inicialización (IV) obtenidos, se descifró el texto base64 dnJXwBR4qc+1Y4WB6ZxR0A==. El proceso implicó decodificar en base64, aplicar AES-CBC y volver a codificar el resultado.

La base de datos MySQL contenía una tabla products con campos cifrados. Se escribió un script para procesar el export CSV y descifrar las columnas relevantes:

import pandas as pd
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
import base64
import json

CLAVE_HEX = "7a68616f686f6e677a68616f686f6e677a68616f686f6e677a68616f686f6e67"
clave = bytes.fromhex(CLAVE_HEX)
iv = b"0123456789012345"

def descifrar_celda(texto_cifrado):
    try:
        datos = base64.b64decode(texto_cifrado)
        cifrador = AES.new(clave, AES.MODE_CBC, iv)
        descifrado = unpad(cifrador.decrypt(datos), AES.block_size)
        return descifrado.decode("utf-8")
    except:
        return "ERROR"

df = pd.read_csv("products.csv")
columnas_objetivo = ["name_encrypted", "price_encrypted", "additional_data_encrypted"]

for col in columnas_objetivo:
    if col in df.columns:
        col_nueva = col.replace("_encrypted", "")
        df[col_nueva] = df[col].apply(descifrar_celda)

# Filtrado para estadísticas
modelo_zk = df[df['name'].str.startswith('ZK')]
total_ventas = int(modelo_zk['price'].sum())
print(f"Ventas totales modelo ZK: {total_ventas}")

El análisis de los datos descifrados permitió contar las variantes de modelos y filtrar por color y tipo para obtener las estadísticas solicitadas.

Dispositivos IoT y Firmware

La evidencia IoT (检材 4) correspondía a un dispositivo OpenWRT. La versión del sistema se identificó como 24.10.0. La configuración de red en /etc/config/network proporcionó la IP de la LAN. El tamaño de la partición Overlayfs se verificó mediante el comando df.

Se localizó una clave privada VPN en los archivos de configuración. Un programa compilado llamado password_collector fue extraído del sistema de archivos. Para analizarlo, se configuró el servicio uhttpd para servir el binario y permitir su descarga. El análisis estático con herramientas de identificación de compiladores reveló que aceptaba dos argumentos de línea de comandos y utilizaba cifrado AES junto con codificación Base64.

El programa almacenaba datos en un archivo de texto plano. El seguimiento de la función de descifrado dentro del binario permitió recuperar la clave AES y la información de los dispositivos vigilados, incluyendo direcciones IP.

Correlación de Evidencias

Al cruzar la información de todas las evidencias, se determinó que el sujeto realizó operaciones de cifrado en múltiples etapas, tanto en el equipo informático como en archivos específicos. La instalación de bases de datos se realizó principalmente mediante gestores de paquetes en Kali y contenedores Docker en el servidor, descartando otros métodos.

Los sistemas operativos utilizados abarcaban versiones de Android, Ubuntu Server y OpenWRT. No se encontró evidencia de una versión específica de kernel Linux en los datos disponibles. El valor hash SM3 de la imagen de fondo de pantalla se calculó desde el almacenamiento del dispositivo móvil.

Finalmente, la contraseña real de GitHub se recuperó de la base de datos de una aplicación de notas en el teléfono móvil (com.ivanovsky.passnotes), donde se almacenaba el hash que correspondía a la credencial Forensix666.

Etiquetas: forense-digital linux Docker cifrado-aes OpenWrt

Publicado el 8-17 19:23