martes, abril 19, 2022

Reentrancy Attack: Cómo te roban criptomonedas por un bug en tu SmartContract

En el equipo de Ideas Locas somos un grupo muy ágil y multidisciplinar que está dispuesto a meterse en muchos fregados, siempre que se pueda. La irrupción de la Web3, el Metaverso y las tecnologías subyacentes hacen que como equipo de pre-innovación nos involucremos en proyectos especiales a ver qué cosas se pueden hacer. El artículo de hoy se centra sobre una tecnología que revolucionó el mundo digital. Se trata de SmartContracts en BlockChain que está evolucionando mucho, así como Ethereum, por lo que hemos puesto el ojo en la seguridad de éstos.

Figura 1: Reentrancy Attack: Cómo te roban
criptomonedas por un bug en tu SmartContract

Estudiando cómo funcionan los SmartContracts, hay que tener en cuenta que lo que nos dice el contrato es lo que se ejecutará (no hay mucha más interpretación), pero  puede ocurrir que si no tenemos cuidado en el desarrollo del contrato podemos caer en una gran cantidad de vulnerabilidades. Una de las más famosas son las que habilitan los  "Ataques de ‘Reentrancy’"

Figura 2: Libro dedicado a "Bitcoin: La tecnología Blockchain y su investigación"
de Yaiza Rubio y Félix Brezo

En este artículo se puede ver un ejemplo claro sobre la peligrosidad que tienen este tipo de vulnerabilidades y cómo poder evitarlo en el código. Para algunos es una vulnerabilidad del pasado, debido a que afectó a contratos años atrás, pero lo cierto es que es una de las vulnerabilidades que debemos tener muy en cuenta a la hora de programar, ya que su explotación puede impactar, directamente, en los fondos de los contratos.

Casos de Reentrancy Attack

Antes de nada, y como puede leerse en hackernoon, existen algunos casos donde se puede ver el impacto que un ‘Reentrancy Attack’ puede tener sobre los fondos de un contrato. A continuación os dejamos un listado:
  • Uniswap/Lendf.Me: En abril de 2020 fueron sustraídos 25 millones de dólares utilizando este tipo de ataque.
  • BurgerSwap: En mayo de 2021, 7.2 millones de dólares fueron sustraídos a través de un ‘fake’ token contract y un exploit de Reentrancy.
  • Cream Finance: En agosto de 2021, 18.8 millones de dólares debido a una vulnerabilidad de Reentrancy.
Y hay muchos más casos. Como se puede ver un SmartContract gestiona activos de mucho valor, por lo que una mala implementación en código puede suponer la pérdida de dichos activos de todos los usuarios que participan en el contrato. Pero…, ¿en qué consiste este tipo de vulnerabilidad? Si nos fijamos en el siguiente esquema, podemos encontrar el siguiente escenario:
  • Tenemos un contrato que gestiona fondos de diferentes usuarios. Lo llamaremos contrato A.
  • El contrato A tiene varias funciones: checkbalance(), sendfunds() y updatebalance().
Es decir, simplemente por una mala definición de las funciones de un SmartContrats un usuario con su wallet o un contrato pueden pedir al contrato A que le reembolse lo que tiene, ya que se puede chequear el balance del contrato, se puede enviar fondos al contrato A y se puede hacer un update de los fondos. Este update para nosotros, en este ejemplo, es una solicitud de reembolso de fondos


Hasta aquí todo normal, el contrato A gestiona fondos de diferentes usuarios y permite a los usuarios “sacar” fondos y devolvérselos. ¿Dónde entra la vulnerabilidad? Pensemos en que el flujo normal sería el siguiente:
  • Un usuario o el contrato B (en este caso) solicitan devolución de fondos al contrato A.
  • El contrato A verifica que se puede devolver dichos fondos.
  • Cuando el contrato A comienza la devolución de fondos, el contrato B no finaliza la función de fallback (la cual es una función para la devolución de fondos en un contrato) y vuelve a solicitar la devolución de fondos al contrato A.
  • El contrato A verifica que se puede devolver dichos fondos y, aquí está el fallo, como no se ha actualizado el valor de los fondos que tiene dicho contrato, se procede a enviar los fondos de nuevo.
  • Cuando el contrato B es invocado con su función de fallback, vuelve a no finalizar dicha función y volver a llamar al contrato A solicitando devolución de fondos.
  • Se puede observar que existe una pila de llamadas recursivas por parte del contrato B al contrato A.
El fallo radica en que el contrato A se quedará sin fondos ya que atenderá a todas las llamadas del contrato B.

¿Por qué ocurre esto?

 Si nos fijásemos en este hipotético contrato (contrato A) veríamos que actualiza los fondos, una vez que hace el envío de fondos. Como el envío de fondos no está finalizando y el contrato B vuelve a pedir devolución, se puede entender que el contrato B va recibiendo dichos fondos. Solo cuando el contrato A se queda sin fondos (aunque la comprobación de que el contrato B tiene fondos sigue saliendo verdadera, ya que no se hizo el update de fondos) es cuando este número indeterminados de llamadas a la función de devolución finaliza.

El problema es que el update viene después del envío de fondos, pero si el envío de fondos no finaliza y se vuelve a llamar a la función de devolución habrá problemas.

Mitigación de la vulnerabilidad

¿Cómo se arregla esto? Bueno, viendo el ejemplo se puede entender que debemos tener en cuenta cuando hacer el update. En Cryptomarket indican lo siguiente:
  • Actualizar el balance de fondos antes de llamar a la función de devolución (o código externo).
  • Se puede hacer usos de cerrojos (para evitar una condición de carrera) con el objetivo de bloquear la instrucción de devolución fondos hasta que no haya finalizado el código externo (es decir, la función de fallback del contrato B). Si la función de fallback acaba, se desbloquearía el cerrojo.
Hace unos días participé en OpenExpo Cibersecurity Day 2022 dando una charla sobre Seguridad en SmarContracts, que os dejo por aquí en vídeo por si fuera de vuestro interés, ya que hablo de ésta y otras vulnerabilidades


Todo lo mostrado y enseñado durante la charla es a modo educativo, y para que entendáis lo que ya se está haciendo con estas vulnerabilidades. El objetivo es concienciar a las personas y que aprendan a evitar estas vulnerabilidades. Más artículos sobre este mundo Web3:

Saludos,

Autor: Pablo González Pérez (@pablogonzalezpe), escritor de los libros "Metasploit para Pentesters", "Hacking con Metasploit: Advanced Pentesting" "Hacking Windows", "Ethical Hacking", "Got Root",  “Pentesting con Powershell” y de "Empire: Hacking Avanzado en el Red Team", Microsoft MVP en Seguridad y Security Researcher en el equipo de "Ideas Locas" de la unidad CDCO de Telefónica.  Para consultas puedes usar el Buzón Público para contactar con Pablo González

Contactar con Pablo González

No hay comentarios:

Publicar un comentario