Anatomía de una APT simulada. Parte 4 - La noche del cifrado, la negociación y el reparto

El domingo a las 02:15, IberLogix todavía existía como empresa normal. A las 02:16, empezó a convertirse en un caso. Los primeros servidores en caer fueron los de ficheros regionales. No se apagaron. No mostraron pantallazos dramáticos. Simplemente empezaron a transformar documentos en ruido matemático. Los nombres cambiaban. Las extensiones aparecían como pequeñas banderas negras:
Contrato_Marco_TransIber.pdf.orchid
Nominas_Marzo_2026.xlsx.orchid
SAP_Proveedores_Q1.csv.orchid

En cada directorio quedaba una nota:
RESTORE-FILES-IBERLOGIX.txt

El texto era sobrio:
Your network has been encrypted by Nebula Jackal.
We have also downloaded sensitive company data.

Do not modify encrypted files.
Do not contact recovery companies before reading this message.
Do not attempt to hide the incident from stakeholders.

Portal:
http://[redacted].onion/iberlogix

Your private code:
IBX-7F3A-22C1

La nota no era el ataque. Era el final visible de un ataque que llevaba semanas ocurriendo. 

OrchidLock: ransomware como sistema de producción 

Nadir había escrito OrchidLock en Rust. No por moda, sino por tres razones: rendimiento, control de memoria y despliegue estático sencillo. El binario era diferente por víctima. Cada build incluye:
campaign_id
victim_id
public_key
extension
exclusion list
service kill list
share targeting config
operator signature
expiration date

El ransomware no contenía la clave privada. Nunca. Usaba cifrado híbrido:
Por archivo:
  file_key = random 256-bit
  nonce = random 96-bit
  encrypt(file, ChaCha20-Poly1305, file_key, nonce)

Por víctima:
  wrapped_key = X25519/ECDH + HKDF + AEAD(public_key_campaign, file_key)
  append metadata footer

Footer conceptual:
ORCHIDLOCKv3
victim_id: 16 bytes
file_id: 16 bytes
nonce: 12 bytes
wrapped_key_len: 2 bytes
wrapped_key: n bytes
tag: 16 bytes

El flujo:
for target in enumerate_targets(config) {
    if is_excluded(target) { continue; }
    if is_large_file(target) {
        encrypt_chunks(target);
    } else {
        encrypt_full(target);
    }
    write_note_once_per_directory(target.parent());
    report_progress(target);
}

La lista de exclusiones evitaba romper el arranque:
C:\Windows
C:\Program Files
C:\Program Files (x86)
C:\ProgramData\Microsoft\Windows Defender
bootmgr
ntldr
pagefile.sys
hiberfil.sys

La lista de procesos a detener era quirúrgica:
sqlservr.exe
oracle.exe
veeam.backup.shell.exe
Veeam.Backup.Service.exe
msmdsrv.exe
outlook.exe
excel.exe
winword.exe

Servicios:
MSSQLSERVER
SQLSERVERAGENT
VeeamBackupSvc
VSS
OracleService*

Comandos internos equivalentes:
vssadmin delete shadows /all /quiet
wmic shadowcopy delete
bcdedit /set {default} recoveryenabled No
bcdedit /set {default} bootstatuspolicy ignoreallfailures

No todos se ejecutaban siempre. El config decidía por host. En servidores críticos, OrchidLock reducía agresividad para mantenerlos arrancables. En estaciones, cifraba más ampliamente. 

Despliegue: GPO, SCCM y shares 

El binario llegó por tres rutas:
1. GPO startup script para workstations seleccionadas
2. PsExec/SMB para servidores con acceso directo
3. SCCM package preparado como fallback

Script de despliegue conceptual:
$src = "\\dc-mad-01\SYSVOL\IBERLOGIX.LOCAL\scripts\orchid.dat"
$dst = "C:\ProgramData\Microsoft\Crypto\orchid.exe"
Copy-Item $src $dst -Force
Start-Process $dst -ArgumentList "--config embedded --mode local" -WindowStyle Hidden

En shares, OrchidLock podía cifrar por UNC:
\\fs-mad-04\finance
\\sap-share-01\exports
\\legal-mad-01\cases

El panel mostraba progreso:
IBX-7F3A-22C1
Hosts enrolled: 1432
Hosts active encryption: 612
Files encrypted: 18,442,901
Bytes encrypted: 74.3 TB
Notes written: 91,204
Errors: 3.8%

El ransomware reportaba en intervalos. No cada archivo. Demasiado ruido. Cada host enviaba resumen:
{
  "host": "FS-MAD-04",
  "status": "running",
  "files_done": 184203,
  "bytes_done": 98234122112,
  "errors": 391,
  "elapsed": 1840
}

A las 03:02, el NOC de IberLogix vio errores masivos en shares. A las 03:11, helpdesk recibió llamadas de usuarios en México que aun estaban trabajando. A las 03:22, un administrador intentó restaurar un archivo y descubrió que parte de los repositorios Veeam no respondían. A las 03:40, el CISO fue despertado. A las 04:05, Vesper abrió el portal de negociación. 

El portal: teatro, prueba y control 

El portal Tor de Nebula Jackal no parecía una web de pelicula. Parecía un SaaS barato:


Incluía:
Chat
File decrypt test
Data proof browser
FAQ
Payment instructions
Countdown

La prueba de datos estaba calculada. No publicaban todo. Mostraban lo suficiente:
10 nominas anonimizadas parcialmente
3 contratos con proveedores
1 documento de seguro ciber
2 capturas de buzones ejecutivos
Listado de directorios legal/finance
Hash manifest de lotes exfiltrados

Vesper escribió:
We are not interested in damaging your operations beyond what is necessary.
You have two problems:
1. Encrypted systems.
2. Confidential data exposure.

Both can be solved here.

El tono era deliberado: no rabia, no insultos, no caos. Control. IberLogix pidií prueba de descifrado. Subieron tres archivos cifrados. Nebula Jackal devolvió dos descifrados y rechazo uno:
Two files decrypted as proof.
Third file rejected: contains legal data. Choose non-sensitive sample.

Ese detalle parecía profesionalidad. También reforzaba una idea: los atacantes habían visto sus documentos. 

Negociación: matemática emocional 

La demanda inicial fue 9 millones USD. The Curator ya había definido el suelo: 4.8 millones. La cifra no salió al azar. Mint y Magpie habían estimado:
Revenue: high
Cyber insurance limit: 10M
Operational downtime cost/day: 1.2M - 2.4M
Regulatory exposure: high
Data sensitivity: high
Backup recovery: partial
PR risk: high

Modelo interno:
initial_demand = min(insurance_limit * 0.9, estimated_5_day_loss * 1.1)
floor = max(cashout_target / payment_probability, 0.45 * initial_demand)

Vesper nunca mencionó el seguro al principio. Esperó a que IberLogix dijera que necesitaba tiempo. Entonces escribió:
Your insurance documentation is part of the downloaded data.
We know delay is a negotiation tactic.
The publication timer is not.

El equipo legal de IberLogix intentó ganar días. Vesper concedió 24 horas a cambio de aumentar prueba de vida: otra muestra descifrada y un árbol de directorios más amplio. La negociación bajó a 6.5M, luego a 5.2M, y finalmente a 4.8M con dos condiciones:
1. Decryptor funcional para todos los sistemas afectados.
2. Eliminacion de datos exfiltrados y no publicacion.

Nebula Jackal entregaría un "delete log". Nadie podía verificar realmente que los datos se borrasen. La promesa era parte del teatro. En doble extorsión, el pago compra probabilidad, no certeza. 

El pago: la linea que nunca debe ser recta 

Mint generó una direccion BTC única para IberLogix:
bc1q-ibx-campaign-unique-address

Internamente, la wallet estaba etiquetada:
{
  "victim_id": "IBX-7F3A-22C1",
  "expected_btc": 73.42,
  "usd_basis": 4800000,
  "split_plan": "orchid-7",
  "risk": "high_visibility"
}

El pago entró en dos transacciones para reducir ansiedad de la víctima y confirmar recepción:
TX1: 5% test payment
TX2: 95% final payment

Una vez confirmado, Nebula Jackal no movió todo inmediatamente. Mover fondos demasiado rápido tras un incidente crea un patrón claro. Mint aplicó un plan de enfriamiento:
T+0h: funds received, no movement except small test
T+8h: split into 12 UTXO clusters
T+36h: partial conversion via non-KYC swap routes
T+72h: XMR routing for 40%
T+5d: OTC placement for 25%
T+10d: stablecoin conversion for 20%
T+21d: mule distribution for operating costs

El reparto inicial:
Gross: 4.8M USD equivalent
Expected laundering loss: 18%
Infrastructure reserve: 7%
Emergency/legal reserve: 5%
Net distributable: approx 3.36M

El plan de chain hopping:
BTC victim wallet
  -> split wallets
    -> BTC/XMR atomic swap or brokered swap
      -> XMR holding wallets
        -> partial XMR/BTC return through different liquidity
        -> stablecoins via OTC
        -> fiat via brokers/mulas

Mint tenía reglas:
No exchange KYC directly from victim-linked UTXO
No equal splits
No round numbers
No synchronized withdrawals
No reuse of deposit addresses
No mixing operator funds with campaign funds

Ejemplo de split:
73.42 BTC
  -> 8.13
  -> 3.77
  -> 12.04
  -> 1.92
  -> 6.41
  -> 9.86
  -> 0.64
  -> 14.22
  -> 2.39
  -> 5.58
  -> 4.01
  -> 4.45

Nada de simetría. La simetría es una firma. 

Monetizacion: del token al mundo físico 

Convertir cripto en dinero util era más difícil que recibirla. El equipo financiero usaba varias vías:
1. Brokers OTC en mercados grises
2. Comerciantes P2P con prima alta
3. Compra de hardware revendible
4. Gift cards mayoristas
5. Stablecoins para pagos internos
6. Sociedades pantalla con facturas falsas
7. Mulas con retiros pequenos

Cada vía tenia coste y riesgo:
Metodo                 Perdida   Riesgo   Velocidad
OTC gris               8-15%     Medio    Media
P2P cash               15-30%    Alto     Alta
Stablecoin             2-6%      Medio    Alta
Hardware resale        20-35%    Bajo     Baja
Gift cards             25-40%    Medio    Media
Shell invoices         10-25%    Alto     Baja

La clave era no maximizar rendimiento, sino supervivencia. Un 20% de perdida era aceptable si reducía trazabilidad y distribuía riesgo. Las mulas no recibían millones. Recibían tareas:
Mula A: vender hardware comprado con cripto
Mula B: mover stablecoins a efectivo local
Mula C: aceptar pago por factura falsa
Mula D: comprar cuentas cloud y dominios

La mayoría no sabia que participaba en ransomware. Algunos creian trabajar en arbitraje cripto. Otros sabían suficiente para cobrar mas y preguntar menos. 

Reparto interno 

The Curator aplicó el contrato interno:
Direction / risk owner: 18%
Initial access cell: 12%
Malware team: 18%
Intrusion operators: 20%
Infrastructure/OPSEC: 8%
Exfiltration: 7%
Negotiation: 7%
Finance/cashout: 10%

Pero no todo se pagaba al instante. Había vesting criminal:
40% immediate after confirmed payment
30% after successful decryptor delivery
20% after first cashout phase
10% reserve released after 60 days

Motivo: evitar que alguien desapareciera con fondos o vendiera datos por su cuenta. Ledger interno, cifrado:
{
  "campaign": "black_orchard",
  "gross_usd": 4800000,
  "net_distributable_usd": 3360000,
  "members": [
    {"id": "curator", "share": 0.18, "paid": 241920},
    {"id": "saltline", "share": 0.12, "paid": 161280},
    {"id": "sable", "share": 0.08, "paid": 107520},
    {"id": "oboe", "share": 0.05, "paid": 67200},
    {"id": "nadir", "share": 0.05, "paid": 67200},
    {"id": "knifewall", "share": 0.12, "paid": 161280},
    {"id": "meridian", "share": 0.08, "paid": 107520},
    {"id": "hollow", "share": 0.07, "paid": 94080},
    {"id": "vesper", "share": 0.07, "paid": 94080},
    {"id": "mint", "share": 0.10, "paid": 134400}
  ],
  "reserve_usd": 336000
}

Los pagos internos se hacian en combinaciones:
XMR para operadores senior
USDT/USDC para infraestructura y servicios
BTC limpio por OTC para reservas
Fiat local para mulas
Servicios prepagados para futuras campanas

El descifrador

Tras el pago, Nebula Jackal entregó un decryptor:
IberLogix_Decryptor.exe
private_key_package.dat
README_RECOVERY.txt

El decryptor era lento, pero funcionaba. Ese era otro detalle de negocio: si el descifrador no funcionaba, futuras victimas tendrian menos incentivos para pagar. El ransomware criminal maduro depende de reputación paradójica. El README:
1. Ejecutar como administrador.
2. Probar primero en 10 archivos.
3. No ejecutar multiples instancias sobre el mismo path.
4. Usar --network-shares para rutas UNC.
5. Guardar logs.

Parámetros:
.\IberLogix_Decryptor.exe --key private_key_package.dat --path D:\Data --threads 8
.\IberLogix_Decryptor.exe --key private_key_package.dat --network-shares \\fs-mad-04\finance

La recuperación duró días. Algunos archivos estaban corruptos por bloqueos previos, software abierto o fallos de red. Nebula Jackal ofreció "soporte" en el chat durante 72 horas. Vesper incluso pidió logs. El absurdo era perfecto: la empresa recibía soporte técnico de quien la había destruido. 

Burn: desaparecer no es apagar 

 Después del pago, Nebula Jackal ejecutó la fase Burn. Lista:
Revoke phishing domains
Destroy VPS frontales
Rotate WireGuard keys
Archive campaign repos
Invalidate operator accounts
Move leak data to cold storage or delete selected lots
Retire SeedCrate config
Generate YARA diff for exposed samples
Update detections internas
Freeze aliases used

Sable revisó muestras capturadas por defensores. Oboe comparó indicadores publicados. Magpie leyó los primeros informes de prensa. The Curator calculó el ROI:
Campaign duration: 31 days
Active intrusion: 19 days
Gross paid: 4.8M
Net estimated: 3.36M
Operational cost: 214k
Exposed infrastructure: acceptable
Tooling burned: partial
Operator exposure: low
Reuse potential: medium

Retrospectiva interna:
What worked:
  - HR pretext aligned with real migration
  - Low-noise loader survived
  - Backup admin path via acquisition user
  - Insurance document improved negotiation

What failed:
  - One EDR flagged Nighthook memory pattern after day 8
  - rclone binary naming appeared in DFIR notes
  - GPO deployment missed 18% remote laptops
  - Decryptor too slow on large PST files

Actions:
  - Refactor Nighthook memory allocator
  - Replace rclone with custom S3 client
  - Improve laptop wake/encrypt routine
  - Add PST sparse recovery mode

Nebula Jackal no pensaba en Black Orchard como una historia. Pensaba en ella como una versión. 

La lectura defensiva 

La belleza oscura de una campana así es que no depende de un milagro técnico. Depende de pequeñas decisiones que, aisladas, parecen defendibles:
Un correo de RRHH plausible.
Un dominio parecido.
Un ZIP con contrasena.
Un LNK que abre un PDF real.
Una DLL cargada por una app legitima.
Una tarea programada con nombre aburrido.
Una credencial vieja en SYSVOL.
Un usuario de adquisicion con permisos pendientes.
Un backup server demasiado poderoso.
Una exfiltracion que parece backup.
Una GPO con permisos delegados.
Un domingo de madrugada.

La defensa no puede limitarse a detectar "ransomware.exe". Cuando aparece el cifrado, la historia ya esta escrita. Los puntos de ruptura estaban antes:

1. Deteccion de dominios lookalike y certificados recien emitidos.
2. Bloqueo o aislamiento de HTML smuggling y archivos LNK desde Internet.
3. Control de DLL sideloading mediante allowlisting.
4. Alertas por scheduled tasks nuevas en perfiles de usuario.
5. Limpieza continua de credenciales en SYSVOL.
6. Revision de permisos tras adquisiciones.
7. Monitoreo de accesos anormales a backup servers.
8. Segmentacion real de repositorios de backup.
9. Deteccion de exfiltracion por volumen, horario y destino.
10. GPO change monitoring con aprobacion fuerte.
11. Simulacros de ransomware con restauracion medida.
12. Correlacion narrativa: convertir alertas sueltas en una historia.

IberLogix no perdió por no tener herramientas. Perdió porque Nebula Jackal hizo que cada señal pareciera pertenecer a una historia distinta hasta que todas se unieron en la peor posible. Esa es la esencia de una APT simulada bien construida: no es un ataque mas sofisticado en cada pieza. Es una cadena donde cada pieza conoce su lugar. Y en Black Orchard, cada pieza encajó. 

Cierre de la serie 

Nebula Jackal no existe. IberLogix Energy tampoco. Pero el patrón es reconocible porque esta construido con elementos que si existen: phishing que aprovecha procesos reales, identidades híbridas, deuda técnica en AD, permisos heredados, backups demasiado confiados, exfiltración camuflada, negociación profesional y monetizaciín distribuida. La moraleja técnica no es "todo esta perdido". Es más concreta y más útil:

"Una organización defensiva debe aprender a ver cadenas."

Un LNK no es sólo un LNK si aparece después de un dominio recién registrado que imita RRHH. Una tarea programada no es sólo una tarea si nace en un portátil de finanzas después de un beacon raro. Un login de un usuario de adquisición no es solo soporte si toca backup fuera de su patrón. Una transferencia nocturna no es sólo backup si el destino es nuevo y el manifiesto no existe. Una GPO modificada no es solo administración si ocurre tras actividad lateral. La APT moderna, real o simulada, gana cuando el defensor mira eventos. Pierde cuando el defensor reconstruye historias.

Comentarios