Mostrando entradas con la etiqueta Smart Contracts. Mostrar todas las entradas
Mostrando entradas con la etiqueta Smart Contracts. Mostrar todas las entradas

martes, julio 09, 2024

LAOS Network: Nueva era en interoperabilidad y escalabilidad para Blockchain

LAOS Network, también conocida como la "Blockchain Universal", es una nueva red de Capa 1 que se presenta como una solución innovadora para algunos de los problemas más comunes de la Blockchain. Se trata de la primera Blockchain Layer 1 capaz de conectarse con Ethereum, Polygon, las Capas 2 de Ethereum y cualquier cadena de bloques compatible con la Ethereum Virtual Machine sin necesidad de bridges.


Su objetivo es crear una red interoperable, escalable y fácil de usar que permita la creación e intercambio de activos de manera fluida entre diferentes Blockchains. LAOS tiene potencial para convertirse en el protocolo utilizado por las principales Blockchain para descargar más del 20% de sus transacciones.

Figura 2: LAOS WhitePaper

Los tokens que se crean sobre LAOS mejoran las soluciones Layer 2 que hay en el mercado, ya que permanecen en su cadena original, por lo que no requiere que los usuarios envuelvan sus tokens o tengan que depender de bridges, que suelen ser inseguros.

Características principales de LAOS Network
  • Interoperabilidad: LAOS Network se conecta de forma nativa con Ethereum, Polygon, sus capas 2 y cualquier otra cadena compatible con EVM, sin necesidad de puentes. Esto permite la creación e intercambio de activos entre diferentes blockchains sin problemas.
  • Escalabilidad: LAOS Network está diseñada para manejar un alto volumen de transacciones, con una capacidad teórica de hasta 1 millón de transacciones por segundo (TPS). Esto la convierte en una opción atractiva para aplicaciones que requieren un procesamiento rápido y tarifas de gas bajas.
  • Descentralización: LAOS Network funciona con un sistema de consenso de Prueba de Participación (PoS), lo que garantiza que la red esté distribuida y sea resistente a la manipulación.
  • Facilidad de uso: LAOS Network está diseñada para ser fácil de usar tanto para desarrolladores como para usuarios. Ofrece una experiencia de usuario fluida y herramientas que simplifican el proceso de creación e intercambio de activos.
Casos de uso de LAOS Network
  • Creación de activos: LAOS Network permite la creación de millones de activos en las blockchains más consolidadas, como Ethereum y Polygon. Estos activos pueden representar una amplia gama de elementos, desde tokens no fungibles (NFTs) hasta tokens de utilidad.
  • Intercambio de activos: Los activos creados en LAOS Network se pueden intercambiar fácilmente entre diferentes blockchains, gracias a la interoperabilidad nativa de la red.
  • Aplicaciones descentralizadas (DApps): LAOS Network puede ser utilizada para desarrollar DApps escalables y eficientes que aprovechen las ventajas de la interoperabilidad y la escalabilidad de la red.
¿Qué es el token LAOS?

LAOS es un Utility Token y tiene tres casos de uso principales. El primero es la creación de millones de activos en las Blockchains más consolidadas, permitiendo también su evolución de forma descentralizada.


El segundo es el staking con sus tokens, que permite a los usuarios obtener recompensas al tiempo que contribuyen a la seguridad y el funcionamiento de la red. Finalmente, el token LAOS sirve como fuerza de voto en la gobernanza de la plataforma y permite a los holders participar en la toma de decisiones sobre el futuro de la plataforma.

¿Por qué participar en el launchpad de LAOS Network?

LAOS Network se encuentra en una etapa temprana de desarrollo, lo que significa que hay una gran oportunidad para los usuarios de participar en el proyecto y obtener mayores recompensas por su participación temprana.


La IEO de tokens LAOS ofrece la posibilidad de adquirir tokens a un precio con descuento antes de que se lancen oficialmente a la venta.

¿Cómo puedes participar en el launchpad de LAOS Network en Bit2Me?

Puedes participar desde la sección Launchpad de la app deBit2Me o desde nuestro sitio web, seleccionando LAOS en la sección Launchpad. Para acceder a la reserva, tienes que depositar la cantidad de euros que quieres reservar en tu Wallet.


Si en algún momento antes de que se ejecuten las reservas quieres cambiar o eliminar tu reserva, podrás hacerlo sin ningún problema. Si una vez finalizado el proceso de reserva te quedas fuera, recuperarás los fondos automáticamente. Si quieres saber más sobre cómo participar en el nuevo proyecto de Bit2Me Launchpad, encontrarás toda la información en su blog y en sus redes sociales.

lunes, julio 18, 2022

Blockchain & SmartContracts: Actualizar SmartContracts con Patrones Proxy

Siempre que hablamos de SmartContracts decimos que es muy importante tener presente que una vez subas tu código a la Blockchain, éste se quedará así para siempre y si tiene un bug o vulnerabilidad pues lo tendrá permanentemente. Pero y si tuviéramos algún tipo de patrón mediante el cual pudiéramos actualizar la lógica de nuestro contrato, entonces no tendríamos que pedir a nuestros usuarios que cambien el contrato que usaban, simplemente podemos actualizarlo y ya. 

Figura 1: Blockchain & SmartContracts.
Actualizar SmartContracts con Patrones Proxy

Si bien existen diferentes formas en las que podemos “actualizar” la lógica de un SmartContract como por ejemplo usando un modelo de “módulos arbitrarios” aprovechándose de que estos contratos pueden ejecutar código de manera arbitraría. Pero el patrón más usado es el patrón “Proxy”.

Figura 2: Idea general del patrón Proxy

Pero hoy nos vamos a centrar en los Proxies, que son un patrón que nos permite actualizar completamente la lógica de nuestros contratos usando solamente dos contratos diferentes, cabe destacar que estos dos contratos son inmutables, pero combinándolos podremos actualizar su funcionamiento. La idea básica de su funcionamiento es la siguiente:

Figura 3: Despliegue de SmartContract Proxy

Tenemos dos contratos diferentes, el primero el Proxy o Storage que se encargará de guardar en la Blockchain todos los datos del SmartContract. Este contrato siempre será el mismo y nunca cambiará, esto es así dado que mover los datos de un contrato a otro es muy costoso. El segundo el contrato de la lógica, como su nombre nos indica este se encargará de manejar la lógica por la que se regirá el SmartContract, este irá cambiando con el tiempo oséa que crearemos nuevos contratos y cambiaremos éste por los nuevos.

Figura 4: Actualizando contrato Proxy

Ahora, en cada interacción que el usuario haga la hará con el contrato Storage y esté a su vez le pasará la llamada al contrato que guarda la lógica y éste modificará la memoria del contrato Storage y no la suya. Ahora imaginemos que queremos actualizar el contrato que utiliza el usuario, pues simplemente subimos un nuevo contrato a la Blockchain que tenga esta lógica nueva y cambiamos en el contrato storage el puntero que redirigía al contrato anterior por el nuevo.

Funcionamiento del Patrón Proxy

Acabamos de ver la idea general y básica sobre cómo funcionan los sistemas proxies en los contratos basados en la EVM, veamos ahora cómo convertir esta idea en algo real. En la EVM (Ethereum Virtual Machine) existe una instrucción llamada delegatecall que funciona de la siguiente manera.
“””
delegatecall(gas, _impl, ptr, calldatasize, 0, 0)
“””
Cabe notar que en Ethereum las instrucciones de código ensamblador se usan como si fueran funciones y no como “ add bx, 5; “ usado por la mayoría de lenguajes de ensamblador. Esta instrucción nos permite llamar a un contrato externo, igual que la instrucción “ call “. Bien pero, ¿qué diferencia hay entre estas instrucciones? Pues que delegatecall no solamente llama a la función de un contrato externo sino que además pasa todo el contenido guardado en msg.data (parámetros de llamada) y msg.value (ETH enviado).

Además teniendo la peculiaridad de que todas las modificaciones que haga el contrato al que se le delega la llamada no se reflejará en el propio contrato sino que lo hará en aquel que haya ejecutado delegatecall. La instrucción delegatecall recibe cinco parámetros:
  • gas: El gas del que va a disponer el contrato al que se le delega la llamada. No siempre este es el máximo posible porque a veces antes de delegar la llamada primero evaluamos unas ciertas condiciones que gastan el gas inicial, por ello es importante calcularlo adecuadamente.
  • _impl: El address del contrato hacia el cual delegamos la llamada. En el patrón proxy se le suele llamar implementación.
  • prt: Los datos del msg.data que se pasan al nuevo contrato, puede bastar con pasar msg.data en vez de ptr, pero puede que primero necesitemos procesar los datos de entrada. El msg.data acabará convirtiendose en los parámetros que le lleguen al contrato final.
  • calldatasize: El valor en bytes de la longitud de memoria que ocupa el msg.data.
  • últimos 2 parámetros: Estos dos últimos parámetros no son importantes, solo sirven para que el valor devuelto por el contrato al que se delegue sea acotado entre el rango provisto en esos dos valores.
Cabe destacar que si usamos la función addr.delegatecall(...) en Solidity, ésta sólo nos devolverá un booleano que nos dirá si la función ha fallado o no. Sin embargo si usamos la instrucción de ensamblador podremos acceder a los datos que devuelva el contrato al que se delegue usando un pequeño truco que veremos más adelante.

Implementación en Solidity

Toda esta teoría está muy bien pero veamos cómo podemos implementar todo esto en Solidity. Para ello vamos ha hacer uso de él “inline-assembly” que nos ofrece Solidity para así poder escribir ensamblador dentro del propio código de Solidity.

Figura 5: Función fallback en un Proxy

Antes de explicar que ocurre dentro de la función veamos el contexto de porque esa función. Si nos fijamos bien veremos que no estamos definiendo una función normal, sino una “fallback” esta función tiene un rol muy importante dentro de los SmartContracts basados en EVM, ésta se ejecutará siempre que se llame a un contrato y la función a la que se está llamando no exista en el propio contrato. Si queréis entender en profundidad cómo funciona este sistema de llamadas os recomiendo leer este artículo sobre los selectores de las funciones en la EVM.

Explicacion del codigo:

Lo primero que hacemos es reservar en memoria un espacio en el que poder guardar los datos que se envían junto con la función como parámetros, etcétera. Y ahora os preguntaréis ¿Y cómo accedemos a ellos si no están declarados en la función? Pues en la EVM todos los datos que se envían a una función están guardados dentro de una variable global llamada calldata. Después copiamos al espacio reservado en memoria los datos guardados en calldata. Esto es necesario ya que calldata es un tipo de memoria que no se puede ni modificar ni pasar a otras funciones como parámetros.

Luego delegamos la llamada a un address llamado _impl y le pasamos el calldata que escribimos en memoria, delegatecall nos devolverá un valor boolean que debemos guardar. Y también guardamos en memoria la longitud de la respuesta del delegatecall. Una vez hecho eso, copiamos el espacio reservado en 0 los valores devueltos por 2 y evaluamos si la llamada delegada fue exitosa o no. En caso de que no devolvemos el error que nos tiró el contrato de lógica, sino devolvemos los valores.

Problemas que pueden surgir

Una cosa muy importante a tener en cuenta es cómo se guarda el nuevo almacenamiento que creamos al añadir lógica a un contrato. Veamos primero cómo transforma Solidity su código a instrucciones.
“””
contract storage{
	uint256 age = 12;// transforms to sstore(0x00,0xC)
	uint256 other = 1; // transforms to sstore (0x40, 0x1)

	function modify() external{
		age = 13; // transforms to sstore(0x00,0xD)
		other = 2; // transforms to sstore(0x40, 0x2)
              }
}
“””
A la hora de actualizar este contrato tenemos que tener mucho cuidado de no hacer override de estas variables o podríamos tener un problema bastante serio, miremos el siguiente ejemplo para ver a lo que me refiero.
“””
contract storageV2{
uint256 score = 100; // transforms to sstore(0x00,0x64)
	uint256 age; // setted in V1 as 0x00 but not is 0x40
	uint256 other; // we setted in V1 0x40 but now is in position 0x60

	function modify() external{
		age = 13; // now it stores age in other slot
		other = 2; // now it stores other in a new slot
		score = 75; // stores it in the age slot
              }
}
“””
Este contrato que trata de actualizar la lógica del contrato anterior está mal, porque lleva a una colisión de almacenamiento. Esto es que cuando tratemos de leer lo que había en age v1 estaremos leyendo lo que había en otro v1 y si leemos other obtendremos 0 dado que no hay datos guardados en el slot nuevo. De manera visual la colisión sería la siguiente:

Figura 6: Storage Collision

Y los datos los podemos seguir leyendo porque aunque estén cambiados a fin de cuentas un uint256 es 32bytes con lo que se lee de la misma manera, pero si estuviésemos leyendo un mapping o un string los datos que leeremos no tendrían siquiera sentido alguno. También existen otros tipos de problemas como el de la transparencia para el usuario, control de acceso y actualización. Estos se resuelven de manera un poco más compleja.

¿Descentralización y transparencia?

Es verdad que es muy útil el poder actualizar la lógica de tus contratos por si acaso algún día se encuentra una vulnerabilidad en tu código o simplemente necesitas extender su funcionalidad, pero esto rompe un poco con los principios de inmutabilidad y transparencia. ¿Pero es esto una carencia? ¿De verdad rompe con la descentralización? Os voy adelantando que no, existen mecanismos para mantener descentralizada la propiedad del contrato y sus actualizaciones, pero esto no lo veremos hoy.


En el siguiente artículo os mostraré algunos problemas más comunes a la hora de usar Proxies en SmartContracts y como está el “state of the art” en lo relacionado a proxies en desarrollo Blockchain y como podéis implementarlo vosotros en vuestros proyectos. Nos vemos en el próximo artículo. Más artículos sobre este mundo Web3:
Saludos,

AutorChema Garabito. Desarrollador Full-Stack. Ideas Locas Telefónica CDO.


viernes, mayo 27, 2022

BlockChain & SmartContracts: Ataque de phishing a tx.origin y robo de criptomonedas

Ya hemos hablado en el blog de algunas vulnerabilidades que afectan a los SmartContracts. Es un tema de actualidad y es un tema importante que debemos manejar en el mundo Web3. La seguridad es un proceso transversal a cualquier paradigma de la llamada transformación digital y el mundo Web3 no escapa de ello. Que una vulnerabilidad en un contrato afecta a miles de usuarios y pueda secuestrar o robar sus fondos es algo crítico.  Desde el mundo IT, el de toda la vida, vemos esto como un riesgo que debe ser gestionado. Por esta razón, la base de todo modelo de defensa es el conocimiento y la concienciación. 

Figura 1: BlockChain & SmartContracts: Ataque de phishing
a tx.origin y robo de criptomonedas

En este caso, no solo los desarrolladores de SmartContracts deben disponer de conocimientos para codificar de forma segura, sino que también deben ser los usuarios de los contratos los que entiendan los riesgos básicos. El artículo de hoy va, precisamente, de esto. ¿Cómo puede afectar el pshising a un SmartContract? Expondré algún ejemplo que debemos entender y valorar antes de ponernos a interactuar con este entorno. Ya hemos hablado en el blog sobre vulnerabilidades como la de Reentrancy que puede afectar a la pérdida o robo de fondos de un contrato y a un escenario de bloqueo de criptomonedas de un contrato o denegación de servicio de un contrato. Hoy vamos a explicar un caso de phishing basado en una mala práctica del uso del elemento tx.origin.

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 el riesgo de usar tx.origin para validar la propiedad de un contrato. ¿Qué es tx.origin? En Solidity se utiliza como variable global la cual devuelve la dirección pública de una cuenta. En este caso la dirección que envió la transacción. Debemos tener claro que si utilizamos tx.origin para validar o chequear a los usuarios, dichos contratos serán vulnerables a ataques de phishing. Hay que saber que tx.origin es una variable global en Solidity que devuelve la dirección de la cuenta que envió la transacción. Los contratos que utilizan tx.origin para autorizar a los usuarios son vulnerables a los ataques de phishing.

Escenario y ejemplo de vulnerabilidad

Para entender el concepto, vamos a suponer el siguiente escenario:
  • Contrato A, el cual es vulnerable.
  • Contrato B, el cual es un contrato preparado por un atacante.
  • Usuario A, el cual será una víctima.
  • Usuario B, el atacante.
El contrato A tiene una función para transferir fondos. Recordemos que el contrato A es el contrato vulnerable. La función permite mover ETH de un contrato a una dirección. El requisito para llevar a cabo esta operación de mover fondos es que tx.origin sea igual al owner del contrato.

¿Qué diferencia hay entre tx.origin y msg.sender? tx.origin es la variable que contiene el emisor de la transacción, es decir, la dirección que ha originado todas las posibles llamadas disparadas a través de los contratos (teniendo en cuenta que un contrato puede llamar a otro, y ese otro a otro…). La variable msg.sender almacena la dirección origen de la llamada actual, por lo que la diferencia es clara, la primera almacena el origen de todo y la segunda el origen de la llamada que se está ejecutando.

Figura 3: Escenario del ataque de phishing a tx.origen

Ahora que tenemos claro que es el tx.origin, supongamos que el usuario B (atacante) envía un phishing al usuario A. El usuario A confía en el phishing y ejecuta una llamada contra el contrato B a través del método ‘attack’. El método ‘attack’ va a provocar que se haga una llamada contra el contrato A en el método ‘Transfer’. El usuario A es el que invoca contratoB.attack por lo que llamada de contratoB.attack a contratoA.Transfer seguirá teniendo como tx.origin al usuario A.

Figura 4: Envio del phishing al usuario A

Si analizamos el requisito del método contratoA.Transfer es que tx.origin sea igual a owner del contrato, por lo que, en este caso, quedará validado con este engaño al usuario A. En la siguiente imagen, se va a mostrar el flujo completo y cómo se activan la pila de llamadas. De todos modos, vamos a hacer un pequeño resumen de la ejecución:
  • El phishing enviado del usuario B al usuario A hace que éste ejecute la primera acción: El usuario A invoca a contratoB.attack. En este punto msg.sender y tx.origin tiene como valor la dirección del usuario A.
  • El contratoB.attack es ejecutado, por lo que éste ejecuta una llamada al contratoA al método ‘Transfer’. En este caso, cuando se ejecuta contratoA.Transfer, msg.sender vale la dirección del contratoB, pero tx.origin sigue valiendo la dirección del usuario A. Aquí está la vulnerabilidad.
Figura 5: Resumen completo de llamadas con el robo de fondos

Al final, la transferencia se valida, ya que el requisito es que tx.origin sea igual al owner del contrato A. En el engaño, en el contrato B, seguramente, se configura para que los valores de transferencia sean para un wallet del usuario B y se produce el robo de fondos.

¿Cómo podemos evitar esto?

La primera práctica es no usar tx.origin, ya que no nos permite verificar realmente quién está detrás de la llamada que invoca. Es mejor utilizar msg.sender para verificar, aunque existen casos dónde podemos tener problemas. Quizá la mejor solución es la firma de mensajes para verificar, antes de realizar la transacción que somos conscientes que vamos a realizar una transacción. Es importante estudiar los patrones de codificación segura en Solidity, ya que podremos evitar cometer errores graves. Además, realizar auditorías de seguridad y utilizar herramientas DAST y SAST en los entornos de desarrollo parecen algo fundamental. 
 

En el siguiente enlace se puede ver un listado de patrones que proporcionan utilidad en cuanto a la mejora de la seguridad en el desarrollo de SmartContracts, y en el vídeo anterior una charla mía sobre vulnerabilidades en SmartContracts. El objetivo de estos artículos es concienciar a las personas y que aprendan a evitar estas vulnerabilidades. Seguiremos mostrando más vulnerabilidades en el mundo de los SmartContracts y seguiremos aprendiendo más sobre este interesante mundo de la Web3. 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

viernes, mayo 13, 2022

Blockchain & SmartContracts: Herramientas Visuales de Auditoría de Seguridad de SmartContracts (y BlockChains)

A la hora de auditar la seguridad de SmartContracts y su BlockChains en búsqueda de vulnerabilidades o debilidades, podemos utilizar distintos tipos de herramientas con entornos gráficos más o menos visuales, y tanto de  de análisis de código estático o dinámico, además de clasificación. En este artículo vamos a ver algunas de ellas para que puedas probarlas y comenzar a trabajar en la auditoría de seguridad de estas tecnologías.

Figura 1: Blockchain & SmartContracts: Herramientas Visuales
de Auditoría de Seguridad de SmartContracts (y BlockChains)

Vamos a comenzar con las herramientas visuales, que son las que nos ayudan a entender de una manera gráfica el flujo de estado y las llamadas que un contrato puede llegar a tener. Esto es muy útil sobre todo para ver qué estados pueden ser afectados dependiendo de la llamada que se lleve a cabo en un instante determinado.

Sūrya

Sürya es una herramienta para inspeccionar de manera visual contratos escritos en Solidity. Para instalarla simplemente tenemos que tener un gestor de paquetes como Npm o Yarn y escribir en una consola:

“””
npm install -g surya
“””

Esta herramienta utilizará graphviz para dibujar los resultados del análisis, luego debemos tenerla instalada también para poder utilizar el comando dot. Con esta herramienta podremos tener.
  • Gráficos de control de flujo: esta parte de la herramienta nos permite visualizar con un grafo, que conexión tienen las funciones en el contrato, el “import flow” y si el contrato llama a otro externo. Se puede observar la imagen que se genera si lanzamos el siguiente comando en este repositorio.
“””
npx surya graph contracts/**/*.sol | dot -Tpng > MyContract.png
“””


Figura 2: Ejemplo de Flujo de un contrato usando Surya.

  • Rastreo de llamadas de una función: nos muestra todas las llamadas a funciones que pueden ocurrir y si el estado que se accede en estas llamadas es accesible para todos. Si lanzamos este comando en el anterior reporte, obtendremos.
“””
npx surya ftrace HackathonWeb3::claimToken all contracts/NFT.sol -i
“””
Figura 3: Ejemplo de como Surya clasifica el acceso a funciones.

  • Control de herencia: nos muestra de manera visual en un grafo como es el sistema de herencias de un contrato o de varios. Basta con usar el siguiente comando.
“””
npx surya inheritance -i contracts/NFT.sol | dot -Tpng > MyContract.png
“””
Figura 4: Flujo de herencia en un contrato NFT.

Además de estos ejemplos, tenéis otros comandos que generan otros gráficos de análisis que pueden ayudar a detectar problemas en el SmartContract. Tenéis todos los comandos de esta herramienta en su repositorio.

EVMLAB

EVMLAB es un onjunto de herramientas para interactuar con la máquina virtual de Ethereum. Esto significa que estas herramientas son compatibles con cualquier Blockchain que use la EVM. Algunas de sus utilidades son:
  • Opviewer: un Trace-Viewer que nos muestra información sobre la cadena de Blockchain y el rastro de una transacción
Figura 5: Consola de EVMLab para acceder a datos de Blockchains basadas en EVM.
  • Reproducer: una herramienta que puede reproducir de manera exacta una transacción en la blockchain de manera local en una Blockchain privada. Ejemplo reproducer.py
PIET

Piet es una aplicación web para crear y editar arquitecturas de SmartContracts. Genera una representación gráfica sobre arquitecturas de contratos, inspector para observar outputs para cada input dado, leer estado del contrato en la Blockchain, propiedades, métodos, generar documentación automática, historial de transacciones del contrato… 

Figura 6: Dashboard de PIET para generar y visualizar arquitecturas de SmartContracts

Estas son algunas de las herramientas más populares para visualizar todos los detalles más importantes del diseño general y particular de un SmartContracts y su BlockChain y así tener más clara su arquitectura, accesos, flujos de llamadas, clases de herencia, etcétera. Información crítica para mejorar su seguridad, que puedes complementar con lecturas como la de este libro donde vas a aprender qué rastros buscan los investigadores en tus actividades.

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

Vamos a dejar las herramientas de análisis estático y dinámico para los artículos siguiente, pero os puedo adelantar que algunas de ellas parece que hacen magia. Más artículos sobre este mundo Web3:
Saludos,

jueves, mayo 12, 2022

Blockchain & SmartContracts: Patrones y buenas prácticas de seguridad

Alrededor de 34 millones de USD, es decir, un total de 11.539ETH en el momento, han sido bloqueados en el SmartContrat de AkuDreams para siempre, y muchos de los usuarios del contrato no podrán recuperar su dinero nunca. A esto hay que sumar que durante lo que llevamos de 2022 se estima que 1.300 millones de USD han sido robados en diferentes ataques a SmartContracts, muchos de estos se produjeron por fallos de seguridad en los propios contratos. 

Figura 1: Blockchain & SmartContracts.
Patrones y buenas prácticas de seguridad

Es por ello que últimamente se escucha mucho por las comunidades de web3 que hay que ocuparse en serio de “auditar contratos” y no es que un equipo legal se encargue de mirar tu contrato, sino que expertos en seguridad de SmartContracts se aseguren de que tu contrato no tenga ningún problema, como los que hemos hablado de D.o.S. a SmartContracts o el Ataque de Rentrancy, por citar solo un par de ellos.

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

En el artículo de hoy os voy a enseñar algunas de las metodologías y herramientas que se suelen utilizar a la hora de auditar contratos, porque los códigos que se programen en ellos pueden hacer que pierdas tus Criptomonedas o Criptotokens.

Patrones y buenas prácticas

Probablemente la parte más importante de securizar un contrato está en la creación. En general a la hora de crear SmartContracts se suelen seguir un mismo conjunto de prácticas y patrones.
  • Caza los bugs antes: es mejor que encuentres los bugs en la fase de creación porque si un contrato es subido a la Blockchain sin usar un Proxy este será inmutable para siempre y en lo que se refiere a SmartContracts los bugs y vulnerabilidades siempre suelen ir parejos a la pérdida de fondos en el contrato.
Figura 3: Tests unitarios de un contrato NFT)

  • Keep it Simple: Mantener los contratos lo más simple posible, cuanto más complejo sea un contrato más fácil será que este tenga algún tipo de error.
  • Factoriza: Solo implementa en el contrato aquello que es crítico que sea descentralizado, si algo no es necesario que sea descentralizado hazlo off-chain para que puedas modificarlo en el futuro si algo malo pasase.
  • Tecnología Probada: Usa código y herramientas ya existentes. La mayoría de ellas habrán sido testeadas a conciencia por muchos desarrolladores experimentados. En nuestro caso sirve como ejemplo las librerías de Openzeppelin que nos aportan muchas funcionalidades con la seguridad que esos contratos han sido auditados por expertos.
Figura 4: Wizard de OpenZeppelin
  • Modularizar el código: Este patrón va muy en la línea del anterior, si puedes dividir un contrato en varios mejor. Así mantendrás la lógica de ambos sencilla y si algún día hay un problema lo más seguro es que solo lo tenga uno de ellos y solventarlo sea más sencillo.
  • Aprende bien de Blockchain: Blockchain es un mundo en sí y mucha de la experiencia en desarrollo fuera de Web3 será útil para crear contratos, pero debes tener en cuenta que  Blockchain y los SmartContracts tienen muchas “propiedades nuevas”.
    • Las llamadas a contratos externos son una herramienta muy útil pero se debe tener cuidado con ella porque puede dar lugar a ejecución remota de código, cambios en el flujo de ejecución como el del ataque de Reentrancy.
    • No existen datos privados en Blockchain, por mucho que declares como privada una variable en tu contrato está siempre estará accesible puesto que todo lo que está en la blockchain es público, lo único a nivel de código otros smart contracts no podrán acceder a esa información directamente.
    • Ten en cuenta el Gas, ya que en la mayoría de Blockchains existe un coste asociado a la ejecución de una instrucción y además existe un número máximos de instrucciones ejecutables en una llamada, lo que significa que puede que una función no sea ejecutable nunca por lo larga que sea.
  • Prepárate para fallar: si tu contrato tiene una cantidad considerable de lógica entonces lo más probable es que tenga algún error y por lo tanto tienes que estar preparado para cuando estos aparezcan en producción. Lo habitual es:
    • Tener un “Circuit Breaker”, que significa que la lógica de tu contrato sea pausable, por ejemplo podríamos heredar el contrato “Pausable” que nos permite justo eso.
    • No pongas todo el dinero en riesgo, mantén muy limitadas las formas de extraer fondos de contratos.
    • Ten una estrategia para solucionar los errores que puedan surgir, como por ejemplo delegar la lógica a un contrato externo y poder cambiar el puntero hacia ese contrato hacia uno nuevo sin los errores.
Figura 5: Contrato NFT actualizable mediante un proxy
  • Favorece el sistema de “Pull over Push”, a la hora de gestionar la lógica en un contrato es mejor permitir que un usuario solo pueda modificar el estado que le afecta a él. Vemos un ejemplo:
Figura 6: Contrato vulnerable a D.oS.

En este caso usuarios diferentes pueden interferir con los fondos de los demás dado que cuando te conviertes en el pujador mayor te encargas también de devolver el dinero, en este caso se podría producir una denegación de servicio.

Figura 7: Contrato que implementa sistema Pull over Push

En este caso evitamos la denegación de servicio al adoptar un “Pull over Push”, de esta manera logramos que un usuario solo pueda interactuar con el estado que le concierne y así nos evitamos muchos problemas como el del D.o.S.

Conocer las vulnerabilidades

Los anteriores patrones y buenas prácticas nos ayudan a evitar bugs y fallos en el futuro, pero también es necesario conocer las vulnerabilidades más comunes y cómo se solucionan para evitar que nuestro contrato las tenga. En este artículo no vamos a tratarlas en profundidad porque poco a poco iremos presentandolas en detalle en otros artículos más adelante como el Ataque de Reentrancy que publicó Pablo Gonzalez. Sin embargo si queréis echar un vistazo por vuestra cuenta en esta web podréis tener una primera toma de contacto con algunas de las vulnerabilidades más conocidas.

En la próxima entrada, vamos a ver algunas herramientas visuales de análisis, ya sea estático o dinámico y de clasificación para ayudarte en en el proceso de tener unos SmartContracts más seguros. Nos vemos en la siguiente parte ;). Más artículos sobre este mundo Web3:
Saludos,

jueves, abril 28, 2022

SmartContracts: Bugs que pueden dejar tu contrato ‘fuera de juego’

Hemos hablado sobre el Ataque de Reentrancy y cómo evitarlo en un SmartContract. Vemos que el crecimiento de los SmartContract es rápido y nos abre un mundo nuevo de posibilidades a través de la Web3. Hoy vamos a trabajar otras vulnerabilidades que pueden afectar a las posibilidades de un SmartContract. Las denegaciones de servicio son la pérdida de disponibilidad de un activo y es una vulnerabilidad que afecta a una de las dimensiones de la ciberseguridad.

Figura 1: SmartContracts: Bugs que pueden dejar tu contrato ‘fuera de juego’

Por esta razón, un DoS en un contrato puede suponer la pérdida de disponibilidad de dicho contrato y los usuarios que tienen fondos o que tienen que operar con dicho contrato pueden verse afectados no pudiendo realizar operaciones. Esto es un problema que como se irá viendo en el artículo, puede llevar a la pérdida de las operaciones y el bloqueo de fondos en un contrato.

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

En el ámbito de la denegación de servicios de un contrato existen muchas formas, por lo que desde el punto de vista de desarrollo se deben tener en cuenta muchos aspectos y realizar muchas pruebas antes del despliegue para encontrar fallos que provoquen el bloqueo de operación en el contrato.

Ejemplificando el caso de DoS

Para entender mejor todo esto, vamos a ejemplificar el caso de la denegación de servicio (o un caso) a través de un supuesto. Para ello, vamos a proponer el siguiente escenario:
  • Pensemos que tenemos un sistema de pujas a través de un SmartContract.
  • El SmartContract tiene una función que se encarga de recibir una puja de un contrato / usuario. Si este contrato / usuario pujan con más cantidad de fondos, lo que hace el contrato es devolver los fondos metidos por el anterior “pujista” y colocan como virtual ganador de la puja al nuevo “pujista”.
Para entender esto último podríamos comentarlo de la siguiente manera:
  • Recibo puja
  • Compruebo si la puja es mayor que la que tengo almacenada como ganadora
  • Si la puja es mayor, devuelvo los fondos del anterior ‘pujista’ y guardo los nuevos fondos y pongo el nuevo virtual ganador de la puja
¿Dónde puede estar el problema?

La función interactúa en una misma llamada con dos contratos. El contrato al que se le devuelven los fondos, en caso de que haya una puja mayor, y el contrato que está pujando. Si el contrato al que devolvemos los fondos no acepta pagos tenemos un problema, ¿Por qué?

Figura 3: Esquema del ataque

Si el contrato al que se le devuelven los fondos, rechaza esto, la función (dependiendo de cómo se implemente) puede no poder devolver los fondos. Esto produce que el nuevo pujista no pueda ser ‘coronado’ virtual ganador, provocando la denegación de servicio, ya que el SmartContract que gestiona la puja no podrá nunca devolver los fondos y no podrá colocar un nuevo ganador.


En el vídeo anterior de la charla de Open Expo CyberSecurity Talent Day 2022 sobre Seguridad en SmartContrats se puede ver un ejemplo concreto de este caso expuesto con Remix IDE y Ganache como BlockChain local. Además, en el video se pueden ver conceptos básicos por si quieres comenzar a aprender sobre este y ver cómo se puede montar un laboratorio para hacer pruebas con tus SmartContracts.

Mitigando o evitando el DoS

¿Cómo podemos evitar que este tipo de fallo concreto no lo tengamos? Vamos a proponer algunas ideas, aunque no son las únicas. A continuación, enumeramos algunas opciones:

  • Lo primero que se nos puede ocurrir es hacer que el usuario sea el que solicite la devolución al ver que ya no es ganador de la puja, por lo que el contrato gestor de la puja debe tener un registro de qué fondos ha aportado cada ‘pujista’ y una función dónde el usuario solicite la devolución de sus fondos.
  • Es importante el separar la lógica de interacción con varios usuarios en una función (es justo lo que ocurría en este caso). Ya que, como se ha visto, un usuario puede afectar al resto por una decisión suya.
Una recomendación que os dejamos es que si te interesa este mundo pruebes los entornos de prueba con vulnerabilidades como, por ejemplo, https://www.damnvulnerabledefi.xyz/. En otros artículos ya trataremos más a fondo sobre estos entornos, que nos ayudan a aprender y conocer más en detalle las vulnerabilidades a las que nos enfrentamos en el mundo SmartContracts.

Figura 5: Retos para probar vulnerabilidades.

El objetivo es concienciar a las personas y que aprendan a evitar estas vulnerabilidades. Seguiremos mostrando más vulnerabilidades en el mundo de los SmartContracts y seguiremos aprendiendo más sobre este interesante mundo de la Web3. 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

Entrada destacada

+300 referencias a papers, posts y talks de Hacking & Security con Inteligencia Artificial

Hace un mes comencé a recuperar en un post mi interés en los últimos años, donde he publicado muchos artículos en este blog , y he dejado mu...

Entradas populares