Joven hacker sonriendo

Cero falsos positivos

Inteligencia experta + automatización eficaz

Asserts

1. Descripción

Asserts es un motor de automatización de cierre de hallazgos de seguridad sobre ambientes en ejecución (DAST).

Asserts
Figura 1. Caso de uso

2. Instalación

Asserts está alojado PyPI, de modo que puedes instalarlo fácilmente utiizando pip3 en un sistema con Python3:

asserts installation
1
$ pip3 install -U fluidasserts

Para uso normal o interactivo se debe configurar la variable FA_STRICT a false en sistemas operativos similares a UNIX (como se muestra a continuación):

1
$ export FA_STRICT="false"

En Windows:

1
> set FA_STRICT="false"

Ahora, estás listo para empezar con las pruebas de cierre de vulnerabilidades.

Instalación en un contenedor de Docker

Si tienes Docker puedes descargar y ejecutar Asserts dentro de un contenedor, para ello ejecuta el siguiente comando:

1
$ docker pull fluidattacks/asserts

Y luego entra al contenedor:

1
2
3
4
5
6
7
8
$ docker run -it fluidattacks/asserts sh
/ # asserts

#  ___
# | >>|> fluid
# |___|  attacks, we hack your software
#
# Loading attack modules ...

Es necesario asegurarse de realizar el docker pull antes de cada ejecución del contenedor para asegurar que se está utilizando la versión más reciente de Asserts.

Una vez dentro del contenedor es posible ejecutar Asserts desde el shell interactivo de Python o contruir rápidamente un script utilizando vi. Pero sería mucho más útil montar el directorio donde se localiza el exploit en el contenedor.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
$ docker run -v /home/me/myexploits/:/exploits/ -it fluidattacks/asserts sh
/ # asserts /exploits/open-sqli.py

#  ___
# | >>|> fluid
# |___|  attacks, we hack your software
#
# Loading attack modules ...

check: fluidasserts.proto.http.has_sqli
status: OPEN
message: A bad text was present
details:
  bad_text: Warning.*mysql_.*
  fingerprint:
    banner: "Server: nginx/1.4.1\r\nContent-Type: text/xml\r\nTransfer-Encoding: chunked\r\
      \nConnection: keep-alive\r\nX-Powered-By: PHP/5.3.10-1~lucid+2uwsgi2"
    sha256: 588702eb0b53294654f934d86664956e9739db47c34ffd8d703550cd5fd670a0
  url: http://testphp.vulnweb.com/AJAX/infoartist.php?id=3%27
when: 2018-09-06 08:33:08.781518

Uso en un pipeline de integración continua (CI)

Si tienes una aplicación suscrita a nuestro servicio de hacking continuo el cual incluye el uso de Asserts, es posible integrarlo en tu pipeline de CI para garantizar que tu software se construya y entregue sin vulnerabilidades abiertas. Entregaremos un contenedor Docker personalizado con las pruebas específicas necesarias para mantener la ruptura de builds con el exploit.

Para lograr esto, sigue los siguientes pasos:

  1. Agrega las variables de entorno requeridas: FA_ORG, FA_PROJECT, FA_${FA_PROJECT}_USER y FA_${FA_PROJECT}_PASS. No te preocupes, los valores serán entregados por nosotros!:

    • FA_ORG: El nombre de la organización.

    • FA_PROJECT: El nombre de la aplicación suscrita a hacking continuou.

    • FA_${FA_PROJECT}_USER: Nombre del usuario de nuestro Container Registry.

    • FA_${FA_PROJECT}_PASS: La contraseña del usuario.

      Por ejemplo, en Gitlab,y asumiendo FA_ORG=FLUIDATTACKS y FA_PROJECT=BWAPP, el entorno del pipeline podría verse así verse así:

      Variables de entorno de Gitlab
  2. Agrega un job para ejecutar Asserts. Por ejemplo en Gitlab, agregarías estos comandos a tu archivo .gitlab-ci.yml:

    asserts in gitlab
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    fluidasserts-static:
      script:
        - export STAGE="${FA_PROJECT}_static"
        - docker login fluid-docker.jfrog.io
            -u "$FA_BWAPP_USER"
            -p "$FA_BWAPP_PASS"
        - docker pull fluid-docker.jfrog.io/"$FA_ORG":"$STAGE"
        - docker run
            -e USER="$FA_BWAPP_USER"
            -e PASS="$FA_BWAPP_PASS"
            -e FA_STRICT=true
            -v "$PWD":/code
            fluid-docker.jfrog.io/"$FA_ORG":"$STAGE"
        - docker logout fluid-docker.jfrog.io
    
    fluidasserts-dynamic:
        - export STAGE="${FA_PROJECT}_dynamic"
        - docker login fluid-docker.jfrog.io
            -u "$FA_BWAPP_USER"
            -p "$FA_BWAPP_PASS"
        - docker pull fluid-docker.jfrog.io/"$FA_ORG":"$STAGE"
        - docker run
            -e USER="$FA_BWAPP_USER"
            -e PASS="$FA_BWAPP_PASS"
            -e FA_STRICT=true
            fluid-docker.jfrog.io/"$FA_ORG":"$STAGE"
        - docker logout fluid-docker.jfrog.io
    
  3. A partir de ahora, tu pipeline fallará si se encuentra alguna vulnerabilidades abierta, sea sobre el código fuente, o sobre el ambiente de producción/pruebas. Para evitar romper el build pero aún así ejecutar las pruebas, cambia el valor de la variable FA_STRICT a false.

Etapas CI

De acuerdo, estoy interesado. Pero en qué etapa debería probar mi aplicación con Asserts ? Existen al menos 3 buenos momentos para ejecutar una prueba de cierre:

  1. Luego de desplegar al ambiente de producción.

  2. Luego de desplegar a un ambiente efímero o real.

  3. Incluso luego de cada commit !

Post-producción

Al igual que antes, iniciamos sesión en el repositorio de artefactos, actualizamos la imagen personalizada, y la ejecutamos con Docker. Esta vez, sin embargo, vale aclarar que el job se ejecuta únicamente sobre la rama master, y en una de las últimas etapas del pipeline, post-deploy. El código fuente de esta rama se enlaza al contenedor por medio de un volumen en la carpeta /code debiado a que éste se encuentra configurado para probar esta carpeta.

post-deploy
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
fluidasserts-static:
  stage: post-deploy
  script:
    - export STAGE="${FA_PROJECT}_static"
    - docker login fluid-docker.jfrog.io
        -u "$FA_BWAPP_USER"
        -p "$FA_BWAPP_PASS"
    - docker pull fluid-docker.jfrog.io/"$FA_ORG":"$STAGE"
    - docker run
        -e USER="$FA_BWAPP_USER"
        -e PASS="$FA_BWAPP_PASS"
        -e FA_STRICT=true
        -v "$PWD":/code
        fluid-docker.jfrog.io/"$FA_ORG":"$STAGE"
    - docker logout fluid-docker.jfrog.io
  only:
    - master

fluidasserts-dynamic:
  stage: post-deploy
    - export STAGE="${FA_PROJECT}_dynamic"
    - docker login fluid-docker.jfrog.io
        -u "$FA_BWAPP_USER"
        -p "$FA_BWAPP_PASS"
    - docker pull fluid-docker.jfrog.io/"$FA_ORG":"$STAGE"
    - docker run
        -e USER="$FA_BWAPP_USER"
        -e PASS="$FA_BWAPP_PASS"
        -e FA_STRICT=true
        fluid-docker.jfrog.io/"$FA_ORG":"$STAGE"
    - docker logout fluid-docker.jfrog.io
  only:
    - master

Post-efímero

Pero espera! podemos evitar algunos bugs antes de realizar el despliegue a producción. Si utilizas ambientes efímeros, también puedes ejecutar pruebas de cierre en éstos:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
fluidasserts-static:
  stage: test
  script:
    - export STAGE="${FA_PROJECT}_static"
    - docker login fluid-docker.jfrog.io
        -u "$FA_BWAPP_USER"
        -p "$FA_BWAPP_PASS"
    - docker pull fluid-docker.jfrog.io/"$FA_ORG":"$STAGE"
    - docker run
        -e USER="$FA_BWAPP_USER"
        -e PASS="$FA_BWAPP_PASS"
        -e FA_STRICT=true
        -v "$PWD":/code
        fluid-docker.jfrog.io/"$FA_ORG":"$STAGE"
    - docker logout fluid-docker.jfrog.io
  except:
    - master

fluidasserts-dynamic:
  stage: test
    - export STAGE="${FA_PROJECT}_dynamic"
    - docker login fluid-docker.jfrog.io
        -u "$FA_BWAPP_USER"
        -p "$FA_BWAPP_PASS"
    - docker pull fluid-docker.jfrog.io/"$FA_ORG":"$STAGE"
    - docker run
        -e USER="$FA_BWAPP_USER"
        -e PASS="$FA_BWAPP_PASS"
        -e FA_STRICT=true
        fluid-docker.jfrog.io/"$FA_ORG":"$STAGE"
    - docker logout fluid-docker.jfrog.io
  except:
    - master

En contraste con el job anterior de post-despliegue, este corre en las ramas de desarrollo, durante la etapa de pruebas (test). Aparte de esto, todo lo demás sigue siendo igual, justo como iniciar un ambiente de producción espejo.

Pre-commit

Como desarrollador, puede que te estés preguntando: "¿Por qué debo esperar a que todas las etapas de CI terminen si solo quiero probar si mi ultimo commit reparó la brecha de seguridad?" Puedes ejecutar Asserts localmente en tu máquina, pero a veces algunos pequeños detalles (como las versiones de las dependencias) pueden causar que la prueba pase exitosamente de forma local pero falle en la integración continua. Recuerda que en este punto del desarrollo, no hay acceso a un ambiente dinámico para hacer pruebas, por lo que estás limitado únicamente a hacer pruebas estáticas sobre el código fuente.

En ese caso, puedes utilizar la versión Dockerizada de Asserts como un hook del pre-commit:

pre-commit
1
2
3
4
5
- id: asserts-docker
  name: Running Asserts on the code
  description: Run Asserts to perform SAST
  entry: -v /path/to/your/code/:/code fluidattacks/asserts:latest /code/asserts.sh
  language: docker_image

Esta configuración en particular funciona para la herramienta pre-commit pero puede ser adaptada a herramientas similares como overcommit. El uso de dichas herramientas es conveniente para el desarrollador, ya que las pruebas pueden ser ejecutadas rápidamente en sus máquinas con cada commit:

Pre-commit test passed
Pre-commit test failed

Las mismas pruebas pueden ser ejecutadas en tiempo de CI (por ejemplo, en una entapa de lint) para garantizar que nada se ha "roto" incluso si el desarrollador olvida ejecutarlo. Para ello sólo coloca la siguiente línea:

1
pre-commit run --all-files

En algún lugar de tu script de CI.


Estado de los servicios - Términos de Uso