
Marco declarativo de orquestación para pruebas de penetración
Decker es un marco de orquestación para pruebas de penetración. Utiliza HashiCorp Configuration Language 2 (el mismo lenguaje de configuración que Terraform) para permitir la prueba de penetración como código declarativa, de modo que tus pruebas puedan ser versionadas, compartidas, reutilizadas y colaboradas con tu equipo o la comunidad.
Ejemplo de un archivo de configuración de decker:
// las variables se obtienen del entorno
// ej: DECKER_TARGET_HOST
// estarán disponibles en todos los archivos de configuración como var.*
// ej: ${var.target_host}
variable "target_host" {
type = "string"
}
// los recursos hacen referencia a plugins
// los recursos necesitan nombres únicos para que los plugins puedan usarse más de una vez
// se declaran con la forma: 'resource "nombre_plugin" "nombre_unico" {}'
// sus salidas estarán disponibles para otros usando la forma nombre_unico.*
// ej: nmap.443
resource "nmap" "nmap" {
host = "${var.target_host}"
plugin_enabled = "true"
}
resource "sslscan" "sslscan" {
host = "${var.target_host}"
plugin_enabled = "${nmap.443 == "open"}"
}
Ejecuta un plugin para cada elemento de una lista:
variable "target_host" {
type = "string"
}
resource "nslookup" "nslookup" {
dns_server = "8.8.4.4"
host = "${var.target_host}"
}
resource "metasploit" "metasploit" {
for_each = "${nslookup.ip_address}"
exploit = "auxiliary/scanner/portscan/tcp"
options = {
RHOSTS = "${each.key}/32"
INTERFACE = "eth0"
}
}
Configuración compleja que combina for_each con valores anidados:
variable "target_host" {
type = "string"
}
resource "nslookup" "nslookup" {
dns_server = "8.8.4.4"
host = "${var.target_host}"
}
resource "nmap" "nmap" {
for_each = "${nslookup.ip_address}"
host = "${each.key}"
}
// para cada IP, comprueba si nmap encontró el puerto 25 abierto.
// si es así, ejecuta el escáner smtp_enum de metasploit
resource "metasploit" "metasploit" {
for_each = "${nslookup.ip_address}"
exploit = "auxiliary/scanner/smtp/smtp_enum"
options = {
RHOSTS = "${each.key}"
}
plugin_enabled = "${nmap["${each.key}"].25 == "open"}"
}
Hay varios formatos de salida disponibles y se puede seleccionar más de uno al mismo tiempo.
Establecer DECKER_OUTPUTS_JSON o DECKER_OUTPUTS_XML a "true" generará archivos formateados en json y xml respectivamente.
.json además de texto plano: export DECKER_OUTPUTS_JSON="true".xml además de texto plano: export DECKER_OUTPUTS_XML="true"Mi amiga Courtney vino al rescate cuando tenía problemas para encontrar un nombre y encontró decker en un glosario de palabras de ciencia ficción... y sonaba bien.
Un cracker del futuro; un experto en software hábil en manipular el ciberespacio, especialmente en sortear las precauciones de seguridad.
Se montan dos volúmenes:
decker-reports donde decker generará un archivo para cada plugin ejecutado. El nombre del archivo será {unique_resource_name}.report.txt.examples que contiene los archivos de configuración de decker. Montar este volumen te permite escribir configuraciones localmente usando tu editor favorito y aún así ejecutarlas dentro del contenedor.Se pasa una variable de entorno:
DECKER_TARGET_HOSTA esto se hace referencia en los archivos de configuración como {var.target_host}. Decker recorrerá todas las variables de entorno llamadas DECKER_*, eliminando el prefijo y estableciendo el resto en minúsculas.
docker run -it --rm \
-v "$(pwd)/decker-reports/":/tmp/reports/ \
-v "$(pwd)/examples/":/decker-config/ \
-e DECKER_TARGET_HOST=example.com \
stevenaldinger/decker:kali decker ./decker-config/example.hcl
Cuando decker termine de ejecutar la configuración, busca en ./decker-reports las salidas.
Probablemente querrás establecer el directorio donde decker escribe los informes con la variable de entorno DECKER_REPORTS_DIR.
Algo como esto sería apropiado. Solo asegúrate de que lo que establezcas sea un directorio existente.
export DECKER_REPORTS_DIR="$HOME/decker-reports"
También necesitarás establecer un host objetivo si estás ejecutando uno de los archivos de configuración de ejemplo.
export DECKER_TARGET_HOST="<inserta el nombre de host aquí>"
Luego simplemente ejecuta un archivo de configuración. Cambia al directorio raíz de este repositorio y ejecuta:
./decker ./examples/example.hcl
Las contribuciones son muy bienvenidas y apreciadas. Consulta docs/contributions.md para conocer las pautas.
Se recomienda usar Docker para el desarrollo para una experiencia fluida. Esto asegura que todas las dependencias estarán instaladas y listas.
Consulta Estructura de directorios a continuación para obtener una visión general del código Go.
make docker_buildmake docker_run (iniciará el contenedor Docker y abrirá una sesión interactiva de bash)dep ensure -vmake build_allmake runEjecuta make init para añadir un script pre-commit que ejecutará linting y pruebas en cada commit.
Decker en sí mismo es solo un marco que lee archivos de configuración, determina las dependencias en los archivos de configuración y ejecuta los plugins en un orden que asegura que los plugins con dependencias de otros plugins (salida de un plugin como entrada de otro) se ejecuten después de aquellos de los que dependen.
El verdadero poder de decker proviene de los plugins. Desarrollar un plugin puede ser tan simple o complejo como quieras, siempre que el resultado final sea un archivo .so que contenga el código del plugin compilado y un archivo .hcl en el mismo directorio que declare las entradas que el plugin espera que el usuario configure.
Consulta docs/building_plugins.md para comenzar con tu primer plugin. Solo te llevará unos minutos tener un plugin "Hello World" de decker funcionando.
Por defecto, se espera que los plugins estén en un directorio relativo a donde se encuentra el binario de decker, en <binario de decker>/internal/app/decker/plugins/<nombre del plugin>/<nombre del plugin>.so. Se pueden añadir rutas adicionales estableciendo la variable de entorno DECKER_PLUGIN_DIRS. La ruta de plugin predeterminada seguirá utilizándose si se establece DECKER_PLUGIN_DIRS.
Ejemplo: export DECKER_PLUGIN_DIRS="/ruta/a/mis/plugins:/ruta/adicional/a/plugins"
Debe haber un archivo HCL junto al archivo .so en <binario de decker>/internal/app/decker/plugins/<nombre del plugin>/<nombre del plugin>.hcl que defina sus entradas y salidas. Actualmente, solo se admiten entradas de tipo string, list y map. Cada entrada debe tener un bloque input que se vea así:
input "mi_entrada" {
type = "string"
default = "algún valor por defecto"
}
.
├── build
│ ├── ci/
│ └── package/
├── cmd
│ ├── decker
│ │ └── main.go
│ └── README.md
├── deployments/
├── docs/
├── examples
│ └── example.hcl
├── githooks
│ ├── pre-commit
├── Gopkg.toml
├── internal
│ ├── app
│ │ └── decker
│ │ └── plugins
│ │ ├── a2sv
│ │ │ ├── a2sv.hcl
│ │ │ ├── main.go
│ │ │ └── README.md
│ │ └── ...
│ │ ├── main.go
│ │ ├── README.md
│ │ └── xxx.hcl
│ ├── pkg
│ │ ├── dependencies/
│ │ ├── gocty/
│ │ ├── hcl/
│ │ ├── paths/
│ │ ├── plugins/
│ │ └── reports/
│ └── README.md
├── LICENSE
├── Makefile
├── README.md
└── scripts
├── build-plugins.sh
└── README.md
resource del archivo, y ejecutar los plugins con las entradas especificadas.decker. Si usas la imagen docker de kali (stevenaldinger/decker:kali), todas las dependencias deberían estar instaladas para todos los archivos de configuración y todo debería funcionar sin problemas.decker