Decker – Declarative Penetration Testing Orchestration Framework

Decker - Declarative Penetration Testing Orchestration Framework

Decker is a penetration testing orchestration framework. It leverages HashiCorp Configuration Language 2 (the identical config language as Terraform) to permit declarative penetration testing as code, so your checks could be versioned, shared, reused, and collaborated on together with your staff or the group.

Example of a decker config file:

// variables are pulled from surroundings
// they are going to be out there all through the config recordsdata as var.*
//   ex: ${var.target_host}
variable "target_host" {
  sort = "string"

// assets discuss with plugins
// assets want distinctive names so plugins can be utilized greater than as soon as
// they're declared with the shape: 'useful resource "plugin_name" "unique_name" {}'
// their outputs can be out there to others utilizing the shape unique_name.*
//   ex: nmap.443
useful resource "nmap" "nmap" {
  host = "${var.target_host}"
  plugin_enabled = "true"
useful resource "sslscan" "sslscan" {
  host = "${var.target_host}"
  plugin_enabled = "${nmap.443 == "open"}"

Run a plugin for every merchandise in an inventory:

variable "target_host" {
  sort = "string"
useful resource "nslookup" "nslookup" {
  dns_server = ""
  host = "${var.target_host}"
useful resource "metasploit" "metasploit" {
  for_each = "${nslookup.ip_address}"
  exploit = "auxiliary/scanner/portscan/tcp"
  choices = {
    RHOSTS = "${each.key}/32"
    INTERFACE = "eth0"

Complex configuration combining for_each with nested values:

variable "target_host" {
  sort = "string"
useful resource "nslookup" "nslookup" {
  dns_server = ""
  host = "${var.target_host}"
useful resource "nmap" "nmap" {
  for_each = "${nslookup.ip_address}"
  host = "${each.key}"
// for every IP, test if nmap discovered port 25 open.
// if sure, run metasploit's smtp_enum scanner
useful resource "metasploit" "metasploit" {
  for_each = "${nslookup.ip_address}"
  exploit = "auxiliary/scanner/smtp/smtp_enum"
  choices = {
    RHOSTS = "${each.key}"
  plugin_enabled = "${nmap["${each.key}"].25 == "open"}"

Output codecs
Several output codecs can be found and multiple could be chosen on the identical time.
Setting DECKER_OUTPUTS_JSON or DECKER_OUTPUTS_XML to "true" will output json and xml formatted recordsdata respectively.

  1. Output .json recordsdata along with plain textual content: export DECKER_OUTPUTS_JSON="true"
  2. Output .xml recordsdata along with plain textual content: export DECKER_OUTPUTS_XML="true"

Why the title decker?
My pal Courtney got here to the rescue after I was struggling to give you a reputation and located decker in a SciFi word glossary… and it sounded cool.

A future cracker; a software program knowledgeable expert at manipulating our on-line world, particularly at circumventing safety precautions.

Running an instance config with docker
Two volumes are mounted:

  1. Directory named decker-stories the place decker will output a file for every plugin executed. The file’s title can be {unique_resource_name}.report.txt.
  2. examples listing containing decker config recordsdata. Mounting this quantity means that you can write configs domestically utilizing your favourite editor and nonetheless run them inside the container.

One surroundings variable is handed in:


This is referenced within the config recordsdata as {var.target_host}. Decker will loop via all surroundings variables named DECKER_*, stripping away the prefix and setting the remainder to lowercase.

docker run -it --rm 
  -v "$(pwd)/decker-reports/":/tmp/stories/ 
  -v "$(pwd)/examples/":/decker-config/ 
 stevenaldinger/decker:kali decker ./decker-config/instance.hcl

When decker finishes operating the config, look in ./decker-stories for the outputs.

Running an instance config with out docker
You’ll probably wish to set the listing decker writes stories to with the DECKER_REPORTS_DIR surroundings variable.
Something like this may be acceptable. Just make sure that no matter you set it to is an current listing.

export DECKER_REPORTS_DIR="$HOME/decker-reports"

You’ll additionally have to set a goal host should you’re operating one of many instance config recordsdata.

export DECKER_TARGET_HOST="<insert hostname here>"

Then simply run a config file. Change to the foundation listing of this repo and run:

./decker ./examples/instance.hcl

Contributions are very welcome and appreciated. See docs/ for tips.

Using docker for improvement is really helpful for a clean expertise. This ensures all dependencies can be put in and able to go.
Refer to Directory Structure beneath for an summary of the go code.

Quick Start

  1. (on host machine): make docker_build
  2. (on host machine): make docker_run (will begin docker container and open an interactive bash session)
  3. (inside container): dep guarantee -v
  4. (inside container): make build_all
  5. (inside container): make run

Initialize git hooks
Run make init so as to add a pre-commit script that can run linting and checks on every commit.

Plugin Development
Decker itself is only a framework that reads config recordsdata, determines dependencies within the config recordsdata, and runs plugins in an order that ensures plugins with dependencies on different plugins (output of 1 plugin being an enter for an additional) run after those they depend upon.
The actual energy of decker comes from plugins. Developing a plugin could be as easy or as advanced as you need it to be, so long as the tip result’s a .so file containing the compiled plugin code and a .hcl file in the identical listing declaring the inputs the plugin is anticipating a consumer to configure.
The really helpful option to get began with decker plugin improvement is by cloning the decker-plugin repository and following the steps in its documentation. It ought to solely take you a couple of minutes to get a “Hello World” decker plugin operating.

Installing plugins
By default, plugins are anticipated to be in a listing relative to wherever the decker binary is, at <decker binary>/inner/app/decker/plugins/<plugin title>/<plugin title>.so. Additional paths could be added by setting the DECKER_PLUGIN_DIRS surroundings variable. The default plugin path will nonetheless be used if DECKER_PLUGIN_DIRS is ready.
Example: export DECKER_PLUGIN_DIRS="/path/to/my/plugins:/additional/path/to/plugins"
There ought to be an HCL file subsequent to the .so file at <decker binary>/inner/app/decker/plugins/<plugin title>/<plugin title>.hcl that defines its inputs and outputs. Currently, solely string, checklist, and map inputs are supported. Each enter ought to have an enter block that appears like this:

enter "my_input" {
  sort = "string"
  default = "some default value"

Directory Structure

├── construct
│   ├── ci/
│   └── package deal/
├── cmd
│   ├── decker
│   │   └── foremost.go
│   └──
├── deployments/
├── docs/
├── examples
│   └── instance.hcl
├── githooks
│   ├── pre-commit
├── Gopkg.toml
├── inner
│   ├── app
│   │   └── decker
│   │       └── plugins
│   │           ├── a2sv
│   │           │   ├── a2sv.hcl
│   │           │   ├── foremost.go
│   │           │   └──
│   │           └── ...
│   │               ├── foremost.go
│   │               ├──
│   │               └── xxx.hcl
│   ├── pkg
│   │   ├── dependencies/
│   │   ├── gocty/
│   │   ├── hcl/
│   │   ├── paths/
│   │   ├── plugins/
│   │   └── stories/
│   └──
├── Makefile
└── scripts
  • cmd/decker/main.go is the motive force. Its job is to parse a given config file, load the suitable plugins based mostly on the file’s useful resource blocks, and run the plugins with the required inputs.
  • examples has a pair instance configurations to get you began with decker. If you employ the kali docker image (stevenaldinger/decker:kali), all dependencies ought to be put in for all config recordsdata and issues ought to run easily.
  • internal/pkg is the place many of the precise code is. It comprises all of the packages imported by main.go.
    • dependencies is liable for constructing the plugin dependency graph and returning a topologically sorted array that ensures plugins are run in a working order.
    • gocty affords helpers for encoding and decoding go-cty values that are used to deal with dynamic enter sorts.
    • hcl is liable for parsing HCL recordsdata, together with creating analysis contexts that allow blocks correctly decode once they depend upon different plugin blocks.
    • paths is liable for returning file paths for the decker binary, config recordsdata, plugin config recordsdata, and generated stories.
    • plugins is liable for figuring out if plugins are enabled and operating them.
    • reports is liable for writing stories to the file system.
  • internal/app/decker/plugins are modular items of code written as Golang plugins, implementing a easy interface that permits them to be loaded and known as at run-time with inputs and outputs specified within the plugin’s config file (additionally in HCL). An instance could be discovered at internal/app/decker/plugins/nslookup/nslookup.hcl.
  • decker config files supply a declarative option to write penetration checks. The manifests are written in HashiCorp Configuration Language 2) and describe the set of plugins for use within the check in addition to their inputs.


Please enter your comment!
Please enter your name here

This site uses Akismet to reduce spam. Learn how your comment data is processed.