Building REST APIs for hacking tools

What is this post about?

In this post I will talk about how to create REST APIs for hacking tools in 5 minutes.

What is the real problem?

The problem that I present to you today solves several small problems. I expose them as questions:

  • Had you have problems auditing remote services lacking a proxy machine?
  • Do you need to allow access to only specifics commands in a system?
  • Moreover: do you need to delegate access to these commands, or ONLY to certain parameters of the command?
  • Wouldn’t be great to be able to perform a security analysis by calling curl or wget?

Well, a lot of us had this problems. For this reason in the BBVA-Labs department we have been working on a pretty cool toy.

Check out our BBVA-Labs projects

The idea is very simple:

Given a command line script, you can create a REST API in minutes.

We gave this project the name of Kapow! and my colleagues chose a pretty cool logo 🙂

Although the project is still in beta, you can download and use it. We think that the idea is powerful and exciting (and that’s why I’m writing this post :D)

Download Kapow! from Github

Create an API for nmap in 5 minutes

How does it works in one image

Kapow actually does the magic of creating the REST API, given a command:

Defining the API

For Kapow to know how to create the API it needs to create a .pow file with the instructions. Do not be scared, it’s very simple:

# nmap.pow

kapow route add -X GET '/scan/{ip}' -c 'nmap -sL $(request /matches/ip) | response /body'

Let’s analyze the file. You’ll see it’s very simple:

  1. We create a new API with a path: /scan/{ip}, where IP is the target to analyze established as an input parameter.
  2. -c ‘nmap…’: is the way we tells Kapow! the command to run.
  3. $(request /matches/ip): this is the way we tells Kapow! that from the received request, we want to use the variable “ip”.
  4. response /body: this is the way we tells Kapow! how to return the result of execution as HTTP

Building Kapow!

Since the project is still beta, we will need to build Kapow! ourselves. You scare us. It’s easy.

At first we clone the repository:

> git clone -b develop https://github.com/BBVA/kapow.git
> cd poc/

Be careful when making the clone. The branch to clone is the develop !!

First of all we will need to add a line to the original Dockerfile, which is located in the /poc/Dockerfile directory. We need to add nmap for installation.

The resulting Dockerfile should look like this:

FROM python:3.7-alpine

COPY Pipfile Pipfile.lock /tmp/

COPY bin/* /usr/bin/

WORKDIR /tmp

RUN apk upgrade --update-cache;                 \
    apk add                                     \
        bash                                    \
        curl                                    \
        coreutils                               \
        nmap                                    \
        file;                                   \
                                                \
    pip install pipenv;                         \
                                                \
    pipenv install --system --deploy;

ENTRYPOINT ["/usr/bin/kapow"]

Finally we will build the image of Kapow! with the Dockerfile that we just modified:

> docker build -t kapow .

Running the API

Once we have built our Docker image, we need our nmap.pow file we created earlier and launch Kapow:

> ls
nmap.pow
> docker run -p 8080:8080 -it -v "$(pwd)/":/tmp kapow server /tmp/nmap/nmap.pow
======== Running on http://0.0.0.0:8080 ========
(Press CTRL+C to quit)
Route created GET /list/{ip}
ROUTE_545919aa_9b5e_452c_bc92_002061aa5003
bash-4.4#

What we have done:

  1. Put our service listening at port 8080.
  2. Since the Docker image has not included the nmap.pow file, we need to “mount” it from the host, with the -v command. The first $(pwd) parameter tells Docker mount the current directory in the /tmp directory inside the Docker container.
  3. We run the server with the server command
  4. We indicate Kapow! the definition file which we assembled from outside the Docker container.

Testing the API

Now we’ll try our API. In this case we will use Curl to launch a scan against our loopback: 127.0.0.1

> curl -v http://localhost:8080/scan/127.0.0.1
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /list/127.0.0.1 HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Length: 168
< Content-Type: application/octet-stream
< Date: Fri, 21 Jun 2019 13:35:48 GMT
< Server: Python/3.7 aiohttp/3.5.4
<
Starting Nmap 7.70 ( https://nmap.org ) at 2019-06-21 13:35 UTC
Nmap scan report for localhost (127.0.0.1)
Nmap done: 1 IP address (0 hosts up) scanned in 0.00 seconds
* Connection #0 to host localhost left intact

Conclusions

Although we are aware that the project is at an early stage, the potential it has is enormous.

Imagine performing an entire security audit with a Postman. It sounds great, right?

Finally, I would like to leave you with a question:

What do you think about the idea of Kapow! and what use cases do you think of?

Crear APIs REST para herramientas de hacking

De qué va este post?

En este post hablaré sobre cómo crear APIs REST para herramientas de hacking y cómo lograr hacerlo en 5 minutos.

Pero, cuál es el problema realmente?

El problema que hoy os presento trata de resolver varios pequeños problemas. Os los planteo como preguntas:

  • Nunca habéis tenido que analizar un entorno en el que era muy complicado tener acceso a una máquina de salto?
  • Necesitáis dejar acceso a solamente cierto comandos en un sistema en concreto?
  • Más aún: necesitáis delegar el acceso a un comando, permitiendo SOLO ciertos parámetros del comando?
  • No sería genial poder hacer una auditoría haciendo llamando a curl o wget?

Pues este problema lo hemos tenido muchos. Precisamente por este motivo, en mi departamento de BBVA-Labs hemos estado trabajando en un juguete bastante chulo.

Echa un vistazo a los proyectos de BBVA-Labs

La idea es muy simple:

Dado script de linea de comandos, poder crear una API REST en cuestión de minutos.

A este proyecto le dimos el nombre de Kapow! y mis compañeros escogieron un logo bastante chulo 🙂

Si bien el proyecto todavía está en beta ya es usable. La idea del proyecto siempre me ha parecido muy potente y emocionante (y por eso estoy escribiendo este post :D)

Echa un vistazo al Github de Kapow!

Crear una API para nmap en 5 minutos

Funcionamiento en 1 imagen

Para que quede claro el concepto, los que realmente hace Kapow! es la magia de crear la API REST, dado un comando:

Definir la API

Para que Kapow! sepa cómo tiene que crear la API, tendremos que crear un fichero .pow con las instrucciones. No os asustéis, es muy sencillo:

# nmap.pow

kapow route add -X GET '/scan/{ip}' -c 'nmap -sL $(request /matches/ip) | response /body'

Analicemos el fichero. Veis que es muy sencillo:

  1. Creamos una nueva API con una ruta: /scan/{ip}, dónde IP es el target a analizar, establecido como parámetro de entrada.
  2. -c ‘nmap…’: de esta manera le indicamos a Kapow! el comando a ejecutar.
  3. $(request /matches/ip): así es como le decimos a Kapow! que, de la petición recibida, queremos utilizar la variable “ip” pasada como parámetro en la API.
  4. response /body: así es como le decimos a Kapow! que devuelva el resultado de la ejecución del comando en la respuesta HTTP.

Construcción de Kapow!

Dado que el proyecto todavía está beta, tendremos que construir Kapow! nosotros mismos. Nos os asustéis. Es muy fácil.

En primer lugar clonaremos el repositorio:

> git clone -b develop https://github.com/BBVA/kapow.git
> cd poc/

Cuidado al hacer el clone. La rama a clonar es la develop!!

En primer lugar tendremos que añadir una linea al Dockerfile original, que se encuentra en directorio /poc/Dockerfile. Lo que necesitamos añadir es la instalación del nmap.

El Dockerfile resultante debe de quedarnos así:

FROM python:3.7-alpine

COPY Pipfile Pipfile.lock /tmp/

COPY bin/* /usr/bin/

WORKDIR /tmp

RUN apk upgrade --update-cache;                 \
    apk add                                     \
        bash                                    \
        curl                                    \
        coreutils                               \
        nmap                                    \
        file;                                   \
                                                \
    pip install pipenv;                         \
                                                \
    pipenv install --system --deploy;

ENTRYPOINT ["/usr/bin/kapow"]

Finalmente construiremos la imagen de Kapow! con el Dockerfile que hemos modificado:

> docker build -t kapow .

Ejecutar la API

Una vez construido nuestra imagen Docker, ya solo necesitamos tener a mano el fichero nmap.pow que creamos más arriba y lanzar Kapow:

> ls
nmap.pow
> docker run -p 8080:8080 -it -v "$(pwd)/":/tmp kapow server /tmp/nmap/nmap.pow
======== Running on http://0.0.0.0:8080 ========
(Press CTRL+C to quit)
Route created GET /list/{ip}
ROUTE_545919aa_9b5e_452c_bc92_002061aa5003
bash-4.4#

Qué hemos hecho:

  1. Ponemos a escuchar nuestro servicio en el puerto 8080.
  2. Puesto que la imagen de Docker no tiene incluido dentro el fichero de nmap.pow, lo hemos “montado” desde fuera, con el comando -v. El primer parámetro $(pwd), le indica a Docker que monte el directorio actual en el directorio /tmp de dentro de contenedor de Docker.
  3. Ejecutamos el servidor con el comando server
  4. Le indicamos la ubicación de nuestro fichero de definición de Kapow! que, recordar, lo montamos desde fuera del contenedor de Docker.

Probar la API

Ahora ya solo queda probar nuestra API. En este caso vamos a usar Curl para lanzar un escaneo contra nuestro loopback: 127.0.0.1

> curl -v http://localhost:8080/scan/127.0.0.1
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /list/127.0.0.1 HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Length: 168
< Content-Type: application/octet-stream
< Date: Fri, 21 Jun 2019 13:35:48 GMT
< Server: Python/3.7 aiohttp/3.5.4
<
Starting Nmap 7.70 ( https://nmap.org ) at 2019-06-21 13:35 UTC
Nmap scan report for localhost (127.0.0.1)
Nmap done: 1 IP address (0 hosts up) scanned in 0.00 seconds
* Connection #0 to host localhost left intact

Conclusiones

Aunque somos conscientes de que el proyecto está en una fase temprana, el potencial que tiene es enorme.

Imaginaros poder realizar toda una auditoria con un Postman. No se a vosotros, pero a mi me parece espectacular.

Finalmente, me gustaría dejaros una pregunta abierta:

¿Qué os parece la idea de Kapow! y qué casos de uso se os ocurren?

Hasta la próxima!