🍎Desarollo de malware avanzado en MacOS ARM: shellcode y metamorfosis de memoria

IntroducciΓ³n

macOS representa uno de los ecosistemas mΓ‘s interesantes desde la perspectiva de investigaciΓ³n en seguridad ofensiva. La combinaciΓ³n de arquitecturas heterogΓ©neas (Intel x86-64 y Apple Silicon ARM64), mecanismos de protecciΓ³n como W^X, firmas de cΓ³digo obligatorias, y tecnologΓ­as como Pointer Authentication (PAC), crean un desafΓ­o tΓ©cnico considerable para el desarrollo de software malicioso sofisticado.

Este artΓ­culo presenta un anΓ‘lisis tΓ©cnico profundo sobre dos Γ‘reas fundamentales: el desarrollo de motores metamΓ³rficos capaces de evadir firmas estΓ‘ticas, y la implementaciΓ³n de shells reversos a bajo nivel en arquitectura ARM64. Ambos temas se interconectan en el contexto de implantes persistentes para sistemas Darwin.


1. El Concepto de MutaciΓ³n MetamΓ³rfica

1.1 Fundamentos TeΓ³ricos

Un motor metamΓ³rfico difiere fundamentalmente de un cifrador polimΓ³rfico. Mientras que el polimorfismo se limita a cifrar el payload y cambiar el decodificador, el metamorfismo reescribe las instrucciones del propio programa [1]. El resultado es que cada generaciΓ³n del cΓ³digo presenta una representaciΓ³n binaria completamente diferente, manteniendo la semΓ‘ntica original.

La motivaciΓ³n es clara: los sistemas de detecciΓ³n basados en firmas estΓ‘ticas, como XProtect de Apple, resultan ineficaces contra cΓ³digo que muta su estructura en cada ejecuciΓ³n [2].

1.2 El DesafΓ­o del TamaΓ±o Fijo

Uno de los problemas estructurales mΓ‘s relevantes en el contexto de Mach-O es la imposibilidad de expandir la imagen de cΓ³digo cargada durante la ejecuciΓ³n:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    MACH-O LAYOUT                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  __TEXT Segment (FIXED at build time)                   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚  Code pages mapped by loader - SIZE IMMUTABLE   β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β”‚                                                         β”‚
β”‚  We can OVERWRITE existing bytes                       β”‚
β”‚  We CANNOT expand the mapped region                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

El cargador de macOS mapea el segmento __TEXT con un layout estΓ‘tico determinado en tiempo de compilaciΓ³n. Esto impone dos modos de operaciΓ³n [2]:

CaracterΓ­stica
DiskMode
InMemMode

TamaΓ±o

Fijo al original

Expansible (~3x)

Mutaciones

Reg-swaps, sustituciones

Pipeline completo

Persistencia

Escritura en disco

VolΓ‘til

Crecimiento

0% en 8 generaciones

~6.79%

1.3 La Arquitectura del Motor

El nΓΊcleo del sistema es el contexto de mutaciΓ³n (context_t), que mantiene el estado completo a travΓ©s de las transformaciones:

Cada binario incorpora un marcador generacional embebido para controlar la evoluciΓ³n:


2. Grafos de Flujo de Control (CFG)

2.1 DefiniciΓ³n y PropΓ³sito

El CFG representa un mapa de la ejecuciΓ³n real del binario: no simplemente la secuencia top-to-bottom, sino todos los saltos, branches, llamadas y retornos que hacen que la ejecuciΓ³n salte como una bola de pinball [2].

Sin comprender el CFG, cualquier manipulaciΓ³n de cΓ³digo resultarΓ­a en corrupciΓ³n instantΓ‘nea. El CFG permite reorganizar el cΓ³digo de manera inteligente.

2.2 Bloques BΓ‘sicos

Un bloque bΓ‘sico es una secuencia lineal de instrucciones que siempre se ejecutan juntas de principio a fin. No hay saltos hacia su interior ni branches hacia afuera hasta la instrucciΓ³n final (el terminador).

Cada bloque posee:

  • Start offset: posiciΓ³n inicial en el flujo de instrucciones

  • End offset: posiciΓ³n de la instrucciΓ³n final

  • Sucesores: bloques donde la ejecuciΓ³n puede transferirse

  • CondiciΓ³n de salida: si el terminador es return, jump indirecto, etc.

2.3 ConstrucciΓ³n del CFG: Algoritmo Leader-Based

El enfoque clΓ‘sico de la teorΓ­a de compiladores utiliza el algoritmo basado en lΓ­deres, O(n), simple y correcto [3]:

Paso 1: Identificar lΓ­deres

Un lΓ­der es cualquier instrucciΓ³n que puede ser la primera de un bloque bΓ‘sico:

Paso 2: Particionar en bloques

Paso 3: Conectar aristas

2.4 IdentificaciΓ³n de Terminadores


3. ManipulaciΓ³n del Control Flow

3.1 Shuffling de Bloques

Una vez construido el CFG, es posible reorganizar los bloques mientras se preservan las semΓ‘nticas:

3.2 El Problema de los Desplazamientos

Al mover bloques, todos los desplazamientos relativos cambian:

Es necesario parchear cada instrucciΓ³n de branch con el nuevo desplazamiento:

3.3 ExpansiΓ³n de Jumps Cortos

Un JMP rel8 solo alcanza Β±127 bytes. Tras el shuffling, el target puede estar mΓ‘s lejos, requiriendo expansiΓ³n a JMP rel32:

3.4 Trampolines para Targets Externos

Cuando un branch apunta fuera del cΓ³digo controlado (llamadas a librerΓ­as), se emite un trampoline:

3.5 Control Flow Flattening

El flattening destruye completamente la estructura visible:

Todo se convierte en un loop gigante con un switch de "estados" en lugar de bloques estructurados. El cΓ³digo se vuelve inanalizable para decompiladores estΓ‘ticos.


4. El Motor de Reubicaciones

4.1 ΒΏPor QuΓ© es CrΓ­tico?

Toda manipulaciΓ³n de cΓ³digo que cambie offsets o posiciones requiere actualizaciΓ³n de referencias. Sin esto, el binario crashea instantΓ‘neamente [2]:

4.2 Estructura de Datos

4.3 Scanner x86-64

4.4 Scanner ARM64

ARM64 simplifica algunos aspectos (instrucciones de ancho fijo) pero complica la extracciΓ³n de inmediatos:


5. Consideraciones Multi-Arquitectura

5.1 La Realidad del Mercado

macOS corre en dos arquitecturas: Intel x86-64 y ARM64 (Apple Silicon). Los Macs con M-series estΓ‘n por todas partes, y las mΓ‘quinas Intel no desaparecerΓ‘n de la noche a la maΓ±ana [2].

La soluciΓ³n: diseΓ±ar para ambas desde el inicio:

5.2 Diferencias en DecodificaciΓ³n

Aspecto
x86-64
ARM64

Ancho de instrucciΓ³n

Variable (1-15 bytes)

Fijo (4 bytes)

Prefijos

Legacy, REX, VEX, EVEX

Ninguno

Addressing

RIP-relative

PC-relative con alineaciΓ³n

Operandos implΓ­citos

PUSH usa RSP, MUL usa RAX/RDX

SP es X31 en algunos contextos

5.3 El DesafΓ­o de Apple Silicon y PAC

Apple Silicon implementa Pointer Authentication (PAC) en hardware:

Instrucciones PAC reconocidas por el decoder:

La estrategia: evitar generar cΓ³digo propio y cargar normalmente a travΓ©s de dyld, que genera PAC para todos los punteros. Las funciones protegidas se dejan intactas.


6. Shell Reverso ARM64 para macOS

6.1 El Problema del struct sockaddr_in

En Linux se puede omitir sin_len; en Darwin (BSD) no es opcional. La estructura debe ser exactamente 16 bytes [4]:

6.2 ImplementaciΓ³n

CreaciΓ³n del socket:

PreparaciΓ³n de sockaddr_in en .data:

ConexiΓ³n:

RedirecciΓ³n de I/O:

Spawn de shell:

6.3 Errores Comunes

Error
SΓ­ntoma
CorrecciΓ³n

Omitir sin_len

connect falla silenciosamente

Incluir primer byte = 16

Puerto en little-endian

ConexiΓ³n a puerto incorrecto

Usar big-endian (0x115C = 4444)

Construir struct en registros

Problemas con relocations

Usar .data + adrp/add

Usar /bin/sh

Puede no existir

Usar /bin/zsh en macOS


7. Flujo de MutaciΓ³n Completo

El pipeline de mutaciΓ³n sigue una secuencia estructurada:


8. El Problema de W^X

macOS enforcement de W^X impide tener pΓ‘ginas de memoria simultΓ‘neamente escribibles y ejecutables:

La tΓ©cnica de dual-mapping mapea el cΓ³digo dos veces: una vista escribible y otra ejecutable.


9. Firmas de CΓ³digo y XProtect

9.1 El Dilema

XProtect, al ser signature-based, falla contra cΓ³digo mutado. Pero hay un problema: cambiar un solo byte rompe la firma de cΓ³digo, y macOS rechaza ejecutar el binario [2].

9.2 Estrategia Operacional

  1. El binario en disco permanece intacto (firma vΓ‘lida)

  2. Cada ejecuciΓ³n: leer cΓ³digo original, mutar en memoria

  3. Reflective loading: cargar cΓ³digo mutado sin tocar disco

  4. Cualquier mutaciΓ³n previa se pierde al terminar la ejecuciΓ³n


10. Conclusiones

El desarrollo de implants sofisticados para macOS requiere dominar mΓΊltiples dominios tΓ©cnicos:

  • Arquitectura Mach-O: Comprender el formato binario y sus limitaciones

  • AnΓ‘lisis de cΓ³digo: CFG, liveness analysis, decoding multi-arquitectura

  • Protecciones del sistema: W^X, code signing, PAC

  • Assembly ARM64/x86-64: Syscalls BSD, calling conventions, addressing modes

El motor metamΓ³rfico presentado demuestra que es posible evadir detecciΓ³n basada en firmas manteniendo estabilidad a travΓ©s de mΓΊltiples generaciones. Sin embargo, las protecciones modernas de Apple Silicon (PAC) aΓ±aden una capa adicional de complejidad que requiere arquitectura especΓ­fica.

El reverse shell ARM64 ilustra la importancia de los detalles especΓ­ficos de plataforma: lo que funciona en Linux puede fallar silenciosamente en Darwin debido a diferencias en el ABI y estructuras de datos del kernel.


Referencias

[1] The Mental Driller, "How I Made MetaPHOR and What I've Learned," VX Heavens, 2002. [Online]. Available: https://web.archive.org/web/20210224201353/https://vxug.fakedoma.in/archive/VxHeaven/lib/vmd01.html

[2] 0xf00sec, "Aether: Metamorphic Engine for macOS," GitHub Repository, 2024. [Online]. Available: https://github.com/0xf00sec/Aether https://0xf00sec.github.io/0x2earrow-up-right

[3] A. V. Aho, M. S. Lam, R. Sethi, and J. D. Ullman, Compilers: Principles, Techniques, and Tools, 2nd ed. Boston, MA, USA: Pearson, 2006.

[4] cocomelonc, "Malware Development for macOS Part 12: Reverse Shell ARM M1," cocomelonc.github.io, 2025. [Online]. Available: https://cocomelonc.github.io/macos/2025/10/15/malware-mac-12.html


Nota: Este artΓ­culo tiene fines exclusivamente educativos y de investigaciΓ³n en seguridad. Las tΓ©cnicas descritas deben utilizarse ΓΊnicamente en entornos controlados y con autorizaciΓ³n explΓ­cita.

Última actualización