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.
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.
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:
¿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.
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.
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:
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.
Figura 2: Libro dedicado a "Bitcoin: La tecnología Blockchain y su investigación" de Yaiza Rubio y Félix Brezo |
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.
¿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.
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:
- 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
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