Declarative penetration testing orchestration framework

Build Status

Decker - Penetration Testing Orchestration Framework

Purpose

Decker is a penetration testing orchestration framework. It leverages HashiCorp Configuration Language 2 (the same config language as Terraform) to allow declarative penetration testing as code, so your tests can be versioned, shared, reused, and collaborated on with your team or the community.

Example of a decker config file:

// variables are pulled from environment
//   ex: DECKER_TARGET_HOST
// they will be available throughout the config files as var.*
//   ex: ${var.target_host}
variable "target_host" {
  type = "string"
}

// resources refer to plugins
// resources need unique names so plugins can be used more than once
// they are declared with the form: 'resource "plugin_name" "unique_name" {}'
// their outputs will be available to others using the form unique_name.*
//   ex: nmap.443
resource "nmap" "nmap" {
  host = "${var.target_host}"
  plugin_enabled = "true"
}
resource "sslscan" "sslscan" {
  host = "${var.target_host}"
  plugin_enabled = "${nmap.443 == "open"}"
}

Run a plugin for each item in a list:

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"
  }
}

Complex configuration combining for_each with nested values:

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}"
}
// for each IP, check if nmap found port 25 open.
// if yes, run metasploit's smtp_enum scanner
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"}"
}

Output formats

Several output formats are available and more than one can be selected at the same time.

Setting DECKER_OUTPUTS_JSON or DECKER_OUTPUTS_XML to "true" will output json and xml formatted files respectively.

  1. Output .json files in addition to plain text: export DECKER_OUTPUTS_JSON="true"
  2. Output .xml files in addition to plain text: export DECKER_OUTPUTS_XML="true"

Why the name decker?

My friend Courtney came to the rescue when I was struggling to come up with a name and found decker in a SciFi word glossary... and it sounded cool.

A future cracker; a software expert skilled at manipulating cyberspace, especially at circumventing security precautions.

Running an example config with docker

Two volumes are mounted:

  1. Directory named decker-reports where decker will output a file for each plugin executed. The file's name will be {unique_resource_name}.report.txt.
  2. examples directory containing decker config files. Mounting this volume allows you to write configs locally using your favorite editor and still run them within the container.

One environment variable is passed in:

  1. DECKER_TARGET_HOST

This is referenced in the config files as {var.target_host}. Decker will loop through all environment variables named DECKER_*, stripping away the prefix and setting the rest 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, look in ./decker-reports for the outputs.

Running an example config without docker

You'll likely want to set the directory decker writes reports to with the DECKER_REPORTS_DIR environment variable.

Something like this would be appropriate. Just make sure whatever you set it to is an existing directory.

export DECKER_REPORTS_DIR="$HOME/decker-reports"

You'll also need to set a target host if you're running one of the example config files.

export DECKER_TARGET_HOST="<insert hostname here>"

Then just run a config file. Change to the root directory of this repo and run:

./decker ./examples/example.hcl

Contributing

Contributions are very welcome and appreciated. See docs/contributions.md for guidelines.

Development

Using docker for development is recommended for a smooth experience. This ensures all dependencies will be installed and ready to go.

Refer to Directory Structure below for an overview of the go code.

Quick Start

  1. (on host machine): make docker_build
  2. (on host machine): make docker_run (will start docker container and open 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 a pre-commit script that will run linting and tests on each commit.

Plugin Development

Decker itself is just a framework that reads config files, determines dependencies in the config files, and runs plugins in an order that ensures plugins with dependencies on other plugins (output of one plugin being an input for another) run after the ones they depend on.

The real power of decker comes from plugins. Developing a plugin can be as simple or as complex as you want it to be, as long as the end result is a .so file containing the compiled plugin code and a .hcl file in the same directory declaring the inputs the plugin is expecting a user to configure.

Check out docs/building_plugins.md to get started on your first plugin. It should only take you a few minutes to get a "Hello World" decker plugin running.

Installing plugins

By default, plugins are expected to be in a directory relative to wherever the decker binary is, at <decker binary>/internal/app/decker/plugins/<plugin name>/<plugin name>.so. Additional paths can be added by setting the DECKER_PLUGIN_DIRS environment variable. The default plugin path will still be used if DECKER_PLUGIN_DIRS is set.

Example: export DECKER_PLUGIN_DIRS="/path/to/my/plugins:/additional/path/to/plugins"

There should be an HCL file next to the .so file at <decker binary>/internal/app/decker/plugins/<plugin name>/<plugin name>.hcl that defines its inputs and outputs. Currently, only string, list, and map inputs are supported. Each input should have an input block that looks like this:

input "my_input" {
  type = "string"
  default = "some default value"
}

Directory Structure

.
├── 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
  • cmd/decker/main.go is the driver. Its job is to parse a given config file, load the appropriate plugins based on the file's resource blocks, and run the plugins with the specified inputs.
  • examples has a couple example configurations to get you started with decker. If you use the kali docker image (stevenaldinger/decker:kali), all dependencies should be installed for all config files and things should run smoothly.
  • internal/pkg is where most of the actual code is. It contains all the packages imported by main.go.
    • dependencies is responsible for building the plugin dependency graph and returning a topologically sorted array that ensures plugins are run in a working order.
    • gocty offers helpers for encoding and decoding go-cty values which are used to handle dynamic input types.
    • hcl is responsible for parsing HCL files, including creating evaluation contexts that let 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, and generated reports.
    • plugins is responsible for determining if plugins are enabled and running them.
    • reports is responsible for writing reports to the file system.
  • internal/app/decker/plugins are modular pieces of code written as Golang plugins, implementing a simple interface that allows them to be loaded and called at run-time with inputs and outputs specified in the plugin's config file (also in HCL). An example can be found at internal/app/decker/plugins/nslookup/nslookup.hcl.
  • decker config files offer a declarative way to write penetration tests. The manifests are written in HashiCorp Configuration Language 2) and describe the set of plugins to be used in the test as well as their inputs.
Comments
  • Build plugin example script

    Build plugin example script

    Hay first really like this idea, been playing around with it for some time.

    Would love some more examples on how to use the build_plugin script. Or how to create the .so file.

  • Fatal when using a new plugin

    Fatal when using a new plugin

    Hi, i have the following error while trying to use a new plugin in an HCL file (plugin compile successfully) :

    panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x879dcd]
    
    goroutine 1 [running]:
    github.com/stevenaldinger/decker/internal/pkg/hcl.parsePluginHCL(0xc0000844e0, 0x56, 0x4b)
            /go/src/github.com/stevenaldinger/decker/internal/pkg/hcl/plugins.go:23 +0x11d
    github.com/stevenaldinger/decker/internal/pkg/hcl.GetResourceBlockSchema(0xc0000a5ab6, 0x6, 0x7f6a8a1ebfff)
            /go/src/github.com/stevenaldinger/decker/internal/pkg/hcl/hcl_schema.go:98 +0xcb
    github.com/stevenaldinger/decker/internal/pkg/hcl.getResourceContent(0xc00009bd40, 0x0)
            /go/src/github.com/stevenaldinger/decker/internal/pkg/hcl/resources.go:11 +0x5b
    github.com/stevenaldinger/decker/internal/pkg/hcl.GetExprVars(0xc00009bd40, 0xc00014f6a0)
            /go/src/github.com/stevenaldinger/decker/internal/pkg/hcl/resources.go:26 +0x40
    github.com/stevenaldinger/decker/internal/pkg/dependencies.addEdgesToGraph(0xc000091ec0, 0xc00008f960, 0x2, 0x2, 0xc00014f640, 0xc00014f638)
            /go/src/github.com/stevenaldinger/decker/internal/pkg/dependencies/graph.go:56 +0x153
    github.com/stevenaldinger/decker/internal/pkg/dependencies.Sort(0xc00008f960, 0x2, 0x2, 0xc00008f9d0, 0x1, 0x1)
            /go/src/github.com/stevenaldinger/decker/internal/pkg/dependencies/graph.go:107 +0x259
    main.main()
            /go/src/github.com/stevenaldinger/decker/cmd/decker/main.go:36 +0xed
    

    I can't figure out why

  • validate config file against unknown plugins and duplicate resources

    validate config file against unknown plugins and duplicate resources

    Duplicate resource names will cause errors when establishing topology and unknown plugin names should keep the config from running (with a nice error message) too before it causes other issues.

  • fix dependency graph with for_each

    fix dependency graph with for_each

    Fixes issue where for_each had to be specified by a plugin's HCL when loops were used, fixes issue where dependency graph was ignoring for_each and plugin's sometimes ran out of order.

  • Nmap protocol detection plugin port sanitization

    Nmap protocol detection plugin port sanitization

    Hello,

    I noticed a problem in the Nmap plugin. The parsed port may contains spaces that could result in formating problems in other plugins.

    The parsed value has to be cleaned, the following code makes the work for me :

    parsedPort := strings.TrimSpace(portInfoSplit[0])
    
    
  • Multiples input for plugins and concurrency

    Multiples input for plugins and concurrency

    Hey ! I'm reposting my question here for more visibility :)

    I'm trying to build a first plugin basically launching "dirb" against an URL. I wonder how i can write the hcl code in order to target 2 urls. My following attempts fail with "index out of range" (note that the plugin code works perfectly fine with one URL)

    resource "dirb" "dirb" {
    for_each = ["https://www.google.fr","https://www.google.com"] 
    target="${each.key}"
    }
    

    Moreover, i think it would be interesting to add a "concurrency" feature. During a pentest engagement there are multiples IPs to target so i would be awesome to launch a decker instance for each target IP especially if time consuming tasks are involved (as dirb :) ).

  • Add binary releases so people can choose their OS distribution

    Add binary releases so people can choose their OS distribution

    This has been something interesting me for a while now but I never set up any easy downloads page to try to add decker to your own environment.

    This will be relevant for another issue in decker-plugin so will resolve ASAP.

  • Protocol detection

    Protocol detection

    Hi,

    First if all, thanks for the project! I really like the idea. The README mentions following example:

    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}"
    }
    // for each IP, check if nmap found port 25 open.
    // if yes, run metasploit's smtp_enum scanner
    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"}"
    }
    

    However, most of the time you will need to detect the protocol and not rely on standard ports. Is it currently possible to do so? e.g. launch a TLS scan for every port where (START)TLS was detected?

A Declarative Cloud Firewall Reverse Proxy Solution with Companion Mobile App
A Declarative Cloud Firewall Reverse Proxy Solution with Companion Mobile App

A declarative Cloud firewall reverse proxy solution with inbuilt DDoS protection and alerting mechanism to protect your servers and keeping an eye on those malicious requests

Aug 10, 2022
A web-based testing platform for WAF (Web Application Firewall)'s correctness

WAFLab ?? WAFLab is a web-based platform for testing WAFs. Live Demo https://waflab.org/ Architecture WAFLab contains 2 parts: Name Description Langua

Oct 25, 2022
A vulnerable graphQL application, for testing purposes

Vulnerable-GoQL Vulnerable-GoQL is an web API which implements main security breach.

Jul 31, 2021
kubescape is the first tool for testing if Kubernetes is deployed securely as defined in Kubernetes Hardening Guidance by to NSA and CISA
kubescape is the first tool for testing if Kubernetes is deployed securely as defined in Kubernetes Hardening Guidance by to NSA and CISA

Kubescape is the first tool for testing if Kubernetes is deployed securely as defined in Kubernetes Hardening Guidance by to NSA and CISA Tests are configured with YAML files, making this tool easy to update as test specifications evolve.

Jan 8, 2023
Easy to use cryptographic framework for data protection: secure messaging with forward secrecy and secure data storage. Has unified APIs across 14 platforms.
Easy to use cryptographic framework for data protection: secure messaging with forward secrecy and secure data storage. Has unified APIs across 14 platforms.

Themis provides strong, usable cryptography for busy people General purpose cryptographic library for storage and messaging for iOS (Swift, Obj-C), An

Jan 6, 2023
The dynamic infrastructure framework for everybody! Distribute the workload of many different scanning tools with ease, including nmap, ffuf, masscan, nuclei, meg and many more!
The dynamic infrastructure framework for everybody! Distribute the workload of many different scanning tools with ease, including nmap, ffuf, masscan, nuclei, meg and many more!

Axiom is a dynamic infrastructure framework to efficiently work with multi-cloud environments, build and deploy repeatable infrastructure focussed on

Dec 30, 2022
Build awesome Golang desktop apps and beautiful interfaces with Vue.js, React.js, Framework 7, and more...
Build awesome Golang desktop apps and beautiful interfaces with Vue.js, React.js, Framework 7, and more...

Guark Guark allows you to build beautiful user interfaces using modern web technologies such as Vue.js, React.js..., while your app logic handled and

Jan 1, 2023
A framework for creating COM-based bypasses utilizing vulnerabilities in Microsoft's WDAPT sensors.
A framework for creating COM-based bypasses utilizing vulnerabilities in Microsoft's WDAPT sensors.

Dent More Information If you want to learn more about the techniques utlized in this framework please take a look at this article. Description This fr

Dec 2, 2022
Jan 6, 2023
Secure Boot certificates from the Framework Laptop

Framework Laptop UEFI Secure Boot Certificates Source: Extracted from a live machine (FRANBMCP08) Date: 2021-10-21 KEK (Key Exchange Key) This certifi

Dec 8, 2022
evilginx2 is a man-in-the-middle attack framework used for phishing login credentials along with session cookies, which in turn allows to bypass 2-factor authentication protection.
evilginx2 is a man-in-the-middle attack framework used for phishing login credentials along with session cookies, which in turn allows to bypass 2-factor authentication protection.

evilginx2 is a man-in-the-middle attack framework used for phishing login credentials along with session cookies, which in turn allows to bypass 2-fac

Nov 4, 2021
A man-in-the-middle attack framework used for phishing login credentials along with session cookies
A man-in-the-middle attack framework used for phishing login credentials along with session cookies

evilginx2 is a man-in-the-middle attack framework used for phishing login credentials along with session cookies, which in turn allows to bypass 2-fac

Nov 7, 2021
Advanced information gathering & OSINT framework for phone numbers
 Advanced information gathering & OSINT framework for phone numbers

PhoneInfoga is one of the most advanced tools to scan international phone numbers using only free resources. It allows you to first gather standard information such as country, area, carrier and line type on any international phone number.

Oct 13, 2021
A Flask-based HTTP(S) command and control (C2) framework with a web frontend. Malleable agents written in Go and scripts written in bash.

▄▄▄▄ ██▓ █████▒██▀███ ▒█████ ██████ ▄▄▄█████▓ ▓█████▄ ▓██▒▓██ ▒▓██ ▒ ██▒▒██▒ ██▒▒██ ▒ ▓ ██▒ ▓▒ ▒██▒ ▄██▒██▒▒████ ░▓██ ░▄█ ▒▒██░ ██▒░

Dec 24, 2022
siusiu (suite-suite harmonics) a suite used to manage the suite, designed to free penetration testing engineers from learning and using various security tools, reducing the time and effort spent by penetration testing engineers on installing tools, remembering how to use tools.
siusiu (suite-suite harmonics) a suite used to manage the suite, designed to free penetration testing engineers from learning and using various security tools, reducing the time and effort spent by penetration testing engineers on installing tools, remembering how to use tools.

siusiu (suite-suite harmonics) a suite used to manage the suite, designed to free penetration testing engineers from learning and using various security tools, reducing the time and effort spent by penetration testing engineers on installing tools, remembering how to use tools.

Dec 12, 2022
Subfinder is a subdomain discovery tool that discovers valid subdomains for websites. Designed as a passive framework to be useful for bug bounties and safe for penetration testing.
Subfinder is a subdomain discovery tool that discovers valid subdomains for websites. Designed as a passive framework to be useful for bug bounties and safe for penetration testing.

Fast passive subdomain enumeration tool. Features • Install • Usage • API Setup • License • Join Discord Subfinder is a subdomain discovery tool that

Jan 4, 2023
Tool which gathers basic info from apk, which can be used for Android penetration testing.
Tool which gathers basic info from apk, which can be used for Android penetration testing.

APKSEC Tool which gathers basic info from apk, which can be used for Android penetration testing. REQUIREMENTS AND INSTALLATION Build APKSEC: git clon

Sep 2, 2022
Serverless SOAR (Security Orchestration, Automation and Response) framework for automatic inspection and evaluation of security alert
Serverless SOAR (Security Orchestration, Automation and Response) framework for automatic inspection and evaluation of security alert

DeepAlert DeepAlert is a serverless framework for automatic response of security alert. Overview DeepAlert receives a security alert that is event of

Jan 3, 2023