Decker - Declarative Penetration Testing Orchestration Framework


Decker is a penetration testing orchestration framework. It leverages HashiCorp Configuration Language 2 (the same config linguistic communication every bit Terraform) to allow declarative penetration testing every bit code, too thus your tests tin hold upward versioned, shared, reused, too collaborated on amongst your squad or the community.

Example of a decker config file:
// variables are pulled from environs //   ex: DECKER_TARGET_HOST // they volition hold upward available throughout the config files every bit var.* //   ex: ${var.target_host} variable "target_host" {   type = "string" }  // resources refer to plugins // resources demand unique names too thus plugins tin hold upward used to a greater extent than than in 1 lawsuit // they are declared amongst the form: 'resource "plugin_name" "unique_name" {}' // their outputs volition hold upward available to others using the shape unique_name.* //   ex: nmap.443 resources "nmap" "nmap" {   host = "${var.target_host}"   plugin_enabled = "true" } resources "sslscan" "sslscan" {   host = "${var.target_host}"   plugin_enabled = "${nmap.443 == "open"}" }
Run a plugin for each particular inwards a list:
variable "target_host" {   type = "string" } resources "nslookup" "nslookup" {   dns_server = "8.8.4.4"   host = "${var.target_host}" } resources "metasploit" "metasploit" {   for_each = "${nslookup.ip_address}"   exploit = "auxiliary/scanner/portscan/tcp"   options = {     RHOSTS = "${each.key}/32"     INTERFACE = "eth0"   } }
Complex configuration combining for_each amongst nested values:
variable "target_host" {   type = "string" } resources "nslookup" "nslookup" {   dns_server = "8.8.4.4"   host = "${var.target_host}" } resources "nmap" "nmap" {   for_each = "${nslookup.ip_address}"   host = "${each.key}" } // for each IP, banking concern stand upward for if nmap constitute port 25 open. // if yes, run metasploit's smtp_enum scanner resources "metasploit" "metasploit" {   for_each = "${nslookup.ip_address}"   exploit = "auxiliary/scanner/smtp/smtp_enum"   options = {     RHOSTS = "${each.key}"   }   plugin_enabled = "${nmap["${each.key}"].25 == "open"}" }

Output formats
Several output formats are available too to a greater extent than than 1 tin hold upward selected at the same time.
Setting DECKER_OUTPUTS_JSON or DECKER_OUTPUTS_XML to "true" volition output json too xml formatted files respectively.
  1. Output .json files inwards add-on to apparently text: export DECKER_OUTPUTS_JSON="true"
  2. Output .xml files inwards add-on to apparently text: export DECKER_OUTPUTS_XML="true"

Why the cite decker?
My friend Courtney came to the rescue when I was struggling to come upward up amongst a cite too constitute decker inwards a SciFi give-and-take glossary... too it sounded cool.
H5N1 futurity cracker; a software goodness skilled at manipulating cyberspace, peculiarly at circumventing safety precautions.

Running an instance config amongst docker
Two volumes are mounted:
  1. Directory named decker-reports where decker volition output a file for each plugin executed. The file's cite volition hold upward {unique_resource_name}.report.txt.
  2. examples directory containing decker config files. Mounting this book allows you lot to write configs locally using your favorite editor too nonetheless run them within the container.
One environs variable is passed in:
  1. DECKER_TARGET_HOST
This is referenced inwards the config files every bit {var.target_host}. Decker volition loop through all environs variables named DECKER_*, stripping away the prefix too setting the residuum to lowercase.
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
When decker finishes running the config, aspect inwards ./decker-reports for the outputs.

Running an instance config without docker
You'll probable desire to laid the directory decker writes reports to amongst the DECKER_REPORTS_DIR environs variable.
Something similar this would hold upward appropriate. Just brand certain whatsoever you lot laid it to is an existing directory.
export DECKER_REPORTS_DIR="$HOME/decker-reports"
You'll every bit good demand to laid a target host if you're running 1 of the instance config files.
export DECKER_TARGET_HOST=""
Then only run a config file. Change to the root directory of this repo too run:
./decker ./examples/example.hcl

Contributing
Contributions are really welcome too appreciated. See docs/contributions.md for guidelines.

Development
Using docker for evolution is recommended for a shine experience. This ensures all dependencies volition hold upward installed too ready to go.
Refer to Directory Structure below for an overview of the larn code.

Quick Start
  1. (on host machine): make docker_build
  2. (on host machine): make docker_run (will source docker container too opened upward an interactive bash session)
  3. (inside container): dep ensure -v
  4. (inside container): make build_all
  5. (inside container): make run

Initialize git hooks
Run make init to add together a pre-commit script that volition run linting too tests on each commit.

Plugin Development
Decker itself is only a framework that reads config files, determines dependencies inwards the config files, too runs plugins inwards an club that ensures plugins amongst dependencies on other plugins (output of 1 plugin beingness an input for another) run subsequently the ones they depend on.
The existent ability of decker comes from plugins. Developing a plugin tin hold upward every bit elementary or every bit complex every bit you lot desire it to be, every bit long every bit the halt number is a .so file containing the compiled plugin code too a .hcl file inwards the same directory declaring the inputs the plugin is expecting a user to configure.
The recommended means to larn started amongst decker plugin evolution is past times cloning the decker-plugin repository too next the steps inwards its documentation. It should solely stimulate got you lot a few minutes to larn a "Hello World" decker plugin running.

Installing plugins
By default, plugins are expected to hold upward inwards a directory relative to wherever the decker binary is, at /internal/app/decker/plugins//.so. Additional paths tin hold upward added past times setting the DECKER_PLUGIN_DIRS environs variable. The default plugin path volition nonetheless hold upward used if DECKER_PLUGIN_DIRS is set.
Example: export DECKER_PLUGIN_DIRS="/path/to/my/plugins:/additional/path/to/plugins"
There should hold upward an HCL file side past times side to the .so file at /internal/app/decker/plugins//.hcl that defines its inputs too outputs. Currently, solely string, list, too map inputs are supported. Each input should stimulate got an input block that looks similar this:
input "my_input" {   type = "string"   default = "some default value" }

Directory Structure
. ├── construct │   ├── 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
  • cmd/decker/main.go is the driver. Its project is to parse a given config file, charge the appropriate plugins based on the file's resource blocks, too run the plugins amongst the specified inputs.
  • examples has a twosome instance configurations to larn you lot started amongst decker. If you lot purpose the kali docker image (stevenaldinger/decker:kali), all dependencies should hold upward installed for all config files too things should run smoothly.
  • internal/pkg is where almost of the actual code is. It contains all the packages imported past times main.go.
    • dependencies is responsible for edifice the plugin dependency graph too returning a topologically sorted array that ensures plugins are run inwards a working order.
    • gocty offers helpers for encoding too decoding go-cty values which are used to grip dynamic input types.
    • hcl is responsible for parsing HCL files, including creating evaluation contexts that permit blocks properly decode when they depend on other plugin blocks.
    • paths is responsible for returning file paths for the decker binary, config files, plugin config files, too generated reports.
    • plugins is responsible for determining if plugins are enabled too running them.
    • reports is responsible for writing reports to the file system.
  • internal/app/decker/plugins are modular pieces of code written every bit Golang plugins, implementing a elementary interface that allows them to hold upward loaded too called at run-time amongst inputs too outputs specified inwards the plugin's config file (also inwards HCL). An instance tin hold upward constitute at internal/app/decker/plugins/nslookup/nslookup.hcl.
  • decker config files offering a declarative means to write penetration tests. The manifests are written inwards HashiCorp Configuration Language 2) too line the laid of plugins to hold upward used inwards the attempt every bit good every bit their inputs.