Mostrando entradas con la etiqueta Proxy. Mostrar todas las entradas
Mostrando entradas con la etiqueta Proxy. Mostrar todas las entradas

viernes, marzo 28, 2025

Tu WebSite con Smart Honeypots contra el WebScrapping usando AI Labyrinth de Cloudflare

En el mundo digital actual los creadores y propietarios de sitios web se están enfrentando a un adversario particularmente voraz: los rastreadores web de Inteligencia Artificial. Estos bots, diseñados para recopilar masivamente datos que alimentarán los modelos de lenguaje de las grandes empresas de IA, están devorando datos de Internet a un ritmo alarmante. Según datos recientes de Cloudflare, estos rastreadores generan más de 50.000 millones de solicitudes diarias a su red, representando casi el 1% de todo el tráfico web que procesan. 
Estos nuevos rastreadores de IA tienen una tendencia a ignorar las reglas de etiqueta digital establecidas, el archivo robots.txt, que durante décadas ha servido como un cartel de "no pasar" respetado por los rastreadores web tradicionales, además de otras señales de opt-out, como metatags específicos que indican la prohibición de uso para entrenamiento de IA.


En este contexto, no es simplemente un malentendido técnico, sino una decisión consciente de ignorar los deseos expresos de los creadores de contenido. Esta situación ha llevado a numerosas demandas legales contra empresas de IA por parte de creadores de contenido, desde periódicos hasta artistas visuales, alegando violaciones de derechos de autor.


Además, para los administradores de sitios Web, los procesos de Webscraping no autorizados aumentan los costos de hosting, ralentiza el rendimiento del sitio y, quizás lo más importante, permite que otras entidades se apropien de contenido original sin permiso para entrenar sus modelos comerciales de IA.

AI Labyrinth  

En este contexto, Cloudflare ha lanzado este mes de marzo una solución que pretende paliar estos daños: AI Labyrinth. Esta herramienta no bloquea a los rastreadores no autorizados (lo que simplemente les alertaría de que han sido detectados), sino que los invita a adentrarse en un laberinto interminable de contenido generado por IA—una trampa digital donde los bots pueden deambular eternamente, consumiendo sus recursos sin obtener nada de valor a cambio.

Métodos tradicionales de protección y sus limitaciones

Antes de soluciones como AI Labyrinth, los sitios web han recurrido a métodos tradicionales para combatir el webscraping no autorizado, pero estos resultan ineficaces contra rastreadores de IA avanzados. El bloqueo de direcciones IP es una estrategia limitada, ya que los operadores de scraping pueden rotar direcciones o utilizar redes de proxies, lo que vuelve el proceso en una batalla interminable. 

Además, existe el riesgo de bloquear usuarios legítimos que comparten rangos de direcciones IP con los rastreadores. De manera similar, los CAPTCHAs, diseñados para diferenciar humanos de bots, generan fricción en la experiencia del usuario y han perdido efectividad con el avance de la IA, que ahora puede resolverlos con facilidad, como hemos visto en todos estos ejemplos:

Otras estrategias como la limitación de tasa de consumo buscan restringir el número de solicitudes por dirección IP, pero los rastreadores pueden ajustar su velocidad para evadir los umbrales de detección. La ofuscación de contenido mediante JavaScript o formatos difíciles de extraer, aunque parece una solución viable, afecta negativamente el SEO y la accesibilidad. 

Peor aún, los rastreadores modernos pueden ejecutar JavaScript y procesar formatos complejos, superando estas barreras con el tiempo. En última instancia, el problema de estos enfoques es que alertan a los operadores de webscraping de que han sido detectados, lo que los lleva a modificar sus tácticas en un ciclo continuo de evasión y ajuste.

Este enfrentamiento perpetuo consume recursos y beneficia a las grandes empresas de IA con capacidad para sortear estas defensas. Por ello lo que hace Cloudflare plantea un enfoque diferente: en lugar de bloquear el acceso y advertir al adversario, lo desvía de manera imperceptible hacia rutas que parecen productivas pero resultan inútiles para sus propósitos.

Implementación técnica

El primer desafío técnico que enfrentó Cloudflare fue generar contenido convincente a escala, ya que producir contenido falso pero plausible en tiempo real para cada solicitud sospechosa podía consumir excesivos recursos y ralentizar la experiencia general; para abordar esto, Cloudflare emplea su servicio Workers AI con un modelo de código abierto que pre-genera un corpus diverso de contenido HTML sobre temas variados, como ciencias (biología, física o matemáticas), utilizando un enfoque donde primero se crean temas diversos y luego contenido específico y coherente para cada uno, logrando resultados factuales y técnicamente correctos, aunque irrelevantes para el sitio web protegido, en lugar de depender de una generación puramente aleatoria.

Posteriormente sanitizan el contenido pre-generado para eliminar vulnerabilidades XSS, lo almacena en R2 para servirlo rápidamente sin cargar los servidores de origen y lo integra en sitios protegidos mediante un proceso HTML personalizado que oculta enlaces al laberinto con CSS, usando metadirectivas para evitar indexación por buscadores y proteger el SEO; además, distingue usuarios legítimos de rastreadores sospechosos analizando patrones de navegación, velocidad, User-Agents y comportamientos a nivel de red, redirigiendo a estos últimos al laberinto antes de que lleguen al servidor, aliviando así la infraestructura del cliente.

 
Para los administradores de sitios web, usar AI Labyrinth es muy sencillo, activando una opción en el panel de control de Cloudflare, en la parte de gestión de bots. Por detrás, cuando un rastreador cae en el laberinto, se recogen datos sobre cómo actúa, los usa para entrenar sus modelos de aprendizaje automático y así afinar la detección de bots maliciosos, de modo que cada sitio protegido ayuda a mejorar la seguridad de los demás.


La arquitectura distribuida de Cloudflare permite que esta solución escale globalmente sin degradación del rendimiento. El contenido del laberinto se distribuye a través de su red global de centros de datos, garantizando tiempos de respuesta rápidos independientemente de la ubicación geográfica del rastreador. Esta capacidad de respuesta global es crucial para mantener la ilusión de un sitio web real, evitando que los rastreadores más sofisticados detecten que han sido redirigidos a un entorno controlado.

Conclusiones

Esta innovadora solución de Cloudflare sacude la dinámica entre creadores de contenido y empresas de IA que recolectan datos masivamente sin permiso. Al usar contenido generado por IA para confundir rastreadores, cuestiona la noción de que internet es un recurso gratuito para tomar datos a voluntad, y sus efectos podrían sentirse en varios frentes.

Obviamente las empresas de IA no se quedarán quietas, y probablemente desarrollen formas de detectar y evitar estos trucos, iniciando una especie de carrera tecnológica. Esto no es nuevo en ciberseguridad: estas competencias suelen traer avances para ambos lados, con ideas que luego se usan en otros campos.

Un saludo,

Autor: Javier del Pino, Investigador en Ideas Locas

sábado, septiembre 10, 2022

BlockChain & SmartContracts: Actualizar SmartContracts como los grandes protocolos

En un anterior artículo hablamos de cómo se pueden actualizar los SmartContracts por medio del patrón proxy y algunos problemas que pueden derivarse de su uso; hoy voy a mostraros como los grandes protocolos y DAOs (Decentralized Autonomous Organizations) implementan este patrón en SmartContracts de Solidity y más importante aún cómo mantener esa descentralización a pesar de que la lógica del contrato sea alterable.

Figura 1: BlockChain & SmartContracts - Actualizar
SmartContracts como los grandes protocolos.
“Photo of an Ethereum smart contract being replaced” por Dall·E.

Claro ahora podrías pensar:

“Oye, pero si la gracia de los SmartContracts estaba en que estos eran inmutables y no se puede alterar ni sus valores ni funcionamiento, ahora se pueden manipular a gusto propio".

Y sí, en parte tendrías razón, por eso actualizar un contrato mediante un proxy puede ser peligroso y no se aconseja más que en grandes protocolos que pueden tener problemas con su lógica en un futuro.

¿Descentralización y proxies es posible?   

Pero aun así la descentralización se puede mantener, hasta ahora el concepto de descentralización y seguridad que hemos visto que tienen los SmartContracts reside en el hecho de que estos son inmutables y se ejecutan en la Blockchain. Con los proxies pasamos esa seguridad a una entidad central encargada de actualizar los contratos, sin embargo ese poder se puede distribuir entre la comunidad de personas que los usan, relegando así a la comunidad usuaria de estos el derecho a actualizarlos mediante por ejemplo sistemas de votación con tokens, NFTs, reputación

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

En los grandes protocolos descentralizados se suele constituir una DAO a la que se le pasa el control de los contratos y ya será esta quien gobernada por la comunidad tomaŕa las decisiones sobre los contratos. Miremos el ejemplo de UniSwap uno de los mayores DEX (Exchange Descentralizado) que existen, su funcionamiento se divide en tres:

1. El exchange: que sirve para hacer swapping entre diferentes tokens y aportar liquidez.

Figura 3: Página de Swapping de UniSwap entre tokens

2. El sistema de gobernanza del protocolo: un conjunto de SmartContracts que junto con el token $UNI conforman el control del protocolo. El funcionamiento de este sistema de gobernanza es bastante complejo y daría para un artículo bastante largo, por lo que podemos dejarlo en que se vota y propone usando $UNI.

Figura 4: Web app de gobernanza de UniSwap

3. La DAO de la comunidad de Uniswap: aunque la mayoría de las acciones que se hacen son off-chain todo el sistema de proponer cambios se hace a través del sistema de votación on-chain.

Esta es una de las maneras en las que se puede mantener la “descentralización” en un protocolo pero hay otras muchas con sus ventajas e inconvenientes pero lo que sí que podéis tener claro es que si veis alguno que no tiene sistema de gobernanza pero sus SmartContracts son actualizables huid de él porque en cualquier momento pueden robar los fondos, manipular los datos…

¿Cómo implementan los proxies los protocolos y DAOs?

Al final el patrón proxy es el patrón más usado para actualizar la lógica de los SmartContracts, implementarlo a mano puede ser tedioso y complejo dado que hay que tener en cuenta cosas como las colisiones de almacenamiento…(en el anterior artículo lo tratamos en mayor profundidad) y por ello es que se han creado herramientas y librerías que nos facilitan la vida a los desarrolladores solucionando en parte problemas de los que hablamos antes.
 
Os voy a mostrar dos formas de hacerlo; una fácil desde el punto de vista de implementación que solo requerirá de un par de cambios en nuestro SmartContract y otra más complicada que exigirá más cambios. Os voy a mostrar las dos porque la primera de ellas nos va a dar un control muy vago de lo que está sucediendo y la última nos permite visualizar de manera más clara lo que estamos haciendo.

1.- Forma “fácil”:

Esta manera es “sencilla” de cara a que no tenemos que hacer nada más que cambiar un par de variables, todo nos lo va ha hacer un módulo de Openzeppelin montado sobre la herramienta de Hardhat, veamos un ejemplo simple.

Figura 5: Proyecto de Solidity usando Hardhat

Para el ejemplo crearemos un proyecto nuevo de JavaScript con Yarn, Npm, Pnpm… u otro gestor de paquetes de NodeJs, e instalamos las siguientes dependencias, dentro de la consola:
“””
yarn init -y
yarn add hardhat @openzeppelin/contracts @openzeppelin/hardhat-upgrades
yarn hardhat
“”
Ahora seleccionaremos las siguientes opciones en la consola:

Figura 6: Selección de opciones en HardHat
  • “Create a JavaScript project”
  • Le damos a “y” a todo lo que nos pregunte HardHat
A continuación añadimos el siguiente contrato que nos servirá de prueba dentro de la carpeta “contracts”.
“
pragma solidity ^0.8.0;

contract Box {
    uint256 private _value;
    event ValueChanged(uint256 value);

    function store(uint256 value) public {
        _value = value;
        emit ValueChanged(value);
    }

    function retrieve() public view returns (uint256) {
        return _value;
    }
}
“
A continuación creamos un script de JavaScript para desplegar el contrato, vamos a modificar un poco el típico script que nos da Hardhat por defecto, dentro del ejemplo que nos da Hardhat escribimos lo siguiente:
“
const { ethers, upgrades } = require("hardhat");

async function main() {
  const Box = await ethers.getContractFactory("Box");
  console.log("Deploying Box...");
  const box = await upgrades.deployProxy(Box, [42], { initializer: "store" });
  await box.deployed();
  console.log("Box deployed to:", box.address);
}

main();
“
Lanzamos el siguiente comando y copiamos el address que nos muestra la consola.
“
yarn hardhat node (en una nueva consola)
yarn hardhat run [nombreScritp].js --network localhost
”
Ahora tenemos el contrato desplegado mediante un Proxy sin que tengamos que haber hecho nada especial más que instalar un par de librerías, guay eh, pues ahora vamos a actualizar mediante ese Proxy el contrato, para ello creamos una nueva versión del SmartContract y del Script. Al nuevo SmartContract lo podemos llamar “Box2” ya que es la segunda versión y este ahora más que guardar un solo valor le vamos a permitir cambiar ese valor incrementándolo al llamar a una función “storeIncrement”.
“
pragma solidity ^0.8.0;
contract Box2{
    uint256 private _value;
    uint256 private _increments;
    event ValueChanged(uint256 value);
    function store(uint256 value) public {
        _value = value;
        emit ValueChanged(value);
    }
    function storeIncrement(uint256 value) public {
        _increments = value;
    }
    function retrieveIncrement() public view returns (uint256) {
        return _increments;
    }
    function retrieve() public view returns (uint256) {
        return _value;
    }
    function increment() public {
        _value = _value + 1;
        emit ValueChanged(_value);
    }
}
”
Y dentro del script nuevo insertamos:
“
const { ethers, upgrades } = require("hardhat");

async function main() {
  const BoxV2 = await ethers.getContractFactory("Box2");
  console.log("Upgrading Box...");
  await upgrades.upgradeProxy(
    "[addressContratoDesplegado]",
    BoxV2
  );
  console.log("Box upgraded");
}

main();
”
Simplemente tenemos que lanzar el siguiente comando y ya tendremos actualizado nuestro SmartContract.
“
yarn hardhat run upgrade_box.js --network localhost
”
Como veis es una forma relativamente sencilla de actualizar un SmartContract sin tener que cambiar nada de este y sin siquiera saber que es un Proxy en la EVM, pero esto lleva consigo unos contras como por ejemplo no llevar el control real del “layout” del almacenamiento del contrato lo que puede ser catastrófico a la hora de actualizar el contrato a una nueva versión.

2.- Forma difícil:

La anterior herramienta nos ofrece muchas facilidades para actualizar nuestros SmartContracts sin embargo en grandes proyectos necesitamos tener un mayor control y conocimiento sobre el SmartContract y no usar una herramienta que “hace magia” para actualizar los SmartContractsLa solución es utilizar librerías de Solidity que solo añaden código y no modifican nuestro SmartContract. Para después ser nosotros quien realice el despliegue y las actualizaciones para saber en todo momento qué es lo que ocurre.

Figura 7: Modelo Proxy en Smart Contracts

Recordemos que a la hora de actualizar SmartContracts mediante proxies tenemos que tener en cuenta que el contrato que despleguemos va a ser solo lógica y que esta va a interactuar para modificar el almacenamiento de otro contrato, visualmente se vería como la imagen de abajo. Si por ejemplo tuviéramos un SmartContract como el siguiente
“
pragma solidity ^0.8.0;

contract Box {
    uint256 private _value = 54;
// … rest go above
}
“
Podríamos observar que configuramos una variable con un valor por defecto. Lo que hace el compilador a la hora de transformar nuestro SmartContract en Bytecode es añadir una función, llamémosla “firstInit”, que se ejecutará al subir este contrato a la cadena de Blockchain actualizando el valor de las variables al que hayamos especificado, lo mismo sucede con las variables en las que definamos un valor en el constructor.

Ahora os pregunto, imaginando que ya tenemos una versión v1 de nuestro SmartContract desplegado mediante un proxy, si al actualizar el SmartContract (de la lógica, es decir, éste) subiendo uno nuevo que añade otros valores en el constructor, ¿estos nuevos valores tendrán efecto en el proxy que guarda todo el almacenamiento o en el contrato de la lógica en el que no sirve de nada guardar valores dado que estos no se van a usar?

La respuesta es la segunda, estos valores se guardarán en el contrato de la lógica lo que no tiene sentido hacer porque entonces nunca usaremos estas variables, es por ello que a la hora de escribir SmartContracts que van a desplegarse mediante proxy hay que eliminar todas las variables que iniciemos en el constructor o en el cuerpo del contrato. Podemos crear una función que actualice esos valores y llamarla a través del proxy una vez se haya actualizado el contrato para que este tenga efecto:
“
pragma solidity ^0.8.0;

contract Box {
    uint256 private _value;
    function initialize(){
	private_value = 54;
   }
}
“
Y lo mismo tenemos que hacer con los contratos grandes. Si usamos estándares ya definidos como el ERC20 o el ERC721 ya existen versiones de estos con los cambios necesarios para actualizarlos mediante proxies, las librerías de Openzeppelin son un buen punto de partida. Si queréis ver cómo se implementan estás aquí os dejo un tutorial.

Conclusión  

Como podéis ver,  el patrón proxy es un patrón complejo que aporta mucha utilidad, pero que para poder mantener esa descentralización es necesario que una comunidad respalde por detrás el proyecto. Nos vemos en los siguientes artículos, pero tienes muchos más artículos sobre este mundo Web3 aquí mismo:
Saludos,

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

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.


jueves, mayo 19, 2022

Cómo montar tu (Open) VPN con PFSense de forma sencilla #PyMES #Teletrabajo

La irrupción de la pandemia en nuestras cambió muchas cosas. Una de esas situaciones fue el fortalecimiento del teletrabajo y la necesidad de las empresas a amoldarse a un trabajo remoto debido a las necesidades que todos conocemos y la imposibilidad de poder tener contacto entre nosotros. Todo esto produjo una situación en la que muchas empresas tuvieron que amoldarse y empezar a emplear recursos para poder llevar a cabo el teletrabajo.

Figura 1: Cómo montar tu (Open) VPN con PFSense de forma sencilla

En muchas ocasiones, se cometieron errores, ya que se empezaron a exponer servidores a Internet con todo el riesgo que eso podía conllevar. Las soluciones más factibles, incluso cómodas, sería la instalación de una VPN para una empresa, independientemente del tamaño de ésta. Una forma segura (si todo está bien configurado) de acceder a los recursos internos de la organización y de disponer de una trazabilidad sencilla de quién se conecta y cuando a la organización.

JL. Rambla, ampliado y revisado por Pablo González y Chema Alonso

En el artículo de hoy vamos a mostrar como se puede montar una OpenVPN, la cual es una de las posibilidades que trae PFSense, para implementar una VPN. Si eres una persona que viaja mucho y necesitas conexiones seguras en diferentes ubicaciones puede interesarte este tipo de soluciones. Montar una VPN en tu casa no es algo complejo a día de hoy con algo de conocimiento básico. PFSense simplifica el proceso de creación de la CA, del certificado del servidor, de los usuarios, etcétera.
 
Entorno: Comenzando

El entorno que vamos a suponer en este ejemplo es el siguiente:
  • Disponemos de una solución PFSense.
  • Tenemos una red LAN donde tenemos una serie de máquinas y recursos.
  • Tenemos una red WAN, la cual es Internet.
Lo que vamos a hacer es configurar en PFSense, el cual es el que se encuentra entre esa LAN y esa WAN filtrando el tráfico, es decir, actuando de firewall, para poder implementar la VPN en dicho punto. La herramienta de Package Manager que dispone PFSense permite instalar paquetes y demás funcionalidades que hacen de esta suite all-in-one una buena solución para muchos entornos. Para poder exportar los perfiles de OVPN vamos a hacer uso de la instalación del paquete openvpn-client-export.

Figura 3: Instalación del paquete openvpn-client-export

Ahora vamos a llevar a cabo la instalación del servicio de OpenVPN en PFSense. Nos dirigimos al apartado VPN y seleccionamos OpenVPN. Seleccionamos ahora “Wizards”, el asistente que simplificará el proceso de creación de todo lo necesario.

(Revisada y Ampliada) de Carlos Álvarez y Pablo González en 0xWord

Al acceder a “Wizards” empezamos en el paso 6 del proceso y nos solicita el tipo de autenticación con el que se van a autenticar los usuarios de la VPN. Puede ser una base de datos local de usuarios que mantenga PFSense o podríamos incluso integrarlo con un servidor RADIUS o LDAP. En este ejemplo, usamos la base de datos de usuarios locales.

Figura 5: Configuración de RAS

Al pulsar sobre siguiente llegamos al apartado de generación de CA. Es un apartado importante, ya que posteriormente podremos gestionar revocaciones de certificados de usuarios, entre otras cosas. Generamos la CA para el servidor de VPN, simplemente seleccionamos el tamaño de clave y el nombre que le daremos a la CA. Además, hay que indicar los típicos parámetros de país, ciudad, tiempo de validez, etcétera.

Figura 6: Configuración de la Certification Authority

Damos a siguiente y nos encontramos con la generación del certificado del servidor. Seleccionamos el tamaño de clave y rellenamos los parámetros anteriores (tiempo de vida, país, ciudad, etcétera). Si alguna vez has implementado una OpenVPN a mano con el uso de OpenSSL para generar CA y certificados o con easy-RSA, verás la diferencia al instante, ya que la GUI enmascara muchos pasos manuales que, aunque necesarios, podían ser tediosos.

Figura 7: Configuración del Certificado del Servidor

Ahora nos aparece un gran número de opciones dentro de la configuración del servicio de VPN. Hay que ir analizando cada opción. Opciones como:
  • Puerto: Es recomendable utilizar un puerto alto para montar el servicio, en vez de utilizar el puerto por defecto (1194).
  • Descripción de la VPN: Nombre descriptivo.
  • Tipo de protocolo: Sobre el que la VPN funcionará (UDP o TCP) y sobre que protocolo de red IPv4 o IPv6.
  • Opciones criptográficas: TLS Auth, TLS Key, el tamaño de DH, algoritmos criptográficos que se pueden utilizar, el algoritmo de digest, etcétera.
  • Configuración de red: De esto hablaremos un poco más adelante.
Figura 8: Configuración General de la VPN

Llegados a este punto, nos fijamos en la configuración del túnel, es decir, la configuración de red. El direccionamiento que se otorgará a los clientes, por defecto 10.0.8.0/24, aunque esto se puede personalizar como se puede ver en la imagen. Este direccionamiento podrá tener acceso a la red LAN, si así lo decidimos. Como se puede ver un poco más abajo, tenemos que indicar la red de área local, en este caso la 10.0.0.0/24 y es con la que tendremos visibilidad.

Figura 9: Opciones de Tunneling

Además, podemos configurar los diferentes parámetros de red que los clientes de la VPN recibirán por parte del servidor como, por ejemplo:
  • Direcciones de los servidores DNS (pudiendo ser el propio PFSense el servidor DNS).
  • Dirección del Gateway.
  • Dirección del servidor NTP.
  • Wins Server.
  • Opciones NetBIOS.
Después, nos encontraremos con la posibilidad de crear automáticamente la regla en el firewall para permitir las conexiones a la OpenVPN desde clientes que se encuentren en la interfaz WAN. Además, existe otra opción para crear una regla que permite todo el tráfico desde los clientes a través del túnel.

Figura10: Firewall y OpenVPN

Cuando acabamos el proceso, se nos crea una nueva interfaz en el firewall. Esta interfaz es la de OpenVPN (tendremos LAN, WAN, DMZ si la tuviéramos). En la interfaz de WAN deberíamos ver la regla creada que da acceso a la OpenVPN y el puerto que hemos seleccionado. Mientras que en la interfaz OpenVPN deberíamos ver también una regla que nos permite sacar el tráfico a través del túnel.

Figura 11: Regla del tunel

Una vez finalizado el proceso, vamos con la parte de usuarios. Lo primero que hay que hacer es ir a crear un usuario o los usuarios necesarios. Vamos al apartado System -> User Manager y aquí gestionaremos el alta y baja de los diferentes usuarios. No se ha comentado, pero en el proceso de configuración también se elige cómo se autenticarán los usuarios (contraseña, certificado, contraseña más certificado…). Hemos elegido, contraseña y certificado. 

Damos de alta un nuevo usuario, tendremos que darle un nombre, podemos meterlo en un grupo con privilegios en el firewall o no, y podremos configurarle una contraseña y, además, indicar que debe disponer de un certificado para la conexión con la VPN.

Figura 12: Certificado para la conexión

Bien, ahora que ya tenemos todo listo, nos vamos al apartado de VPN y OpenVPN y vamos a la aplicación que instalamos al principio para exportar perfiles. Veremos una opción que nos permite exportar el perfil en formato OVPN. Este perfil es el que utilizará el usuario concreto para conectarse a la VPN

Figura 13: Conexión VPN funcionando

En cualquier instante se puede revocar el certificado o eliminar el usuario de la base de datos, por lo que el acceso quedará inhabilitado. A continuación, importamos el perfil a un cliente OpenVPN, por ejemplo, en Windows, y vemos como se realiza la conexión por la interfaz WAN. A partir de entonces, tendremos acceso a los recursos de la LAN (que es la red 10.0.0.0/24).

Figura 14: Hacking Windows: "Ataques a sistemas y redes Microsoft"
de Pablo González, Carlos García y Valentín Martín.

Sin duda, PFSense es un All-in-one que proporciona muchas posibilidades y en temas de seguridad no solo se queda con la VPN. Hay que recordar que se puede instalar un IDS, proxy, AV, ciertos elementos que fortifican la infraestructura y desde un punto de vista accesible a muchos. Es importante asegurarse que las configuraciones son realmente seguras.

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

martes, mayo 10, 2022

PFSense: Un all-in-one con Fiewall, IPS, IDS, VPN y Proxy para fortificar tu red

La seguridad para evitar los Ataques en redes de datos IPv4 e IPv6, es uno de los campos más importantes  dentro de la fortificación de sistemas, ya que necesita de diferentes elementos para mejorar la protección. Elementos como un Firewall, un Sistema de Detección de Intrusiones (IDS), un Sistema de Prevención de Intrusiones (IPS), un Servidor de Redes Privadas Virtuales (VPN), un Proxy, etcétera. Estos elementos copan las redes de las organizaciones y son fundamentales para mantener la seguridad de la red.

Figura 1: PFSense - Un all-in-one con Fiewall, IPS, IDS,
VPN y Proxy para fortificar tu red

Las PYMEs también requieren de seguridad en red y es por esto que las soluciones all-in-one que se pueden encontrar pueden ayudarlas, y mucho, en fortificar su red y evitar que las amenazas del mundo digital se aprovechen de ellas. Ya sabemos que las PYMES son eslabones un poco más débiles, sobre todo cuando no hay conocimiento o concienciación sobre las amenazas del entorno. Para ellas la inversión en seguridad puede suponer un quebradero de cabeza y por esta razón soluciones como las denominadas all-in-one y similares pueden ser importantes.

JL. Rambla, ampliado y revisado por Pablo González y Chema Alonso

En el artículo de hoy, hablaremos de PFSense y de un uso básico en la que a su firewall permite. Una forma sencilla, a través de una GUI de gestionar un firewall. No hace falta aprender el listado de opciones de iptables, que siempre es recomendable de aprender y conocer cómo funciona este mundo por debajo. Además, puedes aprender sobre iptables en el libro de Hardening de servidores GNU/Linux de 0xWord.

¿Qué es PFSense?

Lo primero que hay que indicar es que es una distribución que permite configurar una máquina como router y firewall, en primer lugar. Hay que indicar que aporta un gran número de servicios, la mayoría relacionados con la securización de la red. Desde disponer de servicios básicos de red para la organización como la implementación de un DHCP o un DNS hasta la posibilidad de montar un servidor VPN o una IPSec en el propio endpoint de PFSense.

(Revisada y Ampliada) de Carlos Álvarez y Pablo González en 0xWord

Funcionalidades como el despliegue de un Proxy, de un IDS o incluso de utilizar un AV para evaluar cierto tráfico es posible también con este all-in-one. En el artículo de hoy vamos a tratar la configuración básica de un entorno con PFSense y vamos a utilizar la parte básica del firewall.

Entorno de prueba de PFSense

Para conocer más sobre las posibilidades de este entorno vamos a proponer un escenario. A continuación, los elementos con los que vamos a jugar en esta pequeña prueba:
  • PFSense: Máquina con la distro de PFSense. Tendrá tantas interfaces de red como redes queramos segmentar y definir. En este caso tendremos una red interna y una red externa (la externa simula Internet). Si quisiéramos simular un entorno: Internet, DMZ y red interna meteríamos tres interfaces de red sobre PFSense.
  • Una máquina en la red Internet (con dirección IP 11.0.0.7).
  • Una máquina en la red interna (con dirección IP 10.0.0.2).
  • Las interfaces de red de PFSense serán 10.0.0.1 y 11.0.0.1.
Figura 4: Configuración de los interfaces de PFSense

En la imagen anterior se pueden ver las configuraciones de las dos interfaces de PFSense. Hay que tener en cuenta que, t
ras la instalación de PFSense, hay que definir las interfaces de red e indicar cuál es LAN y cual es WAN. WAN será la interfaz conectada con Internet directamente. LAN será la interfaz que refleja la parte conectada con la red interna. También podemos jugar con DMZ. Una vez instalado el entorno, observamos una pantalla dónde disponemos de diferentes opciones, entre otras:
  • Asignación de interfaces.
  • Configuración de una nueva interfaz.
  • Diferentes formas de resetear el sistema.
  • Visualización y filtrado de logs.
  • Reinicio y apagado del sistema.
Figura 5: Opciones de configuración de PFSense

Si conectamos a través de un navegador web por la interfaz de red de la red interna podemos acceder al panel control web de PFSense. Desde ahí vamos a poder gestionar de manera más sencilla todo lo que se puede hacer desde la herramienta. Si vemos el menú superior podemos encontrar diferentes posibilidades:
  • Ver información del sistema, versión, actualizaciones, etcétera.
  • Configuración de interfaces.
  • Configuración del firewall. Como se puede ver en la imagen todas las opciones que proporciona PFSense: VLANes, NAT, reglas, programación, etcétera.
  • Servicios de red: DNS, DHCP, Wake-on-LAN, portal cautivo, etcétera.
  • Configuración de la VPN: IPSec, L2TP y OpenVPN.
  • Monitorización de los servicios.
Figura 6: Opciones de configuración del Firewall

Las posibilidades sobre PFSense son muchas. Además, existe un market dónde se pueden ampliar funcionalidades, como se comentó anteriormente.
 
Ejemplo 1: Haciendo PING desde red interna a Internet

Como primer ejemplo y entendiendo que en principio PFSense va a bloquear cualquier tráfico que circula entre la máquina situada en una red y en otra, vamos a ver cómo crear reglas en la máquina.

El punto de partida es que la máquina 10.0.0.2 (la que se encuentra en red interna) no puede hacer PING (ICMP) con la máquina de Internet. La política por defecto del Firewall es DROP, ya sea en NAT, ya sea en Filtering. Es decir, se deniega el paso de los paquetes a través del Firewall, salvo que haya alguna regla que indique lo contrario. Ahora nos tocará crear esas reglas.

Figura 7: Ping capturado por una regla DROP

Necesitamos crear una regla para permitir que la petición de PING (ICMP) salga de la red interna a la externa. Si nos fijamos en la siguiente imagen se va a ver que es sencillo indicar la acción (dejar pasar), la interfaz por la que llega el paquete (LAN), la interfaz por la que saldrá el paquete (WAN), el protocolo (ICMP) y el subtipo de mensaje (en este caso un ICMP echo request).

Figura 8:  Configuración de la regla para dejar pasar el Echo Request

En otras palabras, solo permitiremos que salgan los echo request de ICMP. La idea es que desde fuera (Internet) no puedan pasar el Firewall y hacer un PING (ICMP) a una máquina de la red interna, por lo que un echo reply no debe pasar de la LAN a la WAN. Ahora hay que configurar la regla contraria: desde la WAN debemos dejar pasar los ICMP con el tipo de mensaje echo reply.

Figura 9: Y ahora lo mismo desde el interfaz WAN

Todo lo trabajamos en la interfaz WAN, ya que LAN tiene una regla por defecto que es dejar pasar cualquier protocolo de arquitectura TCP/IP, por lo que las reglas se aplicarán en la interfaz WAN.

Este es un ejemplo con PFSense de lo que uno se puede montar en casa o en entornos laborales pequeños o medianos. Poco a poco iremos viendo algunos ejemplos más, donde se añadirá, por ejemplo, una red DMZ con servicios e iremos acercándonos a un entorno más real. Si quieres aprender sobre seguridad en redes, monta tu laboratorio con máquinas virtual.

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