Seguimos con nuestra política de intentar publicar un reto mensual y solucionar otro de los retos antiguos de nuestra plataforma de aprendizaje y retos en Web3 Level_UP! En esta ocasión vamos a solucionar ReLottery, el cual implementa una de las vulnerabilidades más críticas que se pueden encontrar en el mundo Web3. Ya hemos hablado en el blog alguna que otra vez sobre las vulnerabilidades de Re-Entrancy, pero hoy vamos a ver cómo funciona en la plataforma de Level_UP! y conseguir los puntos.
Además, hacia el final del artículo os hablaremos del nuevo reto llamado Pay Me! Un reto de dificultad 1, es decir, de nivel introductorio en el que el usuario deberá interpretar el contrato para entender lo que hay que hacer para conseguir la flag. En este mes de agosto, que estamos acabando, ya viene bien un reto ‘suave’ en temas de dificultad y proporcionar a los que empiezan otro reto con el que aprender nuevos conceptos y nuevas formas de interactuar con los SmartContract.
Comenzamos hablando del reto ReLottery, el cual tiene una dificultad de 4 sobre 5. No es un reto sencillo, aunque conociendo la vulnerabilidad de Re-Entrancy y sabiendo cómo funciona las cosas se simplifican.
Figura 1: Level_Up!: El WriteUp del reto "ReLottery"
y un nuevo reto de agosto llamado “Pay Me!”
Además, hacia el final del artículo os hablaremos del nuevo reto llamado Pay Me! Un reto de dificultad 1, es decir, de nivel introductorio en el que el usuario deberá interpretar el contrato para entender lo que hay que hacer para conseguir la flag. En este mes de agosto, que estamos acabando, ya viene bien un reto ‘suave’ en temas de dificultad y proporcionar a los que empiezan otro reto con el que aprender nuevos conceptos y nuevas formas de interactuar con los SmartContract.
Figura 2: Level_Up! en GitHub
El reto ReLottery
En la descripción del reto ya nos comentan que deberemos desplegar un contrato para implementar el ataque. También nos indican como pista que el contrato tiene unos pocos fondos y que deberá quedarse a 0 para poder conseguir la flag. Si observamos la función getFlag() podemos ver en el código del contrato que necesitamos que el balance del contrato sea 0. En el instante que sea 0, se podrá obtener la flag.
Leyendo el reto y el contrato podemos encontrar que se simula un entorno de lotería, dónde el usuario o player tiene que adquirir un boleto y puede pedir el reembolso de este si no quiere participar en el sorteo.
Para poder pedir un reingreso o reembolso de lo que hemos depositado en el contrato, primero deberemos pagar y adquirir uno o varios boletos. Por esta razón, tenemos la función ‘pagarBoleto’. Se nos pide abonar al menos 1000000 wei. Con esta acción ya conseguiremos al menos un boleto y podremos pedir reembolso. La función ‘anularBoleto’ permite recuperar los fondos pagados en la previa compra de un boleto. Esta es la función ‘anularBoleto’ y su código.
Lo que se puede ver es que se comprueba que el usuario que pide anular el boleto tiene fondos pagados, es decir, ha comprado previamente un boleto. La segunda instrucción de la función realiza el pago al que solicita el reembolso. Si el solicitante de reembolso es un wallet se le enviará sus fondos, el segundo require se resolvería correctamente y se actualizarían los fondos del usuario en el contrato.
Justo aquí está el problema, se actualizan los fondos del usuario en última instancia. ¿Qué ocurre si cuando devuelven los fondos, no se da el ‘ok’ y se vuelve a solicitar de forma recurrente el reembolso? Aquí tenemos la vulnerabilidad de Re-Entrancy.
Si el usuario que pide el reembolso es un contrato, se puede definir cómo actúa el contrato en el momento que recibe fondos: funciones receive y fallback. A continuación, se muestra un ejemplo de contrato que se puede desplegar para interactuar con el contrato ReLottery.
Figura 3: Función getFlag()
Leyendo el reto y el contrato podemos encontrar que se simula un entorno de lotería, dónde el usuario o player tiene que adquirir un boleto y puede pedir el reembolso de este si no quiere participar en el sorteo.
Figura 4: Función pagarBoleto()
Para poder pedir un reingreso o reembolso de lo que hemos depositado en el contrato, primero deberemos pagar y adquirir uno o varios boletos. Por esta razón, tenemos la función ‘pagarBoleto’. Se nos pide abonar al menos 1000000 wei. Con esta acción ya conseguiremos al menos un boleto y podremos pedir reembolso. La función ‘anularBoleto’ permite recuperar los fondos pagados en la previa compra de un boleto. Esta es la función ‘anularBoleto’ y su código.
Figura 5: Función anularBoleto()
Lo que se puede ver es que se comprueba que el usuario que pide anular el boleto tiene fondos pagados, es decir, ha comprado previamente un boleto. La segunda instrucción de la función realiza el pago al que solicita el reembolso. Si el solicitante de reembolso es un wallet se le enviará sus fondos, el segundo require se resolvería correctamente y se actualizarían los fondos del usuario en el contrato.
Justo aquí está el problema, se actualizan los fondos del usuario en última instancia. ¿Qué ocurre si cuando devuelven los fondos, no se da el ‘ok’ y se vuelve a solicitar de forma recurrente el reembolso? Aquí tenemos la vulnerabilidad de Re-Entrancy.
Si el usuario que pide el reembolso es un contrato, se puede definir cómo actúa el contrato en el momento que recibe fondos: funciones receive y fallback. A continuación, se muestra un ejemplo de contrato que se puede desplegar para interactuar con el contrato ReLottery.
Se puede ver la implementación de la función fallback. Esta función será invocada cuando el contrato ReLottery devuelva fondos a este contrato. El flujo del contrato attack es el siguiente:
En el despliegue se indica la dirección del contrato ReLottery y se le pasa al constructor del contrato attack. Ahora, se invoca la función attack() y se debe indicar en value la cantidad de wei que queremos que el contrato pague.
Se consigue obtener el balance total del contrato ReLottery más lo que el propio contrato pagó. Lo importante es que el balance total del contrato ReLottery queda a 0, por lo que ahora se puede solicitar la flag y validarla para sumar los puntos.
- El contrato attack a través de su función attack() compra un boleto y luego pide anular el boleto.
- El contrato ReLottery inicia la devolución de fondos al contrato attack.
- El contrato attack, a través de la función fallback, comprueba si el balance del contrato ReLottery es 0. Si no es 0, volvemos a solicitar devolución de fondos.
- Esto se realiza de forma iterativa hasta que el balance de ReLottery es 0. En este instante se empieza a cerrar las llamadas recursivas a fallback y dichas transacciones se finalizan correctamente.
Figura 7: Desplegando el SmartContract Attack en Ganache
En el despliegue se indica la dirección del contrato ReLottery y se le pasa al constructor del contrato attack. Ahora, se invoca la función attack() y se debe indicar en value la cantidad de wei que queremos que el contrato pague.
Figura 8: Contrato desplegado
Se consigue obtener el balance total del contrato ReLottery más lo que el propio contrato pagó. Lo importante es que el balance total del contrato ReLottery queda a 0, por lo que ahora se puede solicitar la flag y validarla para sumar los puntos.
Figura 9: Flag conseguida y validada
Nuevo reto: Pay Me!
En este nuevo reto de dificultar 1 sobre 5, tenemos que interactuar con el contrato con el objetivo de entender cómo funcionan los pagos en un SmartContract. El reto consistirá en conocer cómo funcionan las funciones payable y cómo interactuar con este tipo de escenarios.
Figura 10: Reto Pay_me #14
El reto es el nivel 14, esto quiere decir que es el reto número 15 que tenemos en Level_UP! Es un reto básico, para todos aquellos que comienzan con los SmartContracts y recuerda mucho al reto Questions o Interact, debido a la poca complejidad que se le presupone al reto. Animaos a jugar y aprender con Level_UP! disponible en su Github: https://github.com/Telefonica/level_up/.
Figura 11: Libro dedicado a "Bitcoin: La tecnología Blockchain y su investigación" de Yaiza Rubio y Félix Brezo |
Más artículos de Web3, Blockchain & SmartContracts
- Blockchain & SmartContracts: Una serie para aprender
- BlockChain & SmartContrats: Primer SmartContract con Solidity
- Blockchain & SmartContracts: Cómo probar y desplegar un SmartContract en Ethereum
- WWW, Web 1.0, Web 2.0, Web 3.0, Web3 y ¿Web 4.0?
- Metaverso, multiverso y las tierras digitales en que vivimos en forma de avatar
- Los Fan Tokens vs. las Criptomonedas y los NFTs: Level 101
- Tokenomics: Las criptomonedas y las "Proof-of-work": Level 101
- Los NFTs y el registro mundial de los dueños de activos digitales en el Metaverso
- BitCoin: Blockchain y su investigación
- BlockChain & SmartContrats: El Internet descentralizado y el almacenamiento off-chain en IPFS
- Reentrancy Attack: Cómo te roban criptomonedas por un bug en tu SmartContract
- BlockChain & SmartContract: Bugs que pueden dejar tu SmartContrat "fuera de juego"
- Blockchain & SmartContracts: Patrones y buenas prácticas de seguridad
- Blockchain & SmartContracts: Herramientas de Auditoría de Seguridad de SmartContracts
- BlockChain & SmartContracts: Ataque de phishing a tx.origin y robo de criptomonedas
- BlockChain & SmartContracts: Ataques de Ice Phishing
- Blockchain & SmartContracts: Herramientas de análisis dinámico
- ZIION: Una distribución Linux para auditar SmartContracts (& BlockChain)
- Dominios Web3 en Etherenum Name Service y la trazabilizad de las transacciones Blockchain
- BlockChain & SmartContracts: Actualizar SmartContracts como los grandes protocolos
- Jumping level up (from) web2 (to) web3: Vulnerabilities & SCAMs - SmartContracts
- 20 millones (Euros) en Tokens de Optimism perdidos por no saber cómo funcionan los Wallets Multifirma
- BlockChain & SmartContracts: Cómo crear una DApp de la Web3 con Python (y Flask)
- Pentesting SmartContracts: From Web2.0 to Web3
- Tokenomics 101: Una explicación con gráficos
- Read-Only Reentrancy Attack: $220k robados y otros +$100M en riesgo
- Como utilizar ChatGPT para encontrar bugs en SmartContracts
- BlockChain & SmartContracts: Nuevas áreas profesionales relacionadas con la Web3
- Las voces de Satoshi: Un canal para estar al día en Web3, Blockchain, Criptos & IA
- BlockChain & SmartContracts: Nuevas áreas profesionales relacionadas con la Web3
- Bit2Me Academy: Una plataforma online para aprender de Web3, BitCoin, Tokenomics o Ethereum con cursos gratuitos
- Level_Up!: Una plataforma para aprender a hacer pentesting en Web3 (SmartContracts & BlockChain ) a través de retos hacking
- Level_Up!: Web3 Security WarGames para los amantes del Challenge Based Learning
- Level_up!: WriteUp del Reto Questions para comenzar el pentesting en la Web3
- Level_Up! Deny_to_me Challenge activado en la plataforma Level_up! de retos hacking Web3
- Level_Up!: WriteUp del Ownership Challenge para hacer pentesting en Web3
- Nuevo reto Hacking Web3 de Level_UP! -> Forensic Ouch!
- Level_Up!: WriteUp del reto "Safeguarding" para hacer pentesting en Web3
- Reto Web3 en Level_Up! "Replay_me": La importancia de una correcta validación de firmas
- Level_Up! Configuración paso a paso de la plataforma de pentesting en Web3
- Level_Up! Consigue tus NFTs mientras cuando supera retos Web3
- Telefónica validará nodos de la cadena BlockChain de Celo
- Latch Web3: Un pestillo de seguridad para SmartContract
- Level_Up!: El WriteUp del reto "Origin" y un nuevo reto "Guess my number"
- CrazyToolBox: Una herramienta multifunción de utilidades Web3
- Level_Up!: El WriteUp del reto "ReLottery" y un nuevo reto de agosto llamado “Pay Me!”
Saludos,
Autor: Pablo González Pérez, 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