Back to Blog

El Análisis del Incidente de Seguridad de FEGtoken: El Diablo Está en los Detalles

Code Auditing
May 18, 2022
6 min read

El 15 de mayo de 2022 aproximadamente a las 8:20 PM (UTC), nuestro sistema de monitoreo detectó que el contrato FEGexPRO del proyecto FEGtoken fue hackeado. El atacante lanzó una serie de ataques tanto en la red principal de ETH como en la de BSC y el valor total involucrado acumuló aproximadamente $1.3m (según el mensaje en cadena enviado por el proyecto).

Más información sobre este incidente se puede encontrar en el Twitter oficial de este proyecto. En este informe, profundizaremos en los detalles para revelar la causa raíz de este incidente.

0x1 Análisis de Vulnerabilidad: A Primera Vista

El contrato vulnerable FEGexPRO está desplegado tanto en ETH como en BSC, y la función vulnerable del contrato es swapToSwap, como se muestra a continuación:

Como se señaló en las redes sociales, el primer parámetro llamado path de la función swapToSwap puede ser especificado por quien llama a la función. De este modo, el atacante podría explotarlo para realizar una aprobación arbitraria (véase la línea 682 de la función swapToSwap).

Hasta aquí nada es nuevo, ya que es otro caso más de parámetro(s) no verificado(s). Sin embargo, el rastro del ataque sugiere que este ataque no puede ilustrarse claramente simplemente atribuyéndolo a la aprobación arbitraria. De hecho, existe un truco sutil, y aquí es donde las cosas se vuelven interesantes.

0x2 Análisis del Ataque

0x2.1 Análisis Preliminar del Ataque

Tomamos una transacción de ataque en BSC como ejemplo para ilustrar el procedimiento del ataque, y el rastro de ataque correspondiente que apunta al activo fBNB se resume brevemente a continuación:

  • Paso 1: preparación de fondos y paths falsos. El atacante pide prestado mediante flashloan aproximadamente 915 BNB de DVM e intercambia parte de ellos por 116 fBNB. Luego el atacante crea una serie de contratos que serán utilizados como paths falsos.
  • Paso 2: depósito del fondo inicial. Al depositar 115 fBNB en el contrato FEGexPRO, el atacante incrementa su balances2 en el contrato víctima.
  • Paso 3: realización de la aprobación arbitraria. El atacante invoca la función swapToSwap y pasa un path falso como primer parámetro, lo que lleva al contrato FEGexPRO a aprobar al path para gastar 114 fBNB.
  • Paso 4: realización de otra aprobación invocando la función depositInternal y la función swapToSwap. El contrato FEGexPRO aprueba otro path para gastar 114 fBNB.

El atacante lanza el Paso 4 repetidamente para obtener más aprobaciones. Finalmente, el atacante utiliza los paths falsos aprobados para drenar todos los fBNB de FEGexPRO e intercambia algunos por BNB para reembolsar el flashloan.

Evidentemente, podemos deducir fácilmente que el contrato absolutamente debería haber verificado el parámetro path.

SIN EMBARGO, para entender completamente este ataque, hay un problema más que abordar: incluso si el contrato FEGexPRO aprueba el path falso, la operación approve se basa en el hecho de que el balances2 del usuario se reduciría inmediatamente (línea 684 de la función swapToSwap), es decir, el fondo aprobado proviene exactamente de la cantidad depositada en el Paso 3. En otras palabras, el atacante simplemente aprueba los fondos que él/ella mismo depositó al path falso. Después de eso, el atacante no debería poder hacer aprobaciones para otros paths falsos debido a la disminución del balances2.

Por lo tanto, surge la pregunta: ¿cuál es exactamente el truco que emplea el atacante para hacer otras aprobaciones y obtener ganancias adicionales?

0x2.2 Análisis Avanzado del Ataque

Para responder a la pregunta, debemos volver a la función swapToSwap. Tras examinar cuidadosamente el código, encontramos que el truco aquí no es solo un path falso sino también un swap falso, lo que provoca una inconsistencia entre el valor real y el registrado del saldo del contrato víctima. Como resultado, la inconsistencia puede usarse para realizar repetidamente la aprobación invocando la función depositInternal para restaurar el monto de depósito del atacante.

Específicamente, la función depositInternal modifica el balances2 de un usuario principalmente basándose en la diferencia entre Main.balanceOf del contrato y _totalSupply2 (línea 651 de la función depositInternal).

Dado que la dirección path pasada al swapToSwap es un path falso controlado por el atacante, en realidad no se transfiere nada. Como consecuencia, el valor de retorno de Main.balanceOf permanece igual que en el Paso 3. Nótese que _totalSupply2 ha sido disminuido en la función swapToSwap, por lo que mientras el atacante deposite, el balance2 incrementado será inevitablemente mayor que el monto real depositado.

Por lo tanto, en el Paso 4, el atacante primero restaura el monto del depósito invocando la función depositInternal, y luego realiza la aprobación y el swap falso invocando la función swapToSwap. Nótese que el monto de depósito utilizado por el atacante es casi 0 (es decir, 1 / 1e18) fBNB, por lo que la función depositInternal restauraría el balances2 del atacante a casi la misma cantidad del Paso 3 como se explicó anteriormente (lo cual también queda demostrado por el rastro de la siguiente aprobación).

El atacante puede ampliar el botín ejecutando el Paso 4 repetidamente.

Finalmente, vale la pena señalar que el ataque que describimos anteriormente es solo uno de los caminos de ataque explotados por el atacante. En la misma transacción de ataque, el atacante también apunta al activo FEG:

0x3 La Causa Raíz

Aquí resumimos la causa raíz de este ataque:

  • Primero, la aprobación arbitraria causada por el parámetro no verificado en la función swapToSwap.
  • Segundo, la inconsistencia entre el valor real y el registrado del saldo del contrato víctima debido al swap falso en la función swapToSwap. Esto se utiliza para realizar repetidamente las aprobaciones restaurando el monto de depósito del atacante.

Combinándolos, el atacante logró drenar todos los fondos del contrato víctima.

0x4 Otros Ataques Relacionados

Al momento de redactar este informe, también observamos más ataques relacionados lanzados por otro atacante.

Nuevamente, fueron atacados contratos desplegados tanto en Ethereum como en BSC. Curiosamente, los rastros del ataque son diferentes al que acabamos de discutir. Aunque los contratos víctima no son de código abierto, sospechamos fuertemente que el atacante explotó la misma vulnerabilidad con un método de ataque similar.

0x5 Conclusiones

Hacer que un proyecto DeFi sea seguro no es una tarea fácil. Además de la auditoría de código, creemos que la comunidad debería adoptar un método proactivo para monitorear el estado del proyecto y bloquear el ataque antes de que ocurra.

Acerca de BlockSec

BlockSec es una empresa pionera en seguridad blockchain fundada en 2021 por un grupo de expertos en seguridad de renombre mundial. La empresa está comprometida con mejorar la seguridad y la usabilidad del emergente mundo Web3 con el fin de facilitar su adopción masiva. Con este fin, BlockSec ofrece servicios de auditoría de seguridad de contratos inteligentes y cadenas EVM, la plataforma Phalcon para el desarrollo seguro y el bloqueo proactivo de amenazas, la plataforma MetaSleuth para el rastreo e investigación de fondos, y la extensión MetaDock para que los desarrolladores de web3 naveguen eficientemente en el mundo cripto.

Hasta la fecha, la empresa ha atendido a más de 300 clientes distinguidos como MetaMask, Uniswap Foundation, Compound, Forta y PancakeSwap, y ha recibido decenas de millones de dólares en dos rondas de financiación de inversores prominentes, incluyendo Matrix Partners, Vitalbridge Capital y Fenbushi Capital.

Sitio web oficial: https://blocksec.com/

Cuenta oficial de Twitter: https://twitter.com/BlockSecTeam

Best Security Auditor for Web3

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

BlockSec Audit