martes, noviembre 28, 2023

WriteUp del Reto Hacking Web3 "Snippet Delegated" & Nuevo Reto "Send to me" en Level_Up!

Nos encontramos a finales de noviembre y, como cada mes, traemos la solución a uno de los retos de Level_UP!, nuestra plataforma de aprendizaje basada en retos de Web3. Hoy le toca el turno al reto “Snippet Delegated”, un reto de dificultad 4 sobre 5 y que sumará 200 puntos a nuestro marcador global. ¡Vamos a por ello!

Figura 1: WriteUp del Reto Hacking Web3 "Snippet Delegated"
& Nuevo Reto "Send to me" en Level_Up!

En esta ocasión partimos de dos contratos diferentes: un primer contrato que tiene una serie de funciones, y un segundo contrato que importa estas funciones para su uso. 

Reto: Snippet Delegated

Tal y como indica el nombre del reto, se va a trabajar con una función llamada “delegatecall” que va a permitir que el contrato del reto pueda ejecutar el código del contrato de funciones con el almacenamiento del contrato del reto, el msg.sender y el msg.value.


Para conseguir el flag de este contrato, si observamos la función getFlag(), nos damos cuenta de que necesitamos ser el owner y, además, hay un valor llamado power que debe ser igual a 9. Debemos encontrar, en primer lugar, como hacernos owner del contrato y, a continuación, como llegar a obtener 9 en el valor de power.

Figura 3: Smart Contract del reto Snippet Delegated

Como se ha comentado con anterioridad, se va a trabajar con la función delegatecall(). Si nos fijamos, el contrato hace uso de está función en la función llamada execution_function().

Figura 4: Función execution_function en el contrato Snippet Delegated

Se puede revisar el contrato functions y ver que opciones tenemos disponibles. Rápidamente podemos encontrar varias funciones que van a jugar con los valores de power y stamina y recordamos que una condición para obtener el flag es que power tenga el valor de 9.

Figura 5: Funciones para interactuar con los valores power y stamina

Además, también encontramos una función llamada setOwner() que establece el propietario del contrato con el valor msg.sender. Con esto confirmamos que debemos interactuar con este contrato para conseguir los requisitos para conseguir la flag.

Comenzamos por llamar a la función setOwner(). Para ello debemos averiguar el selector de la función para pasarlo como el parámetro _data de la función execution_function(), que a su vez se pasará como parámetro de la función delegatecall().

Figura 6: Selector encoder con la herramienta CrazyToolBox

Para ello, hacemos uso de nuestra herramienta Open Source CrazyToolBox. En el apartado “Function selector encode”, indicamos el nombre de la función setOwner() y nos devuelve el selector 0x40caae06. Llamamos a execution_function:

Figura 7: Ejecución de la función getOwner() a través de delegatecall

Tras esto, podemos verificar que hemos conseguido ser el propietario del contrato llamando a contract.owner(). También podemos llamar a la función getFlag() y nos encontramos con que pasamos el primer requisito (ser el owner) pero no el segundo. Todavía nos queda conseguir poder para obtener el valor de la flag.

Figura 8: Valores de power y stamina

Tenemos que llegar al valor 9 en power. La función addPower() nos sumará 5 al valor de poder. Además, contamos con las funciones addStamina() y delStamina(), que sumarán o restarán 1 al valor de stamina. Por último, también tenemos la función addStaminaToPower() que suma el valor de la stamina al valor que tiene poder. 

En el caso del ejemplo, stamina ha comenzado en el valor 6. Para llegar al valor 9 en power, una posible opción sería:
  • addPower() -> Power pasa de valer 0 a valer 5
  • delStamina() -> Stamina pasa de valer 6 a valer 5
  • delStamina() -> Stamina pasa de valer 5 a valer 4
  • addStaminaToPower() -> Power pasa de valer 5 a valer 9 (le suma el valor 4 de stamina)
Para hacer las llamadas a través de delegatecall hay que volver a calcular el selector de las funciones:
  • addPower() -> 0x51f2e64a
  • addStamina() -> 0x1659544c
  • delStamina() -> 0x9499443a
  • addStaminaToPower() -> 0xcf5e9734
Por último, debemos traernos el valor de power haciendo una llamada a getPower(), con el selector 0x49a4e50d.

Figura 9: ¡Flag conseguida!

Ahora sí, podemos hacer la llamada al contrato para conseguir la flag y pasar a validarla en el contrato base y la función validateFlag() ya conocida de otros retos. 

Figura 10: Superar el reto “Snippet Delegated” sumará 200 puntos a tu marcador

Ya podemos visitar el apartado de player para ver el reto completado y los 200 puntos obtenidos.

Nuevo reto: Send to me

Como cada mes, la publicación de un nuevo WriteUp! viene acompañado de un nuevo reto. En esta ocasión, parece un contrato sencillo a simple vista. Únicamente hay que encontrar la manera de mandar fondos a un contrato que no está preparado para la recepción de fondo. ¿Encontrarás la manera de hacerte con la flag?

Figura 11: Nuevo reto “Send to me"

Como siempre, esperamos que sigas disfrutando y aprendiendo con la plataforma Level_UP! y nos vemos el próximo mes con un nuevo reto, que pronto tendréis novedades para jugar en una testnet

Seguiremos resolviendo retos y creando nuevos retos para el aprendizaje en seguridad en Web3 y recuerda que si quieres aprender de estas tecnologías, tienes Bit2Me Academy, que es una plataforma online para aprender de Web3, BitCoin, Tokenomics o Ethereum con cursos gratuitos además del libro dedicado a "Bitcoin: La tecnología Blockchain y su investigación" de Yaiza Rubio y Félix Brezo que seguro que te ayudan a ponerte las pilas.

Más artículos de Web3, Blockchain & SmartContracts
Happy Hacking!

No hay comentarios:

Publicar un comentario