Back to Blog

~88M USD perdidos: exploits de COLDCARD y LULA | BlockSec Weekly

Code Auditing
5 de agosto de 2026
13 min read
Key Insights
  • En este informe se destacan 2 incidentes de seguridad notables que, en conjunto, representan pérdidas de aproximadamente $88M en Bitcoin y BNB Chain. Un único fallo de entropía en un hardware wallet (COLDCARD) provocó más del 99% del total, un recordatorio de que un error silencioso en la configuración de compilación del firmware de una wallet puede socavar la entropía de la que depende la seguridad de los fondos.

  • Los dos incidentes revelan patrones de vulnerabilidad distintos: una generación de entropía defectuosa en el firmware de una wallet (COLDCARD), donde la creación de la semilla recurrió silenciosamente a un generador de números pseudoaleatorios (PRNG) de software determinista en lugar del generador de números aleatorios (RNG) de hardware, y una falla de lógica de negocio en un token de BNB Chain (LULA), donde una ruta accesible por un atacante podía activar la función privilegiada recycle(), permitiendo que el contrato Rental transfiriera LULA fuera de un par de PancakeSwap V2 y resincronizara sus reservas al saldo manipulado.

  • La falla de COLDCARD se distribuyó en 2021 y no fue explotada a gran escala hasta finales de julio de 2026, cuando las wallets afectadas fueron vaciadas en una serie de oleadas en cadena que comenzaron el 30 de julio. La falla raíz fue que el firmware nunca comprobó que su API de generación de semillas alcanzara realmente el RNG de hardware previsto: una protección de compilación solo verificaba si existía una macro de configuración, no su valor. Las protecciones de compilación para la entropía criptográfica deben verificar el valor de la macro y fallar de forma segura (fail closed), y los componentes de firma y generación de claves fuera de la cadena (off-chain) merecen una revisión de seguridad igualmente rigurosa.

Durante la última semana (27/07/2026 - 02/08/2026), se destacan los siguientes 2 incidentes de seguridad notables, que en conjunto representan aproximadamente $88M en pérdidas.

Fecha Incidente Tipo Pérdida Estimada
29/07/2026 LULA Falla de Lógica de Negocio ~$578K
30/07/2026 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: el mínimo mostrado de ~1,370 BTC (~$88M) es el mínimo verificable públicamente en cadena (coldcardwatch.com); la reconciliación a través de canales privados (Galaxy Research, a partir de correspondencia con 73 víctimas) la sitúa más alta, en aproximadamente 1,596 BTC y hasta ~2,055 BTC (~$130M) una vez incluidos los drenajes sospechosos pero no confirmados.

Razones de la selección

  • LULA: Una función de token privilegiada que puede mover los balances de un par AMM y forzar una resincronización de reservas se convierte en un mecanismo repetible de drenaje de liquidez 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 mecanismo alternativo de software determinista, socavando las garantías de entropía y convirtiendo la recuperación de semillas en una búsqueda fuera de línea que escaló hasta una pérdida de fondos a gran escala.

El Mejor Auditor de Seguridad para Web3

Valide el diseño, el código y la lógica de negocio antes del lanzamiento

Destacado Semanal: COLDCARD

Seleccionamos COLDCARD como el destacado de esta semana porque un error de entropía en una billetera produjo la mayor pérdida del período. La causa raíz, una protección de compilación que verificaba si existía una macro de configuración en lugar de si estaba habilitada, es el tipo de error de integración silencioso 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, lanzó en 2021 un firmware que generaba semillas de billetera utilizando 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 suman al menos 1,370 BTC (~$88M, al precio de $64,099 del 5 de agosto) [3], mientras que los informes confirmados de forma privada sitúan la cifra hasta en 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 mecanismo alternativo 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 fuera de línea.

Antecedentes

COLDCARD es una billetera de hardware de Bitcoin. Las claves privadas y direcciones de una billetera se derivan todas de un único valor secreto, su semilla, por lo que la seguridad de cualquier billetera de autocustodia descansa en dos propiedades de esa semilla: que permanezca secreta y que sea impredecible cuando se genera. Las billeteras de hardware existen en gran medida para proteger la primera propiedad; este incidente es un fallo de la segunda. Una frase semilla BIP-39 es legible para 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 una caja fuerte cuya combinación se elige lanzando dados: si los dados están trucados, la caja fuerte queda abierta para cualquiera que conozca el sesgo, sin importar cuán fuerte sea la cerradura.

Para una billetera, "dados trucados" 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 con datos públicos de la billetera, como una dirección, un xpub o una clave pública, lo cual convierte la recuperación de semillas de un problema criptográficamente inviable en una búsqueda fuera de línea.

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 la biblioteca criptográfica de la billetera esperaba, mientras que COLDCARD también mantenía su propio contenedor 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 RNG global resuelto en el momento de compilar el firmware.

Análisis de la Vulnerabilidad

La causa raíz fue un error de compilación e integración en torno a la macro de configuración MICROPY_HW_ENABLE_RNG. La configuración de placa de producción de COLDCARD establecía esta macro en 0, porque el firmware pretendía usar su propio contenedor 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 era la siguiente:

generate_seed()
  -> ngu.random.bytes(32)
  -> libngu CHIP_TRNG_32()
  -> rng_get()
  -> MicroPython STM32 RNG module
  -> Yasmarang software fallback because MICROPY_HW_ENABLE_RNG == 0

La configuración de la placa deshabilitó la rama de RNG de hardware de MicroPython:

// We have our own version of this code.
#define MICROPY_HW_ENABLE_RNG (0)

La biblioteca criptográfica seguía tratando 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 protección pasa por alto el caso peligroso: una macro definida como 0 sigue estando definida, por lo que la verificación #ifndef se supera y la compilación se completa con éxito. Debido a que MicroPython selecciona su implementación de RNG según el valor de la macro y no según su existencia, MICROPY_HW_ENABLE_RNG == 0 enrutó rng_get() hacia la rama de mecanismo alternativo de software en lugar del contenedor local a la placa de COLDCARD [6]:

#if MICROPY_HW_ENABLE_RNG
    // STM32 hardware RNG
#else
    // Yasmarang software fallback
#endif

Las consecuencias difieren según la generación del dispositivo. Para el firmware v4.0.0-v4.1.9 de Mk2/Mk3, 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 mecanismo alternativo y el historial de llamadas (el aviso de Coinkite [2] delimita el rango Mk2/Mk3 de forma algo más restringida, como v4.0.1-v4.1.9). Para Mk4/Q/Mk5, el material del elemento seguro se procesó con hash, pero solo se pasaron cuatro bytes a ngu.random.reseed(), limitando el resiembra segura a una única palabra de estado de 32 bits, un espacio de búsqueda mucho menos efectivo que la entropía de billetera que los usuarios esperan. Aplicar hash a 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 la explotación de un contrato inteligente, este incidente no tiene una única transacción de ataque en cadena que rastrear. Fue un problema de recuperación de semillas fuera de línea seguido de vaciados en cadena. La precondición era que los usuarios afectados hubieran generado sus semillas de billetera a través de la ruta vulnerable ngu.random.bytes(32), de modo que el material de su semilla dependía de un estado de mecanismo alternativo de software reproducible en lugar de entropía de hardware completa. Una segunda precondición, inferida, es que las billeteras afectadas fueran derivables únicamente a partir de la semilla: una frase de contraseña BIP-39 fuerte y única mezcla entropía independiente y proporcionada por el usuario a través de PBKDF2 que la falla de RNG nunca tocó, lo que coloca a esas 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 dicha frase de contraseña. A partir de ahí, la recuperación probablemente procedió en tres pasos:

  1. El atacante restringió o enumeró estados candidatos de RNG utilizando metadatos del dispositivo, tiempos de arranque, suposiciones de RTC/SysTick e historiales plausibles de llamadas al RNG.
  2. Para cada estado candidato, el atacante derivó semillas de billetera candidatas y las verificó fuera de línea contra datos públicos de billetera, como direcciones, xpubs o claves públicas generadas.
  3. Una vez que un candidato coincidía con una billetera real, el atacante recuperaba la semilla, reconstruía las claves privadas y vaciaba el BTC asociado.

En cadena, el robo apareció como una ráfaga de vaciados de direcciones que comenzó el 30 de julio. El seguimiento heurístico independiente en cadena [3] identifica varias oleadas de drenaje que suman al menos 1,370 BTC (aproximadamente $88M, valorando las monedas al precio de BTC de $64,099 del 5 de agosto) vaciados de 4,580 direcciones verificadas, un mínimo verificado en lugar de un total. Mientras tanto, un canal privado [4], confirmado mediante correspondencia con 73 víctimas, sitúa la cifra hasta en aproximadamente 1,596 BTC, elevándose hacia 2,055 BTC (~$130M) una vez que se añaden los drenajes sospechosos pero no confirmados.

Conclusión

El incidente de COLDCARD fue un fallo de generación de entropía: la API de generación de semillas, crítica para la seguridad, se resolvió silenciosamente hacia un mecanismo alternativo de PRNG de software determinista en lugar del RNG de hardware previsto, porque una protección 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 fuera de línea, y el resultado fue el vaciado de más de 1,370 BTC [3] en múltiples oleadas (los recuentos de canales privados la sitúan en aproximadamente entre 1,596 y 2,055 BTC [4]).

El fallo de ingeniería central es que el firmware lanzado nunca demostró que su API más crítica para la seguridad realmente alcanzara el RNG de hardware previsto. Tres prácticas lo habrían detectado: las protecciones de compilación para la entropía criptográfica deben verificar tanto la existencia de la macro como su valor; los mecanismos alternativos 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 repararse en su lugar; sus fondos deben moverse 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 caen colectivamente en un rango pequeño y enumerable. Los componentes de generación de claves fuera de cadena merecen un escrutinio de seguridad de primer nivel.

Referencias

Comience con Phalcon Explorer

Sumérjase en las Transacciones para Actuar con Sabiduría

Pruébelo gratis ahora

Más Incidentes 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 accesible por el atacante podía activar su función privilegiada recycle(), permitiendo que el contrato Rental transfiriera LULA directamente fuera del par PancakeSwap V2 y luego llamara a sync(), actualizando las reservas del par a los balances manipulados. El atacante activó recycle() repetidamente para reducir la reserva de LULA del par casi hasta cero, y luego intercambió una pequeña cantidad de LULA por casi todo su USDT [1].

Antecedentes

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 destinado a la distribución de recompensas. recycle() no puede ser llamado por usuarios arbitrarios; solo el contrato Rental está autorizado a ejecutarlo.

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 de código delegado.

En un creador de mercado automatizado (AMM), un par fija los precios de los intercambios a partir de sus reservas almacenadas, y esas reservas se actualizan mediante la función sync() del par, que las establece según los balances actuales de tokens del par. Las reservas normalmente reflejan el trading genuino porque se mueven con los intercambios y los eventos de liquidez, pero el balance de tokens de un par también puede cambiarse mediante una transferencia directa, y sync() copia el balance presente, sea manipulado o no, hacia las reservas almacenadas.

Análisis de la Vulnerabilidad

La causa raíz fue que LULA.recycle() permitía que el contrato Rental transfiriera LULA directamente fuera del par PancakeSwap V2 y luego llamara a sync(), actualizando las reservas del par a los balances manipulados [1].

Debido a que sync() establece las reservas según cualquiera que sea el balance de LULA que quede en el par, esta ruta privilegiada puede llevar la reserva de LULA del par a niveles arbitrariamente bajos mientras deja intacto el lado del USDT. Una vez que la reserva de LULA está cerca de cero, el par fija el precio de una pequeña cantidad de LULA como si valiera 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 provinieron de múltiples fuentes de préstamos flash y préstamos, incluyendo 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 -> LULA a través del router de PancakeSwap V2. Esto redujo drásticamente la reserva de LULA del par de unos 8M de LULA a 24,022 LULA, mientras aumentaba el lado de USDT a aproximadamente 197.64M de USDT.
  • Paso 3: El atacante invocó la ruta de recompensas a través de múltiples billeteras EIP-7702. Cada billetera llamó a claimTeamReward() en el contrato Rental, que a su vez activó LULA.recycle(), reduciendo la reserva de LULA del par de 24,022 LULA a 0.004 LULA mientras el par todavía mantenía un lado de USDT muy grande.
  • Paso 4: El atacante enrutó un intercambio final de PancakeSwap V2 a través del router, enviando solo ~4,749 LULA al par y recibiendo ~197.64M de USDT.
  • Paso 5: El atacante devolvió todos los préstamos flash, obteniendo una ganancia aproximada de $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 accesible por el atacante podía activar su función privilegiada recycle(), permitiendo que el contrato Rental transfiriera LULA directamente fuera del par PancakeSwap V2 y luego llamara a sync(), resincronizando las reservas del par con los balances manipulados. El atacante activó esto repetidamente para sesgar el precio del par e intercambiar una pequeña cantidad de LULA por casi todo su USDT.

Un contrato de token nunca debería exponer una ruta privilegiada que pueda mover los balances de un par AMM y forzar una resincronización de reservas, porque hacerlo otorga el control del precio a quien sea capaz de acceder a esa ruta. Los tokens que se integran con pares AMM deben mantener las reservas del par vinculadas a cambios de balance genuinos y guiados por el mercado, y cualquier lógica que lea las reservas del pool para fijar precios debería tratarlas como manipulables en lugar de autoritativas.

Referencias

Comience con Phalcon Security

Detecte cada amenaza, alerte sobre lo que importa y bloquee los ataques.

Pruébelo gratis ahora

Acerca de BlockSec

BlockSec es un proveedor integral de seguridad blockchain y cumplimiento normativo cripto. Desarrollamos productos y servicios que ayudan a los clientes a realizar auditorías de código (incluyendo contratos inteligentes, blockchain y billeteras), interceptar ataques en tiempo real, analizar incidentes, rastrear fondos ilícitos y cumplir con las obligaciones de AML/CFT, a lo largo de todo el ciclo de vida de los protocolos y las plataformas.

BlockSec ha publicado múltiples artículos de seguridad blockchain en conferencias prestigiosas, ha reportado varios ataques de día cero en aplicaciones DeFi, ha bloqueado múltiples hackeos para rescatar más de 20 millones de dólares, y ha protegido miles de millones en criptomonedas.

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit