Archivo de la categoría: Geek

Implementación teórica con BlockChain para un sistema de votaciones

Ha inicios de este año recibí un mensaje en Linkedin donde me preguntaban si estaba interesado en comenzar un proceso de reclutamiento, lo cual no es nada raro ya que siendo ingeniero de software (una de las industrias con más de profesionales en la actualidad) te llegan correos con propuestas laborales todos los días, sin embargo esta propuesta me pareció bastante interesante ya que necesitaban un Senior BlockChain Engineer, el mensaje en cuestión era:

Si bien no tengo experiencia desarrollando BlockChain como tal, si tengo bastante experiencia con sistemas distribuidos, así que me di a la tarea de comenzar a aprender el funcionamiento de esta tecnología desde un punto de vista técnico, sus conceptos básicos y sobre todo tratar de entender por que se volvió tan popular y sera el “futuro”.

Disclaimer: El código mostrado en el articulo a continuación no es una implementación real de BlockChain (no esta ni cerca del 1% de ser un proyecto real) la intención es resaltar y explicar las partes mas importantes y hacer hincapié en los conceptos básicos de lo que es BlockChain, el código dista de ser perfecto y no debe ser usado en producción.

Bueno ya estan advertidos hehe, comenzamos.

El bloque

Para entender lo que es la cadena de bloques primero tenemos que entender lo que es un bloque, el bloque puede ser representado como un objeto que contiene un identificador único, un timestamp, información en cualquier formato que queramos, un hash o checksum que representa la información que contiene y lo mas importante es que debe tener una referencia al bloque anterior, como si de una lista enlazada se tratara.

Con un lenguaje tan sencillo como Javascript podemos representar al bloque de la siguiente forma:

class Block {
  constructor(index, timestamp, data, previousHash = '') {
    this.index = index;
    this.timestamp = timestamp;
    this.data = data;
    this.previousHash = previousHash;
    this.hash = this.calculateHash();
  }

  calculateHash() {
    return SHA256(this.index + this.timestamp + JSON.stringify(this.data) + this.previousHash).toString();
  }
}

La clase bloque contiene una función muy especial llamada calculateHash, esta función toma toda la información del bloque (index, timestamp, data, previousHash), la concatena y le aplica un algoritmo de hashing para generar un checkSum que despues sera almacenado en el mismo bloque, la parte interesante y una de las razones por las que BlockChain es seguro es precisamente el uso de estas funciones criptográficas, ya que su integridad esta respaldada de forma matemáticamente.

Detengamonos por unos segundos y pensemos, si todo bloque debe de tener una referencia al hash del bloque anterior, y ese dato (previousHash) se utiliza para calcular el hash del bloque actual eso significa que si alguien hackea/modifica/elimina uno de los bloques anteriores todos los siguientes bloques quedarían invalidados 🙂 , seria un efecto domino de fallas en la integridad de los bloques.

Esta es la representación mas básica que se me ocurre de un bloque, en la vida real son estructuras de datos mucho mas complejas y en la parte de los datos pueden contener muchísimas mas piezas de información y no solo una, como lo es el caso de las transacciones en la BlockChain de Bitcoin.

La cadena

Habiendo entendido un poco lo que es el bloque ahora toca el turno de la cadena, esta es otra estructura de datos que funciona alrededor de los bloques y realiza operaciones con ellos, mencione que esta tecnología es muy parecida a una lista enlazada, si el bloque es uno de los nodos entonces la cadena serian las operaciones de agregar, eliminar, modificar, etc nodos, aunque en BlockChain solo podemos agregar bloques y nunca eliminarlos por lo que mencionaba sobre la integridad de los hashes.

En Javascript podemos representar la cadena de la siguiente forma:

class BlockChain {
  constructor() {
    this.chain = [this.createGenesisBlock()];
  }

  createGenesisBlock() {
    return new Block(0, new Date(), "Genesis block");
  }

  getLatestBlock() {
    return this.chain[this.chain.length - 1];
  }

  addBlock(block) {
    block.previousHash = this.getLatestBlock().hash;
    block.hash = block.calculateHash();
    this.chain.push(block);
  }

  isChainValid() {
    for(let i = 1; i < this.chain.length; i++) {
      const currentBlock = this.chain[i];
      const previousBlock = this.chain[i - 1];
      if (currentBlock.hash !== currentBlock.calculateHash()) {
        return false;
      }
      if(currentBlock.previousHash !== previousBlock.hash) {
        return false;
      } 
    }
    return true;
  }
}

Tenemos varias funciones interesantes como addBlock (agregar nuevo bloque), getLatestBlock (obtener el ultimo bloque), isChainValid (valida la integridad de la cadena de bloques) y createGenesisBlock, estas dos ultimas son las mas interesantes.

Mencione que cada bloque debe tener una referencia al bloque anterior ¿Pero entonces cuál fue el primer bloque 🙂 ?

Toda cadena de bloques inicia con un bloque llamado Bloque Genesis, ese nombre no es nada mas que una convención, es la forma de inicializar la cadena.

La función isChainValid verifica la integridad de la cadena utilizando los hashes de cada uno de los bloques, comienza revisando a partir del segundo bloque (uno después del bloque génesis) y primero revisa que el hash actual efectivamente corresponda con la información del bloque

if (currentBlock.hash !== currentBlock.calculateHash()) {
  return false;
}

Después revisa que la referencia (previousHash) al bloque anterior sea la correcta:

if(currentBlock.previousHash !== previousBlock.hash) {
  return false;
} 

Así hasta llegar al ultimo bloque y si todo sale bien la cadena es valida :). Sin embargo si entendieron bien el concepto de verificación de integridad pueden ver el problema con esta implementación, si bien no es posible modificar la información de un bloque intermedio, teóricamente es posible “hackear” la información del ultimo bloque antes de que agreguen nuevos nodos a la cadena.

Este precisamente es el problema que se aborda en el primer paper de Bitcoin por Satoshi Nakamoto: Bitcoin: A Peer-to-Peer Electronic Cash System

Sin entrar en detalles, en implementaciones reales la cadena de bloques no se encuentra centralizada en una sola maquina, en lugar de eso es una red distribuida y todas las computadoras de la red contienen una copia completa de la cadena, entonces cada vez que alguien va a agregar un nuevo bloque toda la red tiene que consentir y finalmente ese bloque se almacena en las cadenas de todas las maquinas, sin embargo esta solución abre la posibilidad a nuevos tipos de ataques como por ejemplo el double spend attack, aun así, teóricamente sigue siendo posible “hackear” la BlockChain pero para eso tendrías que modificar los últimos bloques de todas las maquinas de la red lo cual requiere una cantidad inmensa de recursos y por lo tanto no es factible.

Ejemplo de BlockChain para votaciones

Habiendo aprendido los conceptos básicos ahora podemos pensar en como usar BlockChain para almacenar información referente a un sistema de votaciones, vamos a escribir unas cuantas pruebas en Javascript para probar nuestras dos clases, Block y BlockChain.

  it('Generate genesis block', () => {
    voteChain = new BlockChain();
    assert.lengthOf(voteChain.chain, 1);
    assert.equal(voteChain.chain[0].data, 'Genesis block');
  });

Con este test probamos que la cadena se inicializa y el bloque génesis es generado correctamente (la longitud de la cadena es 1 y data del primer bloque contiene el string ‘Genesis block’)

Ahora vamos a agregar unos cuantos bloques a la cadena

  it('Add some blocks', () => {
    voteChain.addBlock(new Block(1, new Date(), { user: 'Manuel', voted: 'PRI' }));
    voteChain.addBlock(new Block(2, new Date(), { user: 'Andres', voted: 'PAN' }));
    voteChain.addBlock(new Block(3, new Date(), { user: 'Julio', voted: 'PRD' }));
    voteChain.addBlock(new Block(4, new Date(), { user: 'Carlos', voted: 'PRI' }));
    voteChain.addBlock(new Block(5, new Date(), { user: 'Ruben', voted: 'PAN' }));
    voteChain.addBlock(new Block(6, new Date(), { user: 'Laura', voted: 'PRD' }));
    assert.lengthOf(voteChain.chain, 7);
  });

Estamos almacenando nombres de personas y el partido político mexicano por el que votaron, un bloque a la vez y al final verificamos que la longitud de la cadena es 7 (incluyendo el bloque génesis). En la vida real esto es mucho mas complicado ya que la gente no podría agregar bloques “solo por que si”, al igual que con Bitcoin se utilizaría una tecnología de PKI (Infraestructura de llave publica) en donde cada transacción de voto deberá ser firmada usando la llave privada (como con la FIEL del SAT) de la persona que emite su voto, de esa manera nadie podría votar a nombre de alguien mas.

Ahora tenemos nuestro test para verificar la integridad de la BlockChain, si la cadena es valida esperaríamos que la función isChainValid nos devolviera true.

  it('Validate chain integrity', () => {
    assert.isOk(voteChain.isChainValid(), 'Block hashes are incorrect'); // this should return true
  });

Observen como en cada uno de los bloques el valor de previousHash es identico al hash del bloque anterior

En la ultima prueba simulamos que alguien modifico el voto de alguien mas, para eso tomamos de forma aleatoria un bloque y cambiamos el valor de su data por el nombre de otro partido político.

  it('Changing random data in the BlockChain', () => {
    const min = 0; // first block id
    const max = 5; // for academic purpose this cannot be 6 (the last block id) due to double spend attack
    const blockId = Math.floor(Math.random() * (max - min + 1) + min); // https://stackoverflow.com/questions/4959975/generate-random-number-between-two-numbers-in-javascript
    const block = voteChain.chain[blockId];
    block.data = { user: block.data.user, voted: 'MORENA' }; // Changing block value
    block.hash = block.calculateHash(); // Re calculate the current block hash so no one notices the hack
    assert.isNotOk(voteChain.isChainValid(), 'Block hashes are incorrect'); // this should return false
  });

El test, de forma aleatoria, tomo el bloque con index 2 y cambio los valores que tenia en data y eso hizo que el hash resultante de ese bloque cambiara completamente.

hash antes del cambio:
9ecbe54e3e6b3f22a522bbee7f399002f1de2d653c15a74d2d321f27cdfe116b

hash después del cambio:
3e6c8f5c0a734db4bb19483a11022081250171621e5c5c17c21a302d1d9d14d0

Por lo tanto el previousHash del bloque index 3 ya no coincide con el del bloque index 2.

Debido a este cambio la validación de integridad de la cadena fallara (siempre y cuando no modifiquemos los datos del ultimo bloque) y isChainValid() nos devolverá false.

Y eso es todo por ahora, finalmente si quieren descargar este sencillo código para verlo mas a detalle o simplemente para tenerlo lo pueden hacer desde el siguiente repositorio de github alevsk blockchain javascript con los siguientes comandos

$ git clone https://github.com/Alevsk/blockchain-javascript
$ cd blockchain-javascript
$ npm install
$ mocha index.test.js

Resumen

BlockChain nos ofrece ante todo integridad de la información, nos asegura que la información no puede ser cambiada ni eliminada sin que nos demos cuenta, ademas por su naturaleza de ser un sistema distribuido es virtualmente imposible hackear la red, esta tecnología aplicada a un sistema de votaciones nos garantiza que algo como el robo de votos no puede ocurrir y tendríamos total transparencia en las votaciones.

Si quieren aprender mas sobre esta tecnología les recomiendo ver este video en donde se explica con mucho mas detalle como funciona Bitcoin y la BlockChain en general, se abordan muchísimos mas conceptos de los que mencione en este articulo.

Happy hacking 🙂

25 mujeres tecnólogas / hackers / programadoras que sigo en twitter – Parte 2

Continuo con la segunda parte de mi listas, mujeres en la tecnología que no puedes dejar de seguir en Twitter 🙂

#11 – Jessy Irwin

Tecnologa y entusiasta de la ciberseguridad, Jessy es un miembro muy activo en la comunidad, parte de su tiempo lo dedica a impartir platicas sobre privacidad de datos, consejos básicos sobre seguridad y en general concientizar a la población acerca del buen uso de Internet, en su blog personal tiene bastantes referencias sobre platicas y eventos a las que ha sido invitada

#12 – Julia Evans

Julia es una hacker muy peculiar 🙂 no solo por la manera en la que transmite sus ideas (les recomiendo ver los videos de sus presentaciones en YouTube) si no también por el gran numero de áreas que domina en la informática, parece que no hay algo que esta mujer no sepa y lo mejor de todo es que puede explicar temas muy complejos de una forma simple y fácil de entender para el común de los programadores. Algunas de sus publicaciones mas populares incluyen System design, TCP stack, Kernel hacking, dynamic memory, etc.

Aunque ella se considera a si misma una simple administradora de sistemas, en sus publicaciones Julia demuestra un gran expertis en el área de redes y sistemas operativos en general.

#13 – Katie Moussouris

Fundadora y CEO de LutaSecurity, empresa dedicada en proveer soluciones para el responsable disclosure de vulnerabilidades en las organizaciones, los tweets de Katie incluyen las ultimas noticias sobre el malware que afecta a las organizaciones y APTs (advanced persistent threat) en general.

#14 – Katie Neuman

Katie Neuman es una autoridad en la comunidad de seguridad, junto con un grupo de expertos se encargan de crear las pautas para que los procesos de seguridad a nivel corporativo sigan un mismo estándar, en su cuenta de Twitter publica acerca de las ultimas amenazas en el mundo de la ciberseguridad.

#15 – Lesley Carhart

Lesley Carhart es una veterana de la seguridad, con mas de 15 años de experiencia en la industria, incluyendo 8 como DFIR (Digital Forensics and Incident Response) es una gran inspiración para todas los entusiastas de la informática forense, mediante su blog personal colabora con la comunidad publicando artículos de seguridad dirigidos tanto a audiencia técnica como no técnica, puedes encontrar varios videos de sus charlas en Youtube

#16 – Amanda Rousseau

Amanda Rousseau, mejor conocida como Malware Unicorn, es una analista de Malware e investigadora de seguridad, su experiencia incluye haber trabajado como Malware reverse Engineer en el centro de delitos cibernéticos del Departamento de Defensa de los Estados Unidos, Amanda es especialmente popular en eventos de ciberseguridad como Defcon y Black Hat por sus platicas y talleres sobre ingeniería inversa.

Si estas interesado en el análisis de Malware, en su blog encontraras dos cursos completamente gratuitos que te ayudaran a empezar, Reverse Engineering Malware 101 y Reverse Engineering Malware 102.

#17 – Melissa Archer

Melissa Archer es una entusiasta de la tecnología, actriz y empresaria, mejor conocida por ser cofundadora de Hacker’s brew, Jailbreak developer y Tweak developer.

#18 – Ophelia Pastrana

Ophelia Pastrana es una mujer transgénero, física, economista, emprendedora y agnóstica de la tecnología, es muy activa en redes sociales, especialmente en la comunidad tecnológica y LGBT de Latinoamérica, es creadora de varios podcast/vlogs como nerdcore y canvas y le gusta asistir a multitud de eventos tecnológicos entre ellos Campus Party MX, en el cual he tenido la oportunidad de conocerla y hablar con ella personalmente.

#19 – Parisa Tabriz

Parisa Tabriz aka Security Princess, trabaja en Google liderando uno de los equipo de ciberseguridad encargado de mejorar la seguridad de varios productos, entre ellos como Google Chrome, Parisa es una investigadora de la que todo entusiasta de la seguridad ha oído hablar al menos una vez, una de sus aportaciones mas significativas ha sido su articulo So, you want to work in security? en donde comparte consejos a las personas que se quieren iniciar en seguridad.

#20 – Rosa Guillén

Rosa Guillén, también conocida como Novatillasku es una entusiasta de Linux a la que tengo ya varios años de seguir en Internet, es autodidacta y tiene un blog donde publica noticias y artículos de tecnología, comencé a leer sus tutoriales sobre Ubuntu y Linux en general cuando empezaba la preparatoria, si quieres estar enterado de las ultimas noticias sobre este sistema operativo definitivamente es una excelente fuente de noticias.

#21 – Sailor Mercury (Amy)

Sailor Mercury tiene una historia muy interesante, ella solía ser una desarrolladora web en Airbnb y tenia un pasa tiempo que consistía en crear historietas sobre tecnología y diversos temas de ciencias computacionales como algoritmos, memoria, TCP, protocolos, etc. con la ayuda de Kickstarter consiguio fondos para crear una tienda en linea llamada bubblesort.io, dejo su trabajo en Airbnb y ahora se dedica de tiempo completo a seguir transformando conceptos complejos en pequeñas historietas para que mas gente tenga acceso al conocimiento.

#22 – Samantha Davison

Samantha Davidson es una hacker que ha trabajado en equipos de seguridad de compañías como Uber y actualmente Snapchat, su trabajo consiste en concientizar a las personas acerca de la privacidad de sus datos, sobre todo en ambientes corporativos.

#23 – Sheila A. Berta

Tuve la oportunidad de conocer a Sheila en una de sus platicas durante el DragonJar Security Conference en 2015 en Manizales, Colombia. Ella se dedica a la seguridad informática pero desde un punto de vista mas ofensivo, es una reverse engineer y analista de malware muy hábil, ha contribuido a la comunidad de seguridad creando herramientas como CBM – The Bicho y el framework Crozono

#24 – Yan Zhu

Yan Zhu es otra de las hackers mas populares y respetadas en la comunidad de seguridad, siempre esta presente en eventos como Defcon y Black Hat, entre sus aportaciones a la comunidad se encuentran haber contribuido a proyectos como HTTPS everywhere, Let’s Encrypt, SecureDrop, Privacy Badger y Brave

Puedes encontrar varias de sus charlas en Youtube, la gran mayoría de ellas son acerca de protocolos de seguridad para comunicaciones como TLS.

#25 – Keren Elazari

Investigadora y oradora en temas de ciberseguridad reconocida mundialmente, trabaja directamente con compañías Big 4 y Fortune 500 ayudandolos a crear estrategias para mejorar su seguridad y la de sus productos. Esta mujer ha aportado bastante a la comunidad y ha sido fuente de inspiración de muchísimos entusiastas alrededor del mundo, ha sido mencionada en medios de gran reputación como Forbes, Scientific American, WIRED y TED.

Tienen alguna otra recomendación para seguir en Twitter? de ser así se los agradecería.

Saludos.

#Docker para #hackers y pentesters, ejecutando #metasploit desde un container

Se acabó el 2016 y como ultima publicación del año les traigo un tutorial exprés que involucra docker y seguridad informática. En publicaciones anteriores explicaba que durante estos últimos meses he estado trabajando bastante con docker, orchestration e infraestructura de cloud en general (parte habitual en un trabajo de full stack engineer).

Docker es una herramienta muy poderosa para desarrolladores pues nos ayuda a construir imágenes con todas sus dependencias y nos deja el paso libre para enfocarnos en lo que realmente importa: deployar rápidamente una aplicación (o varias) que sabemos que va a funcionar.

Bajo esa premisa no es de extrañarse que la comunidad de seguridad haya adoptado docker tan rápidamente, docker es una herramienta fantástica 🙂 y así como nos permite dockerizar una aplicación también podemos dockerizar herramientas de seguridad y en general cualquier cosa que tengamos en nuestro arsenal para pentest.

La gente que trabaja o ha trabajado en seguridad, específicamente en el área de penetration testing, estará de acuerdo en que uno de los recursos más importantes que tenemos son las ventanas de tiempo, por lo general cuando se realiza una prueba de penetración a alguna aplicación o sistema se hace durante un periodo de tiempo bien definido, el tiempo es valioso y no podemos desperdiciarlo en instalar y configurar herramientas, o peor aun ¿que pasa si la infraestructura que estamos auditando nos bloquea? ¿cuánto tiempo vamos a invertir en preparar un nuevo nodo desde donde podamos lanzar ataques y recibir shells?, para todo lo anterior llega docker al rescate 🙂

En este tutorial mostraré como ejecutar una de las herramientas de seguridad más populares utilizando docker: metasploit, específicamente utilizaremos el módulo exploit/multi/handler para recibir sesiones de meterpreter.

ojo: no voy a mostrar como dockerizar metasploit, eso lo dejamos para un siguiente tutorial donde veamos como dockerizar aplicaciones

Ejecutando metasploit desde un contenedor de docker

Para evitarte el problema de abrir los puertos en tu router y hacer un mapeo de puertos para exponer tu maquina a internet, puedes contratar un vps con algún proveedor de tu elección, hoy en día es muy sencillo contratar un vps y puedes tener uno en línea prácticamente en minutos, yo recomiendo digitalocean por qué sus vps son baratos y el soporte es muy bueno, con un nodo de 10 USD al mes es suficiente para correr una imagen de metasploit, puedes contratar el de 5 USD pero tendrás que habilitar el swap o si no quieres gastar dinero siempre puedes aprovechar la promoción que te ofrece Amazon Webservices (más o menos 1 año de uso gratuito de una instancia micro)

Sea cual sea el proveedor que hayas elegido el siguiente paso es instalar docker en tu instancia, para este tutorial lo haré sobre ubuntu / debian pero podrías instalarlo en el sistema operativo de tu elección, acá tienes una lista de sistemas operativos soportados

Desde la terminal de tu instancia y como root vamos a ejecutar algunos comandos para instalar herramientas necesarias como compiladores de gcc/g++, algunas librerías, utilidades, etc. al final vamos a instalar docker

apt-get install build-essential
apt-get install libxslt-dev libxml2-dev zlib1g-dev --yes
apt-get install docker
apt-get install docker.io

Lo siguiente que vamos a hacer es crear un directorio en nuestra instancia, este directorio lo vamos a utilizar como un volumen persistente cuando ejecutemos metasploit desde el contenedor para poder almacenar ahí todo el loot, scripts y en general archivos que nos genere la herramienta.

mkdir /root/.msf4

Llego el momento, en el docker registry oficial existe una imagen llamada remnux/metasploit que contiene todo lo necesario para ejecutar la herramienta, ejecutamos el siguiente comando y docker comenzara a descargar la imagen y posteriormente procederá a correr el contenedor.

docker run --rm -it -p 443:443 -v ~/.msf4:/root/.msf4 -v /tmp/msf:/tmp/data remnux/metasploit

En el tutorial de docker anterior explicaba para que era cada parametro, en resumen -p nos permite mapear puertos y -v definir volúmenes persistentes (mapear una carpeta de nuestro sistema de archivos a una del sistema de archivos virtual del contenedor).

Una vez la imagen haya sido descargada el contenedor será creado y todas las dependencias necesarias comenzaran a ser instaladas, nos olvidamos de instalar todas las gemas y resolver conflictos y nos podemos ir por un café ya que es un proceso bastante automatizo 🙂

Después de unos minutos tenemos un nodo listo para recibir conexiones.

En el caso de necesitar más listeners no hay problema pues podemos ejecutar múltiples contenedores de metasploit en diferentes puertos y así tener nuestras shells organizadas, y si nuestro servidor es baneado rápidamente podemos desplegar otro ejecutando esos 6 comandos.

Como lo he comentado en varios artículos, docker es una herramienta muy poderosa que puede ser utilizada en varias situaciones además del desarrollo de software, como lo vimos en este tutorial. Puedes dockerizar casi cualquier cosa, yo en lo personal tengo una imagen con un set de herramientas que utilizo en mi día a día (fierce, dirb, sqlmap, nmap, enum4linux, hashcat, Responder, etc.)

Saludos y Happy Hacking.

Docker 101 #2: puertos y volúmenes de un contenedor

docker-image

En el artículo anterior comenzamos con una breve introducción a docker, vimos su instalación, configuración e incluso lanzamos un par de servidores web nginx usando contenedores, en esta ocasión explicare un poco más acerca de los puertos y los volúmenes.

Puertos

Ok, lo primero que explicare será el mapeo de puertos, abrimos una terminal y ejecutamos el siguiente comando:

$ sudo docker run --name servidor-web -p 80:80 nginx

El parametro –name sirve para asignarle un nombre al contenedor.

El parámetro -p sirve para realizar el mapeo de puertos y recibe una cadena en el formato PUERTO-HOST:PUERTO-CONTENEDOR, es decir, del lado izquierdo definimos el puerto que nuestro sistema operativo le asignara al contenedor de docker y del lado derecho el puerto en el que realmente se ejecuta el servicio dentro del contenedor, en este caso nginx (suena un poco confuso al inicio así que regresa y léelo de nuevo hasta que lo entiendas)

En el comando anterior estamos mapeando el puerto 80 de nuestra computadora con lo que sea que este corriendo en el puerto 80 del contenedor, es por eso que si vamos a http://localhost veremos el servidor web en ejecución 🙂

nginx

En la consola desde donde ejecutaste el comando podrás ver las peticiones hechas al servidor dentro del contenedor.

docker-cli

Al ejecutar el comando y correr el contenedor abras notado que la consola se queda bloqueada por el servidor web, para evitar eso podemos correr el contenedor en modo detach con el parámetro -d, esto ejecutara el contenedor en segundo plano.

$ sudo docker run -d --name servidor-web -p 80:80 nginx

docker_detach

Observa como tan pronto como ejecutamos el comando docker nos devuelve el control de la terminal, cuando ejecutas contenedores de esta forma no olvides que para eliminarlos primero tienes que recuperar su id, el cual puedes obtener haciendo:

$ sudo docker ps

y en la primera columna encontraras el ID del contenedor que después deberás de eliminar usando sudo docker rm [CONTAINER-ID], si lo prefieres un tip muy útil para borrar todos los contenedores que hayas creado es ejecutar:

$ sudo docker stop $(sudo docker ps -a -q)
$ sudo docker rm $(sudo docker ps -a -q)

El primer comando detiene todos los contenedores que estén en ejecución y el segundo los elimina todos (no puedes eliminar un contenedor que este en ejecución).

Puedes correr todas los contenedores que quieras (o necesites) de nginx en diferentes puertos y con diferentes nombres y cada uno será una instancia completamente diferente del servidor web 🙂
containers

Observa como cada uno de los servidores web corren en un puerto diferente.

multi-docker

Volúmenes

Los volúmenes en docker pueden ser definidos con el parámetro -v y nos ayudan a resolver el problema de la persistencia de datos en los contenedores, un volumen puede ser visto como un mapeo entre un directorio de nuestra computadora y un directorio en el sistema de archivos del contenedor, regresemos a nuestro contenedor de nginx, ¿cómo le hacemos para mostrar un sitio web en nginx en lugar de la página por default?

Lo primero que haremos será crear una carpeta en donde colocaremos el código fuente de nuestro sitio web html (por ahora no trabajaremos con nada dinamico), por ejemplo website

website

Ejecutamos el siguiente comando mapeando el contenido de /home/alevsk/dev/sitio-web hacia /usr/share/nginx/html que es el directorio por default que utiliza nginx para servir contenido a Internet.

$ sudo docker run -d --name sitio-web -v /home/alevsk/dev/sitio-web:/usr/share/nginx/html -p 80:80 nginx

La próxima vez que visitemos http://localhost/ veremos nuestro sitio web corriendo.

nginx-web

Puedes replicar este contenedor con el contenido del sitio web tantas veces como quieras, es muy util en un escenario donde necesitas varios ambientes para pruebas, desarrollo, etc.

Eso es todo por ahora, en el siguiente tutorial aprenderemos a crear nuestras propias imágenes de docker (dockerizar aplicaciones), después de eso veremos otra herramienta bastante útil llamada docker-compose para facilitar la orquestación de aplicaciones que utilizan múltiples contenedores.

Saludos y happy hacking.

StringTransformer: the transformation tool

st

Hola lectores, en esta ocasión me gustaría compartir con ustedes una herramienta opensource que he publicado en mi repositorio de github, se trata de StringTransformer, un script desarrollado en python cuya finalidad es tomar una cadena de texto y transformarla a distintas representaciones equivalentes de la misma, por ejemplo binario, hexadecimal, octal, md5, sha256, etc. Las funciones de transformación son clases separadas del script principal por lo que la herramienta es modular, esto significa que es bastante fácil para cualquier programador (que sepa python) crear sus propias transformaciones y extender la funcionalidad de la herramienta.

Esta herramienta les puede ser útil cuando están jugando Capture the flags y necesitan una forma rápida de analizar cadenas de texto (o al menos esa es su finalidad), la herramienta sigue en desarrollo, corrigiendo bugs e implementando nuevas funcionalidades.

Instalación

Su instalación es bastante sencilla, primero deben de clonar el repositorio usando git

$ git clone https://github.com/Alevsk/stringTransformer.git

Una vez descargado el repositorio acceden a la carpeta del proyecto, dan los permisos de ejecución necesarios y lanzan el script:

$ cd stringTransformer
$ chmod +x stringTransformer.py
$ ./stringTransformer.py
                  
              _______         
       _____ |   _   |  ____  
      |    |  \  V  /  |    | 
      |   \ \  \_ _/  / /   | 
      \  \ \ \   '   / / /  / 
       \  \   | 'V' |   /  /  
     |\ \_____| \ / |_____/ /|
     | \        | |        / |
     |  |    ,/|| ||\,    |  |
     |   `| '  || ||  ' |`   |
     |    | |  || ||  | |    |
     \    | |  || ||  | |    /
      \.  | |  ||_||  | |  ./ 
       \  | |  |___|  | |  /  
         \' ,  _____  , '/    
             \/ ___ \/        
               /___\          
                           

stringTransformer v0.1 (https://github.com/alevsk/stringTransformer/)

Usage: stringTransformer.py -i INPUT_STRING | --input INPUT_STRING | --load FILE

stringTransformer.py: error: Required argument is missing. Use '-h' for help.

Con el comando -h o –help podran ver el menu de ayuda:

Options:
  -h/--help             show this help message and exit
  -i/--input=INPUT      set the input string to test with
  -l/--load=LOAD_FILE   load list of input strings (one per line)
  -x/--exclude=EXCLUDE  exclude this representations
  -o/--only=ONLY        transform input only to this representations
  -O/--output=OUTPUT    generate an output file
  -p/--params=PARAMS    use custom parameters on transformation functions
  --list                list available input representations
  --update              update from the official git repository

Examples:
./stringTransformer.py -i [STRING]
./stringTransformer.py -i [STRING] --exclude "hexa, octal"
./stringTransformer.py -i [STRING] --only "hexa, octal"
./stringTransformer.py -i [STRING] --params "rot.cipher=13,rot.encoding=utf-8"
./stringTransformer.py --load list.txt
./stringTransformer.py --list

Para ver las funciones de transformación actualmente disponibles pueden utilizar –list:

stringTransformer v0.1 (https://github.com/alevsk/stringTransformer/)

- sha1
- octal
- binary
- sha256
- html_entities_decode
- html_entities_encode
- md5
- base64_encode
- base64_decode
- ascii
- slug
- rot_encode
- hexa
- urlencode

Puedes ayudar a crear más funciones de transformación para la herramienta, para eso sugiero lean la documentación en la página principal del repositorio (o en el archivo README.md) https://github.com/Alevsk/stringTransformer

Ejemplos de uso

Queremos aplicar una transformación hexadecimal, rot 13 encode y ascii a la cadena de texto “The transformation tool”

$ ./stringTransformer.py -i "The transformation tool" -o "hexa,rot_encode,ascii"

Obtenemos como resultado:

stringTransformer v0.1 (https://github.com/alevsk/stringTransformer/)

[i] Loaded 3 representations to apply.
[i] Starting tests at: "23:54:04"

The transformation tool

[i] applying transformation...

ascii:

84 104 101 32 116 114 97 110 115 102 111 114 109 97 116 105 111 110 32 116 111 111 108

rot_encode:

Gur genafsbezngvba gbby

hexa:

54 0x68 0x65 0x20 0x74 0x72 0x61 0x6e 0x73 0x66 0x6f 0x72 0x6d 0x61 0x74 0x69 0x6f 0x6e 0x20 0x74 0x6f 0x6f 0x6c 

==================================

Incluso podemos pasar parámetros a las funciones de transformación que lo soporten, rot_encode por defecto utilizar 13 posiciones de desplazamiento pero aquí indicamos que use 51

$ ./stringTransformer.py -i "The transformation tool" -o "rot_encode" --params="rot_encode.cipher=51"

stringTransformer v0.1 (https://github.com/alevsk/stringTransformer/)

[i] Loaded 1 representations to apply.
[i] Starting tests at: "23:58:11"

The transformation tool

[i] applying transformation...

rot_encode:

Sgd sqzmrenqlzshnm snnk

==================================

La herramienta cuenta con muchísimos otros parámetros que los invito a explorar.
saludos