Durante la semana pasada (2026/07/27 - 2026/08/02), se destacan los siguientes 2 incidentes de seguridad notables, que en conjunto representan aproximadamente $88M en pérdidas.
| Fecha | Incidente | Tipo | Pérdida Estimada |
|---|---|---|---|
| 2026/07/29 | LULA | Falla de Lógica de Negocio | ~$578K |
| 2026/07/30 | COLDCARD | Generación de Entropía Defectuosa | ~1.370 BTC (~$88M)* |
* La pérdida de COLDCARD varía según el método de confirmación: los ~1.370 BTC (~$88M) mostrados corresponden al mínimo verificable públicamente en cadena (coldcardwatch.com); la reconciliación por canales privados (Galaxy Research, a partir de correspondencia con 73 víctimas) lo sitúa en un valor mayor, aproximadamente 1.596 BTC y hasta ~2.055 BTC (~$130M) si se incluyen los drenajes sospechados pero no confirmados.
Razones de selección
- LULA: Una función de token privilegiada que puede mover los saldos de un par AMM y forzar una resincronización de reservas se convierte en una primitiva de drenaje de liquidez repetible mediante manipulación de precios.
- COLDCARD: Un error de compilación e integración en el firmware de la billetera enrutó silenciosamente la generación de semillas a través de un fallback de software determinista, comprometiendo las garantías de entropía y convirtiendo la recuperación de semillas en una búsqueda offline que escaló hasta ocasionar pérdidas de fondos a gran escala.
El Mejor Auditor de Seguridad para Web3
Valida el diseño, el código y la lógica de negocio antes del lanzamiento
Destacado de la Semana: COLDCARD
Seleccionamos COLDCARD como el destacado de esta semana porque un error de entropía en la billetera produjo la mayor pérdida del período. La causa raíz —una guarda de compilación que verificaba si existía una macro de configuración en lugar de si estaba habilitada— es el tipo de error silencioso de integración que las pruebas funcionales no pueden detectar, y la lección aplica a cualquier sistema donde la seguridad en cadena depende de la aleatoriedad fuera de cadena.
COLDCARD, una billetera de hardware de Bitcoin, distribuyó firmware en 2021 que generaba semillas de billetera usando una fuente de software determinista en lugar del generador de números aleatorios (RNG) de hardware previsto [1][2]. La falla no fue explotada a gran escala hasta finales de julio de 2026, cuando las billeteras afectadas fueron vaciadas en oleadas en cadena que comenzaron el 30 de julio: las pérdidas confirmadas públicamente ascienden a al menos 1.370 BTC (~$88M, al precio de $64.099 del 5 de ago) [3], mientras que los informes confirmados de forma privada elevan la cifra a aproximadamente 1.596 BTC [4]. La causa raíz fue un error de compilación y configuración que enrutó la generación de semillas hacia un fallback de software en lugar del RNG de hardware previsto. Para los dispositivos afectados, esto convirtió la recuperación de semillas de un problema criptográficamente inviable en una búsqueda offline.
Contexto
COLDCARD es una billetera de hardware de Bitcoin. Las claves privadas y direcciones de una billetera se derivan de un único valor secreto, su semilla, por lo que la seguridad de cualquier billetera de autocustodia depende de dos propiedades de esa semilla: que permanezca secreta y que sea impredecible al generarse. Las billeteras de hardware existen en gran medida para proteger la primera; este incidente es un fallo de la segunda. Una frase semilla BIP-39 es legible por humanos, pero la propiedad de seguridad subyacente al requisito de impredecibilidad sigue siendo la entropía de los bytes aleatorios utilizados para crearla. Si esos bytes pueden reproducirse, la semilla puede reproducirse. La intuición es la de una caja fuerte cuya combinación se elige lanzando dados: si los dados están cargados, la caja fuerte queda abierta para cualquiera que conozca el sesgo, sin importar cuán fuerte sea la cerradura.
Para una billetera, "dados cargados" significa un generador de números aleatorios débil. Se espera que las billeteras de hardware obtengan la entropía de la semilla de un generador de números verdaderamente aleatorios (TRNG) de hardware en su microcontrolador seguro, porque un generador pseudoaleatorio (PRNG) de software es determinista: dado su estado interno e historial de llamadas, su salida puede reproducirse exactamente. Si las salidas del generador son predecibles, su rango de candidatos puede enumerarse y compararse contra datos públicos de billetera como una dirección, un xpub o una clave pública, lo que colapsa la recuperación de semillas de un problema criptográficamente inviable a una búsqueda offline.
El firmware de COLDCARD exponía dos superficies de RNG separadas. MicroPython incluía una capa de plataforma STM32 que exponía el símbolo global rng_get() que esperaba la biblioteca criptográfica de la billetera, mientras que COLDCARD también mantenía su propio wrapper de RNG de hardware local a la placa. Ambas superficies están destinadas a suministrar entropía de hardware, y la biblioteca criptográfica de la billetera accede a una de ellas a través de un único símbolo de RNG global resuelto al compilar el firmware.
Análisis de Vulnerabilidad
La causa raíz fue un error de compilación e integración relacionado con la macro de configuración MICROPY_HW_ENABLE_RNG. La configuración de la placa de producción de COLDCARD establecía esta macro en 0, porque el firmware pretendía usar su propio wrapper de RNG de hardware local a la placa en lugar de la implementación de RNG de hardware de MicroPython. Sin embargo, la ruta de generación de billeteras había sido migrada a ngu.random.bytes(32), y la ruta STM32 de la biblioteca criptográfica dependía en última instancia del símbolo global rng_get() resuelto por MicroPython.
La cadena del problema fue:
generate_seed()
-> ngu.random.bytes(32)
-> libngu CHIP_TRNG_32()
-> rng_get()
-> Módulo RNG STM32 de MicroPython
-> Fallback de software Yasmarang porque MICROPY_HW_ENABLE_RNG == 0
La configuración de la placa deshabilitaba la rama de RNG de hardware de MicroPython:
// Tenemos nuestra propia versión de este código.
#define MICROPY_HW_ENABLE_RNG (0)
La biblioteca criptográfica aún trataba la macro como prueba suficiente de un RNG de hardware [5], porque solo verificaba si la macro existía antes de llamar a rng_get():
extern uint32_t rng_get(void);
#define CHIP_TRNG_32() rng_get()
#ifndef MICROPY_HW_ENABLE_RNG
#error "get a HW TRNG plz"
#endif
Esa guarda omite el caso peligroso: una macro definida como 0 sigue estando definida, por lo que la verificación con #ifndef pasa y la compilación tiene éxito. Dado que MicroPython selecciona su implementación de RNG por el valor de la macro y no por su existencia, MICROPY_HW_ENABLE_RNG == 0 enrutaba rng_get() hacia la rama del fallback de software en lugar del wrapper local de la placa de COLDCARD [6]:
#if MICROPY_HW_ENABLE_RNG
// RNG de hardware STM32
#else
// Fallback de software Yasmarang
#endif
Las consecuencias difieren según la generación del dispositivo. Para el firmware Mk2/Mk3 v4.0.0-v4.1.9, el análisis de Block [7] indica que no se añadió entropía criptográfica a ngu.random, por lo que la generación de billeteras puede volverse determinista una vez que se conocen el estado del fallback y el historial de llamadas (el aviso de Coinkite [2] delimita el rango de Mk2/Mk3 de forma ligeramente más estrecha, como v4.0.1-v4.1.9). Para Mk4/Q/Mk5, se hasheó material del elemento seguro pero solo se pasaron cuatro bytes a ngu.random.reseed(), limitando la resembrado seguro a una única palabra de estado de 32 bits, un espacio de búsqueda mucho menos efectivo del que los usuarios esperan para la entropía de la billetera. Hashear los 32 bytes aleatorios finales no puede aumentar la entropía del resultado; solo transforma un conjunto de candidatos ya limitado.
Análisis del Ataque
A diferencia de un exploit de contrato inteligente, este incidente no tiene una única transacción de ataque en cadena que rastrear. Fue un problema de recuperación de semillas offline seguido de vaciados en cadena. La precondición era que los usuarios afectados habían generado las semillas de su billetera a través de la ruta vulnerable ngu.random.bytes(32), por lo que el material de su semilla dependía de un estado de fallback de software reproducible en lugar de entropía de hardware completa. Una segunda precondición inferida es que las billeteras afectadas eran derivables solo a partir de la semilla: una frase de contraseña BIP-39 fuerte y única mezcla entropía independiente suministrada por el usuario a través de PBKDF2 que la falla del RNG nunca tocó, colocando dichas billeteras fuera de la enumeración pura de semillas, y la escala de los vaciados sugiere que la mayoría de los usuarios afectados no habían establecido tal frase de contraseña. A partir de ahí, la recuperación probablemente procedió en tres pasos:
- El atacante restringió o enumeró los estados candidatos del RNG usando metadatos del dispositivo, temporización de arranque, suposiciones de RTC/SysTick e historial plausible de llamadas al RNG.
- Para cada estado candidato, el atacante derivó semillas candidatas de billetera y las verificó offline contra datos públicos de billetera como direcciones, xpubs o claves públicas generadas.
- Una vez que un candidato coincidió con una billetera real, el atacante recuperó la semilla, reconstruyó las claves privadas y vació el BTC asociado.
En cadena, el robo apareció como una ráfaga de vaciados de direcciones que comenzaron el 30 de julio. El seguimiento heurístico independiente en cadena [3] identifica varias oleadas de drenaje que totalizan al menos 1.370 BTC (aproximadamente $88M, valorando las monedas al precio de BTC de $64.099 del 5 de ago) vaciados desde 4.580 direcciones verificadas, un mínimo verificado y no un total. Mientras tanto, un canal privado [4], confirmado mediante correspondencia con 73 víctimas, eleva la cifra a aproximadamente 1.596 BTC, llegando hasta 2.055 BTC (~$130M) una vez añadidos los drenajes sospechados pero no confirmados.
Conclusión
El incidente de COLDCARD fue un fallo en la generación de entropía: la API de generación de semillas de importancia crítica para la seguridad se resolvió silenciosamente hacia un fallback de PRNG de software determinista en lugar del RNG de hardware previsto, porque una guarda de compilación verificaba si existía una macro de configuración en lugar de si estaba habilitada. Para los dispositivos afectados, esto convirtió la recuperación de semillas de un problema criptográficamente inviable en una búsqueda offline, y el resultado fue más de 1.370 BTC [3] vaciados en múltiples oleadas (los recuentos por canal privado lo sitúan en aproximadamente 1.596 a 2.055 BTC [4]).
El fallo de ingeniería central es que el firmware distribuido nunca demostró que su API más crítica para la seguridad realmente alcanzaba el RNG de hardware previsto. Tres prácticas lo habrían detectado: las guardas de compilación para entropía criptográfica deben verificar tanto la existencia de la macro como su valor; los fallbacks de entropía deben fallar de forma cerrada en lugar de sustituir silenciosamente un PRNG de software; y la verificación de la imagen final del firmware debe cubrir la procedencia de los símbolos y el flujo de entropía de extremo a extremo, no solo que el código compile. Una semilla afectada no puede corregirse en su lugar; sus fondos deben trasladarse a una billetera creada con firmware corregido, y una frase de contraseña fuerte y única reduce la exposición inmediata sin reparar la semilla [2].
Vale la pena subrayar el modo de fallo: los errores de aleatoriedad de este tipo son invisibles para las pruebas funcionales porque cada semilla generada es individualmente válida. El defecto no reside en ninguna salida individual sino en la fuente que las produjo: como esa fuente es predecible y reproducible, las semillas en conjunto caen dentro de un rango pequeño y enumerable. Los componentes de generación de claves fuera de cadena merecen un escrutinio de seguridad de primera clase.
Referencias
- [1] Alerta de BlockSec Phalcon que vincula el vaciado de billeteras COLDCARD con la debilidad en la aleatoriedad de generación de semillas
- [2] Coinkite, Análisis Técnico Profundo del Problema de Entropía
- [3] coldcardwatch.com, Coldcard Sweep Watch: seguimiento en cadena de direcciones drenadas y metodología
- [4] Galaxy Research, estimación de pérdidas del hackeo de COLDCARD (~1.596 BTC confirmados mediante informes de víctimas)
- [5] libngu, la ruta RNG de STM32 referencia el
rng_get()global y solo guarda con#ifndef MICROPY_HW_ENABLE_RNG - [6] Coldcard MicroPython,
rng_get()recurre a Yasmarang cuando el RNG de hardware está deshabilitado - [7] Block Engineering, Fallback de RNG Predecible y Resembrado de 32 Bits en el Firmware de COLDCARD
Comienza con Phalcon Explorer
Analiza transacciones para actuar con inteligencia
Pruébalo gratis ahoraMás Incidentes de Esta Semana
LULA
LULA, un token BEP-20 en BNB Chain, perdió aproximadamente $578K el 29 de julio de 2026 debido a una falla de lógica de negocio en su contrato de token. Una ruta alcanzable por el atacante podía activar su función privilegiada recycle(), permitiendo al contrato Rental transferir LULA directamente fuera del par PancakeSwap V2 y luego llamar a sync(), actualizando las reservas del par con los saldos manipulados. El atacante activó recycle() repetidamente para reducir la reserva de LULA del par a casi cero, luego intercambió una pequeña cantidad de LULA de vuelta por casi todo su USDT [1].
Contexto
LULA es un token BEP-20 en BNB Chain con un mecanismo de recompensa de equipo basado en alquiler. Las direcciones elegibles acumulan recompensas de equipo pendientes en un contrato Rental y las reclaman a través de claimTeamReward(). Durante el flujo de reclamación, el contrato Rental llama a la función recycle() del token para obtener LULA para la distribución de recompensas. recycle() no puede ser llamada por usuarios arbitrarios; solo el contrato Rental está autorizado a ejecutarla.
El punto de entrada claimTeamReward() contiene una verificación de "solo EOA". Admite llamadas directas desde cuentas de propiedad externa donde msg.sender == tx.origin, y también admite llamadas delegadas EIP-7702 inspeccionando el prefijo del código delegado.

En un creador de mercado automatizado (AMM), un par calcula el precio de los intercambios a partir de sus reservas almacenadas, y esas reservas se actualizan a través de la función sync() del par, que las establece según los saldos de tokens actuales del par. Las reservas normalmente reflejan operaciones genuinas porque se mueven con los intercambios y eventos de liquidez, pero el saldo de tokens de un par también puede modificarse mediante una transferencia directa, y sync() copia cualquier saldo presente, manipulado o no, en las reservas almacenadas.
Análisis de Vulnerabilidad
La causa raíz fue que LULA.recycle() permite al contrato Rental transferir LULA directamente fuera del par PancakeSwap V2 y luego llamar a sync(), actualizando las reservas del par con los saldos manipulados [1].

Dado que sync() establece las reservas al saldo de LULA que queda en el par, esta ruta privilegiada puede llevar la reserva de LULA del par a un valor arbitrariamente bajo mientras deja intacto el lado de USDT. Una vez que la reserva de LULA está cerca de cero, el par valora una pequeña cantidad de LULA como equivalente a casi todo su USDT.
Análisis del Ataque
El siguiente análisis se basa en la transacción 0xa219ab9...411d7c.
- Paso 1: El atacante financió la manipulación acumulando ~197,05M de USDT. Los fondos provienen de múltiples fuentes de préstamos flash y préstamos, incluidos Moolah/Lista, Aave V3, Venus, PancakeSwap V3, PancakeSwap Vault, Uniswap V4 PoolManager y Uniswap V3.
- Paso 2: El atacante usó los ~197,05M de USDT para realizar un gran intercambio
USDT -> LULAa través del router PancakeSwap V2. Esto redujo drásticamente la reserva de LULA del par de aproximadamente 8M de LULA a 24.022 LULA, mientras que el lado de USDT aumentó a aproximadamente 197,64M de USDT. - Paso 3: El atacante invocó la ruta de recompensa a través de múltiples billeteras EIP-7702. Cada billetera llamó a
claimTeamReward()en el contrato Rental, que luego activóLULA.recycle(), reduciendo la reserva de LULA del par de 24.022 LULA a 0,004 LULA mientras el par aún mantenía un lado de USDT muy grande. - Paso 4: El atacante enrutó un intercambio final en PancakeSwap V2 a través del router, enviando solo ~4.749 LULA al par y recibiendo ~197,64M de USDT a cambio.
- Paso 5: El atacante devolvió todos los préstamos flash, obteniendo una ganancia de aproximadamente $578K.
Conclusión
El token LULA en BNB Chain fue explotado por aproximadamente $578K a través de una falla de lógica de negocio en su contrato de token: una ruta alcanzable por el atacante podía activar su función privilegiada recycle(), permitiendo al contrato Rental transferir LULA directamente fuera del par PancakeSwap V2 y luego llamar a sync(), resincronizando las reservas del par con los saldos manipulados. El atacante activó esto repetidamente para distorsionar el precio del par e intercambiar una pequeña cantidad de LULA por casi todo su USDT.
Un contrato de token nunca debe exponer una ruta privilegiada que pueda mover los saldos de un par AMM y forzar una resincronización de reservas, ya que esto entrega el control del precio a quien pueda alcanzar esa ruta. Los tokens que se integran con pares AMM deben mantener las reservas del par vinculadas a cambios de saldo genuinos impulsados por el mercado, y cualquier lógica que lea las reservas del pool para calcular precios debe tratarlas como manipulables en lugar de autoritativas.



