Back to Blog

La carrera contra el tiempo y la estrategia: sobre el rescate de AnySwap y las lecciones aprendidas

Phalcon
April 4, 2022
13 min read

El 18 de enero, nuestro sistema de monitoreo detectó un ataque contra el proyecto AnySwap (también conocido como Multichain). La vulnerabilidad se debe a la función anySwapOutUnderlyingWithPermit() defectuosa, cuyo mecanismo de verificación puede ser eludido para retirar los tokens aprobados.

Aunque el proyecto adoptó diferentes enfoques (por ejemplo, enviando transacciones a los usuarios, como se muestra en la Figura 1) para notificar a los usuarios afectados, varios de ellos no tomaron acciones oportunas (es decir, revocar las aprobaciones) para proteger sus fondos. Como resultado, los atacantes podían lanzar el ataque de forma continua para obtener los fondos de las víctimas.

Figura 1: El proyecto notificó a la víctima a través de mensajes de Ethereum
Figura 1: El proyecto notificó a la víctima a través de mensajes de Ethereum

Para proteger a las posibles víctimas, tras mucha deliberación, nuestro equipo decidió realizar un rescate de emergencia para el contrato vulnerable de AnySwap (0x6b7a87899490EcE95443e979cA9485CBE7E71522) en Ethereum. Específicamente, podemos transferir los fondos de la cuenta vulnerable a nuestra billetera de sombrero blanco, que es una billetera multifirma (0xd186540FbCc460f6a3A9e705DC6d2406cBcc1C47) en Ethereum.

Para hacer transparente nuestro rescate de sombrero blanco, documentamos nuestra intención en un archivo PDF y compartimos el hash del archivo con la comunidad. Esto permite diferenciar nuestro rescate de emergencia del ataque, sin filtrar los detalles al mismo tiempo (ya que la vulnerabilidad aún podía ser explotada). Lanzamos el rescate de emergencia desde el 21 de enero de 2022 hasta el 11 de marzo de 2022, y los mensajes correspondientes fueron publicados al público, de la siguiente manera:

Figura 2: Nuestro anuncio para realizar el rescate
Figura 2: Nuestro anuncio para realizar el rescate
Figura 3: El anuncio para detener el rescate
Figura 3: El anuncio para detener el rescate

El rescate de emergencia no es una tarea trivial. De hecho, existen varios desafíos, tanto técnicos como no técnicos, para lograr un rescate exitoso. Como el rescate de emergencia ya ha concluido, podemos revisar de manera integral todo el proceso y compartir las lecciones aprendidas. Creemos que esta experiencia puede arrojar algo de luz sobre cómo asegurar el ecosistema DeFi.

Conclusiones clave (TL;DR)

  • Existen competencias entre los diferentes participantes, incluidos los sombreros blancos y los atacantes. La tarifa de pago para los Flashbots aumentó rápidamente con el tiempo.
  • Los Flashbots no siempre funcionaron. En cambio, algunos atacantes recurrieron al uso del mempool normal para lanzar un ataque exitoso adoptando estrategias sofisticadas.
  • Algunos atacantes fueron blanqueados al devolver parte de los fondos robados, mientras que el resto fue conservado como recompensa. Este fenómeno, aunque no es la primera vez que ocurre, es controvertido en la comunidad porque tal incentivo puede no ser justo para los verdaderos sombreros blancos.
  • Para convencer a la comunidad, es una buena práctica que el sombrero blanco haga pública la acción de antemano sin filtrar ninguna información sensible detallada.
  • La comunidad puede trabajar en conjunto para realizar el rescate de manera más efectiva y eficiente. Por ejemplo, construyendo un mecanismo de coordinación para reducir/evitar las competencias entre sombreros blancos.

A continuación, primero ofrecemos una visión general del rescate durante este período. Luego, ilustramos nuestra forma de realizar el rescate y los desafíos que debían resolverse. Después, discutimos algunas lecciones aprendidas del rescate. Finalmente, proporcionamos algunos pensamientos/sugerencias que podrían ser significativos para asegurar el ecosistema.

0x1 Rescates y Ataques

0x1.1 Resultado General

Los ataques y rescates que observamos e investigamos en este informe han durado meses, desde el bloque 14028474 (18 de enero de 2022) hasta el bloque 14421215 (20 de marzo de 2022).

Las cuentas que realizaron rescates y ataques se resumen en la siguiente tabla. Por simplicidad, solo se dan los primeros cuatro bits de la dirección para representar una EOA. Una cuenta es una cuenta de rescate o una cuenta de ataque. Vale la pena señalar que el tipo de una cuenta se determina según las etiquetas marcadas por Etherscan.io, o las direcciones de destino de transferencia que observamos.

En total, hay 9 cuentas de rescate que rescataron 483.027693 ETH (con una tarifa de 295.970554 ETH, es decir, el 61.27% del monto total) y 21 cuentas de ataque que obtuvieron 1433.092224 ETH (con una tarifa de 148.903707 ETH, es decir, el 10.39% del monto total), respectivamente. Vale la pena señalar que la pérdida es una estimación aproximada debido a algunas interacciones complicadas. Por ejemplo, una cuenta de ataque podría convertirse en una cuenta de rescate después de negociar con AnySwap, y discutiremos tal fenómeno más adelante. La última columna de la tabla indica la tarifa enviada al minero, que se utilizó para ganar la competencia de uso de los Flashbots.

No. Cuenta Tipo # de Víctimas # de Pérdida (ETH) # de Tarifa (ETH)
1 0x14ca** Cuenta de rescate 50 432.958062 287.849654
2 0x9a65** Cuenta de rescate 23 22.569429 0.000000
3 0x9117** Cuenta de rescate 14 18.897622 7.213585
4 0x17d2** Cuenta de rescate 3 3.552833 0.000000
5 0x6360** Cuenta de rescate 21 3.540061 0.907168
6 0x0edd** Cuenta de rescate 7 1.498706 0.000000
7 0x281e** Cuenta de rescate 1 0.006000 0.000000
8 0xd83b** Cuenta de rescate 1 0.004000 0.000000
9 0x8af3** Cuenta de rescate 6 0.000980 0.000147
10 0x4986** Cuenta de ataque 332 456.004547 0.000000
11 0xfa27** Cuenta de ataque 42 433.438935 46.636389
12 0x48e9** Cuenta de ataque 66 312.014657 0.000000
13 0x5738** Cuenta de ataque 67 83.589240 62.587238
14 0x34b2** Cuenta de ataque 7 63.599821 20.642705
15 0xd374** Cuenta de ataque 86 45.452703 12.824763
16 0x1fe7** Cuenta de ataque 9 12.817241 0.000000
17 0x98f5** Cuenta de ataque 20 8.381273 0.000000
18 0x455d** Cuenta de ataque 11 5.047377 0.544263
19 0x1b45** Cuenta de ataque 6 4.942442 3.074813
20 0x3ec7** Cuenta de ataque 6 3.705686 0.741137
21 0xbca4** Cuenta de ataque 1 2.784250 1.392125
22 0xb0ab** Cuenta de ataque 18 0.834068 0.296000
23 0x0a5b** Cuenta de ataque 1 0.286750 0.143375
24 0x2d3a** Cuenta de ataque 2 0.080090 0.000000
25 0x835d** Cuenta de ataque 5 0.063945 0.000000
26 0x1dbd** Cuenta de ataque 1 0.027431 0.012893
27 0x813d** Cuenta de ataque 1 0.019528 0.008007
28 0x85dd** Cuenta de ataque 6 0.002240 0.000000
29 0x2394** Cuenta de ataque 1 0.000000 0.000000
30 0x6360** Cuenta de ataque 2 0.000000 0.000000

0x1.2 La Tendencia de la Tarifa para Pujar por los Flashbots

Como se mencionó anteriormente, los sombreros blancos necesitan competir con los atacantes para enviar las transacciones. Como resultado, el porcentaje de la tarifa al minero (en las transacciones de Flashbots) puede reflejar el nivel de la competencia. Para medirlo cuantitativamente, investigamos el porcentaje de tarifa (incluyendo transacciones de ataque y transacciones de rescate respectivamente) para cada bloque.

La Figura 4 muestra la tendencia que observamos hasta ahora (desde el bloque 14028474 hasta el bloque 14369199). Las primeras transacciones de ataque no implican ninguna tarifa, lo que significa que había pocas (o ninguna) competencias durante ese período. Esto es razonable porque estos ataques tempranos podrían no ser bien conocidos por otros.

De hecho, el primer ataque con tarifa (10%) ocurrió en el bloque 14029765. Desde entonces, el porcentaje de tarifa aumentó rápidamente a medida que se involucraron más participantes. Por ejemplo, el porcentaje alcanzó el 80% en el bloque 14072385, y pronto llegó al 91% en el bloque 14129449.

En resumen, la tendencia sugiere que definitivamente es una carrera armamentista para ganar la competencia ajustando más tarifas al(los) minero(s).

Figura 4: Porcentaje de tarifa de ataques y rescates
Figura 4: Porcentaje de tarifa de ataques y rescates

0x2 Nuestro Rescate y los Desafíos

0x2.1 La Forma de Realizar el Rescate

La idea básica para realizar el rescate es bastante sencilla. Específicamente, necesitamos monitorear las cuentas que han aprobado WETH al contrato vulnerable. Cuando hay algún WETH transferido a la cuenta, podemos transferirlo directamente a nuestra billetera multifirma explotando el contrato AnySwap vulnerable. Los requisitos clave son:

  • R1: Localizar eficientemente las transacciones que transfieren tokens a las cuentas de las víctimas. Denominamos estas transacciones como TXs transferidas en lo siguiente.
  • R2: Elaborar correctamente las transacciones para realizar el rescate. Denominamos estas transacciones como TXs de rescate en lo siguiente.
  • R3: Adelantarse con éxito a las transacciones enviadas por los atacantes (y cualquier otra tercera parte). Denominamos estas transacciones como TXs de ataque en lo siguiente.

R1 y R2 no son obstáculos para nosotros. Específicamente, hemos construido un sistema interno para monitorear el mempool, lo que nos permite localizar oportunamente las transacciones de transferencia. Además, también hemos desarrollado una herramienta para construir las transacciones automáticamente.

Sin embargo, R3 sigue siendo un desafío. Se podría esperar que los Flashbots puedan usarse para ganar la competencia. Sin embargo, no es tan fácil lograr el objetivo. En primer lugar, los atacantes también pueden adoptar los Flashbots. Como sistema de puja por tarifas, la tasa de éxito puede depender de la tarifa especificada al minero. La estrategia para establecer la tarifa debe determinarse. En segundo lugar, usar Flashbots podría no ser una buena opción debido a la intensa competencia. Por lo tanto, también enviamos transacciones normales usando el mempool. Para garantizar el éxito, debe considerarse la estrategia para colocar la transacción en la posición correcta. Finalmente, también competimos con otros sombreros blancos, cuyo comportamiento parece ser sospechoso en algunos casos.

0x2.2 Competencias en las que Participamos

En total, intentamos proteger a 171 posibles víctimas distintas, mientras que 10 de ellas se protegieron a sí mismas revocando las aprobaciones justo antes de que intentáramos realizar el rescate. De las 161 víctimas válidas restantes, solo logramos rescatar a 14 de ellas debido a las competencias. Los casos de fracaso se resumen en la siguiente tabla, involucrando 3 cuentas de rescate y 16 cuentas de ataque.

No. Cuenta Tipo # de Víctimas # de Pérdida (ETH) # de Tarifa (ETH) % Promedio de Tarifa
1 0x14ca** Cuenta de rescate 44 431.651020 286.891724 66.46%
2 0x9a65** Cuenta de rescate 7 11.321441 0.000000 0.00%
3 0x6360** Cuenta de rescate 3 3.300000 0.891000 27.00%
4 0x48e9** Cuenta de ataque 35 301.681589 0.000000 0.00%
5 0x5738** Cuenta de ataque 58 78.482472 58.851862 74.99%
6 0x34b2** Cuenta de ataque 2 53.591712 17.685265 33.00%
7 0xd374** Cuenta de ataque 6 23.658698 10.073638 42.58%
8 0x4986** Cuenta de ataque 16 22.900105 0.000000 0.00%
9 0x1fe7** Cuenta de ataque 6 12.057241 0.000000 0.00%
10 0x1b45** Cuenta de ataque 5 4.402442 3.010013 68.37%
11 0xbca4** Cuenta de ataque 1 2.784250 1.392125 50.00%
12 0x98f5** Cuenta de ataque 8 2.339543 0.000000 0.00%
13 0x455d** Cuenta de ataque 3 0.741817 0.175454 23.65%
14 0xfa27** Cuenta de ataque 3 0.320288 0.032590 10.18%
15 0x0a5b** Cuenta de ataque 1 0.286750 0.143375 50.00%
16 0x3ec7** Cuenta de ataque 1 0.245000 0.049000 20.00%
17 0xee7e** Cuenta de ataque 1 0.190000 0.096900 51.00%
18 0x835d** Cuenta de ataque 3 0.024533 0.000000 0.00%
19 0xb0ab** Cuenta de ataque 1 0.000618 0.000000 0.00%

Por lo tanto, existen algunas lecciones que estamos dispuestos a compartir con la comunidad.

0x3 Algunas Lecciones que Hemos Aprendido

0x3.1 ¿Cómo Determinar la Cantidad de Tarifa para el Minero de Flashbots?

En resumen, fuimos superados por 12 competidores, incluidas 2 cuentas de rescate y 10 cuentas de ataque, que estaban usando los Flashbots.

Nuestra estrategia para establecer la tarifa del minero fue bastante conservadora. Específicamente, nuestro objetivo era proteger a las víctimas gastando la menor tarifa posible. Por lo tanto, no aumentamos activamente la tarifa a menos que algunas TXs de ataque exitosas ya hubieran establecido la tarifa. Por ejemplo, si un atacante establece la tarifa en el 10% del fondo, entonces podríamos usar el 11% para el siguiente rescate para competir con ese atacante. Sin embargo, el resultado sugiere que esta estrategia no funcionó ya que los atacantes (o incluso algunos sombreros blancos) a menudo (si no siempre) aumentaban agresivamente la tarifa para superar a los demás, como se muestra a continuación:

  • La Figura 5 muestra que el atacante 0x5738** estableció el porcentaje de tarifa en 70% en el bloque 14071986.
  • La Figura 6 muestra que el sombrero blanco 0x14ca** estableció el porcentaje de tarifa en 79% en el bloque 14072255.
  • La Figura 7 muestra que el sombrero blanco 0x14ca** estableció el porcentaje de tarifa en 80%, en el bloque 14072385.
  • La Figura 8 muestra que el sombrero blanco 0x9117** estableció el porcentaje de tarifa en 81% en el bloque 14072417.
  • La Figura 9 muestra que el atacante 0x5738** estableció el porcentaje de tarifa en 86% en el bloque 14073395.
Figura 5: Tarifa del 70% especificada por el atacante 0x5738
Figura 5: Tarifa del 70% especificada por el atacante 0x5738
<center>Figura 6: Tarifa del 79% especificada por el sombrero blanco 0x14ca**</center>
Figura 6: Tarifa del 79% especificada por el sombrero blanco 0x14ca**
<center>Figura 7: Tarifa del 80% especificada por el sombrero blanco 0x14ca**</center>
Figura 7: Tarifa del 80% especificada por el sombrero blanco 0x14ca**
<center>Figura 8: Tarifa del 81% especificada por el sombrero blanco 0x9117**</center>
Figura 8: Tarifa del 81% especificada por el sombrero blanco 0x9117**
<center>Figura 9: Tarifa del 86% especificada por el atacante 0x5738**</center>
Figura 9: Tarifa del 86% especificada por el atacante 0x5738**

En resumen, parece ser un juego de suma cero que requiere modelar los comportamientos de los diferentes participantes para ganar la competencia.

En la práctica, sin embargo, es difícil encontrar estrategias mejores/óptimas y, al mismo tiempo, reducir el costo tanto como sea posible.

0x3.2 ¿Cómo Colocarse en la Posición Correcta en el Mempool?

Ahora parece que el rescate dependería de la carrera armamentista de la competencia de tarifas para pujar por los Flashbots. Sin embargo, descubrimos que usar Flashbots no era una panacea debido a la intensa competencia de otros participantes que no tenían nada que ver con el rescate y el ataque. En tal caso, incluso la tarifa más alta especificada por una TX de ataque no puede garantizar ganar la oportunidad de usar los Flashbots.

Alternativamente, una transacción normal con la posición correcta en el mempool puede tener la oportunidad de lograr el objetivo. La posición correcta aquí significa que la TX de rescate/ataque debe colocarse en la posición detrás de la TX transferida, y la posición debe estar muy cerca de la TX transferida (cuanto más cerca, mejor). Nótese que usando esta estrategia, el atacante 0x48e9** obtuvo 312.014657 ETH sin pagar ninguna tarifa a los mineros de Flashbots.

Las siguientes cuatro figuras demuestran las 2 mayores ganancias que obtuvo el atacante:

  • La Figura 10 muestra que una víctima depositó 50 ETH en la posición 65 del bloque 14051020, y la Figura 11 muestra que el atacante obtuvo los 50 ETH en la posición 66 del mismo bloque.
  • La Figura 12 muestra que una víctima depositó 200 ETH en la posición 161 del bloque 14052155, y la Figura 13 muestra que el atacante obtuvo los 200 ETH en la posición 164 del mismo bloque.
<center>Figura 10: TX transferida en la posición 65 enviada por la víctima 0x3acb**</center>
Figura 10: TX transferida en la posición 65 enviada por la víctima 0x3acb**
<center>Figura 11: TX de ataque en la posición 66 enviada por el atacante 0x48e9**</center>
Figura 11: TX de ataque en la posición 66 enviada por el atacante 0x48e9**
<center>Figura 12: TX transferida en la posición 161 enviada por la víctima 0xbea9**</center>
Figura 12: TX transferida en la posición 161 enviada por la víctima 0xbea9**
<center>Figura 13: TX de ataque en la posición 164 enviada por el atacante 0x48e9**</center>
Figura 13: TX de ataque en la posición 164 enviada por el atacante 0x48e9**

Obviamente, esta sofisticada estrategia es bastante útil e ilustrativa, y merece más atención y esfuerzo para aprender algo de ella.

0x4 Algunos Otros Pensamientos

0x4.1 ¿Hackeo de Sombrero Blanco o Ataque?

Cuando se trata del reconocimiento de los hackeos de sombrero blanco, pueden no ser tan sencillos como uno podría esperar.

Por ejemplo, la dirección 0xfa27 fue etiquetada como Multichain Exploiter 4 (Whitehat) por Etherscan.io. En realidad, al principio fue etiquetada como Multichain Exploiter 4. Después de varias rondas de negociación entre el atacante y el proyecto AnySwap, el atacante fue persuadido para devolver parte de los fondos robados.

  • En TX 0x3c3d**, AnySwap contactó al atacante:

Ante todo, gracias por obtener el weth. No estaba al tanto del hackeo y me di cuenta de la situación solo porque el weth nunca llegó a mi billetera después de la transacción de cowswap. Considerando la cantidad en juego, ¿aceptarías 50 eth como propina justa? Aquí está mi txn: 0x2db9a6a51604e2be8b2c3469773afb201f0b48a318fb7e5f5e49175e818df5ba 0xe50ed602bd916fc304d53c4fed236698b71691a95774ff0aeeb74b699c6227f7

  • En TX 0xd360**, el atacante respondió:

por favor verifica enviándome una tx de vuelta. Te enviaré los 258 eth restantes. 39 eth fueron para los mineros porque había otros atacantes, así que tuve que pagar esa propina para salvar el dinero.

  • En TX 0x354f**, AnySwap agradeció tras recibir los fondos:

Bien recibido, gracias por tu honestidad.

Obviamente, este atacante fue blanqueado y también obtuvo algunas ganancias del ataque. Casos similares han ocurrido varias veces en el pasado, y siguen siendo controvertidos en la comunidad porque tal incentivo puede no ser justo.

0x4.2 ¿Competencia Entre Hackeos de Sombrero Blanco?

Es necesario construir un mecanismo de coordinación para reducir/evitar las competencias entre los sombreros blancos. Tal competencia inevitablemente lleva a un desperdicio del poder de rescate. En este rescate, hay 54 víctimas (con 450 ETH de fondo) que fueron protegidas por otros tres sombreros blancos, mientras que también intentamos realizar el rescate.

La competencia entre sombreros blancos no solo desperdició el poder de rescate, sino que también elevó el costo de realizar el rescate. Por ejemplo, como se muestra en las figuras 7 y 8, las tarifas gastadas por las dos TXs de rescate de diferentes sombreros blancos son del 80% y el 81% respectivamente.

Desafortunadamente, los sombreros blancos no darán un paso atrás a menos que exista algún mecanismo para coordinarse entre sí. De lo contrario, es imposible hacer desaparecer la competencia.

0x4.3 ¿Cómo Realizar un Mejor Rescate?

Por un lado, para convencer a la comunidad, es una buena práctica que el sombrero blanco haga pública la acción de antemano sin filtrar ninguna información sensible detallada. Hay suficiente tiempo para hacerlo ya que el rescate suele ser una batalla de vaivén con múltiples intentos, lo cual es diferente de algunos esfuerzos únicos como bloquear un ataque particular. Por supuesto, la información detallada sobre las vulnerabilidades no debe filtrarse.

Para lograr esto, la información detallada no se divulgará al principio y se divulgará a la comunidad después de completar el rescate, tal como lo hemos hecho para el rescate de AnySwap. Sin embargo, el hash del documento con la intención del sombrero blanco puede compartirse con la comunidad.

Por otro lado, la comunidad puede hacer más cosas para realizar el rescate de manera más efectiva y eficiente, incluyendo, pero no limitado a:

  • Flashbots/Miner puede proporcionar un canal verde para los sombreros blancos certificados. El canal verde puede proporcionar una alta prioridad para adelantarse a las TXs de los atacantes y evitar la competencia entre sombreros blancos.
  • Los proyectos atacados cubren el costo de Flashbots/mineros.
  • Los proyectos pueden aplicar mecanismos de notificación convenientes y rápidos a los usuarios.
  • El proyecto puede aplicar el mecanismo de emergencia en el código.

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 a mejorar la seguridad y la usabilidad para el 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 de seguridad y el bloqueo proactivo de amenazas, la plataforma MetaSleuth para el seguimiento e investigación de fondos, y la extensión MetaSuites para que los constructores 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 estadounidenses en dos rondas de financiamiento de inversores prominentes, incluidos Matrix Partners, Vitalbridge Capital y Fenbushi Capital.

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

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