
선언적 침투 테스트 오케스트레이션 프레임워크
Decker는 침투 테스트 오케스트레이션 프레임워크입니다. HashiCorp Configuration Language 2 (Terraform과 동일한 구성 언어)를 활용하여 선언적인 침투 테스트를 코드로 작성할 수 있게 해주므로, 팀이나 커뮤니티와 테스트를 버전 관리, 공유, 재사용 및 협업할 수 있습니다.
decker 구성 파일 예시:
// 변수는 환경에서 가져옵니다.
// 예: DECKER_TARGET_HOST
// 구성 파일 전체에서 var.*로 사용 가능합니다.
// 예: ${var.target_host}
variable "target_host" {
type = "string"
}
// 리소스는 플러그인을 참조합니다.
// 리소스는 고유한 이름이 필요하므로 플러그인을 여러 번 사용할 수 있습니다.
// 다음과 같은 형식으로 선언됩니다: 'resource "plugin_name" "unique_name" {}'
// 해당 출력은 unique_name.* 형식으로 다른 곳에서 사용할 수 있습니다.
// 예: nmap.443
resource "nmap" "nmap" {
host = "${var.target_host}"
plugin_enabled = "true"
}
resource "sslscan" "sslscan" {
host = "${var.target_host}"
plugin_enabled = "${nmap.443 == "open"}"
}
목록의 각 항목에 대해 플러그인 실행:
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"
}
}
중첩된 값과 for_each를 결합한 복잡한 구성:
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}"
}
// 각 IP에 대해 nmap이 포트 25가 열려 있는지 확인합니다.
// 열려 있으면 metasploit의 smtp_enum 스캐너를 실행합니다.
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"}"
}
여러 출력 형식을 사용할 수 있으며, 동시에 여러 개를 선택할 수 있습니다.
DECKER_OUTPUTS_JSON 또는 DECKER_OUTPUTS_XML을 "true"로 설정하면 각각 json 및 xml 형식의 파일이 출력됩니다.
.json 파일 출력: export DECKER_OUTPUTS_JSON="true".xml 파일 출력: export DECKER_OUTPUTS_XML="true"제 친구 Courtney가 이름을 정하는 데 어려움을 겪을 때 도움을 주었고, SciFi 용어 사전에서 decker를 찾았습니다... 그리고 멋져 보였습니다.
미래의 크래커; 사이버 공간을 조작하는 데 능숙한 소프트웨어 전문가, 특히 보안 예방 조치를 우회하는 데 능숙한 사람.
두 개의 볼륨이 마운트됩니다:
decker-reports라는 디렉토리로, decker가 실행된 각 플러그인에 대한 파일을 출력합니다. 파일 이름은 {unique_resource_name}.report.txt입니다.decker 구성 파일이 포함된 examples 디렉토리. 이 볼륨을 마운트하면 즐겨 사용하는 편집기로 로컬에서 구성을 작성하고 컨테이너 내에서 실행할 수 있습니다.하나의 환경 변수가 전달됩니다:
DECKER_TARGET_HOST이는 구성 파일에서 {var.target_host}로 참조됩니다. Decker는 DECKER_*라는 이름의 모든 환경 변수를 반복하여, 접두사를 제거하고 나머지를 소문자로 설정합니다.
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
decker가 구성을 완료하면 ./decker-reports에서 출력물을 확인하세요.
decker가 보고서를 작성할 디렉토리를 DECKER_REPORTS_DIR 환경 변수로 설정하는 것이 좋습니다.
다음과 같은 설정이 적절합니다. 설정한 디렉토리가 이미 존재하는지 확인하세요.
export DECKER_REPORTS_DIR="$HOME/decker-reports"
또한 예제 구성 파일 중 하나를 실행하는 경우 대상 호스트를 설정해야 합니다.
export DECKER_TARGET_HOST="<호스트 이름 입력>"
그런 다음 구성 파일을 실행하면 됩니다. 이 저장소의 루트 디렉토리로 이동하여 다음을 실행하세요:
./decker ./examples/example.hcl
기여는 매우 환영하며 감사드립니다. 지침은 docs/contributions.md를 참조하세요.
원활한 경험을 위해 Docker를 사용한 개발을 권장합니다. 이렇게 하면 모든 종속 항목이 설치되어 바로 사용할 수 있습니다.
Go 코드 개요는 아래 디렉토리 구조를 참조하세요.
make docker_buildmake docker_run (Docker 컨테이너를 시작하고 대화형 bash 세션을 엽니다)dep ensure -vmake build_allmake runmake init을 실행하여 각 커밋 시 린팅과 테스트를 실행하는 pre-commit 스크립트를 추가하세요.
Decker 자체는 구성 파일을 읽고, 구성 파일의 종속성을 결정하며, 다른 플러그인에 종속된 플러그인(한 플러그인의 출력이 다른 플러그인의 입력이 되는 경우)이 종속된 플러그인 이후에 실행되도록 순서를 결정하는 프레임워크일 뿐입니다.
decker의 진정한 힘은 플러그인에서 나옵니다. 플러그인 개발은 원하는 만큼 간단하거나 복잡하게 할 수 있으며, 최종 결과는 컴파일된 플러그인 코드가 포함된 .so 파일과 사용자가 구성할 입력을 선언하는 동일한 디렉토리의 .hcl 파일이어야 합니다.
첫 번째 플러그인을 시작하려면 docs/building_plugins.md를 확인하세요. 몇 분만에 "Hello World" decker 플러그인을 실행할 수 있을 것입니다.
기본적으로 플러그인은 decker 바이너리가 있는 위치를 기준으로 <decker binary>/internal/app/decker/plugins/<plugin name>/<plugin name>.so 경로에 있을 것으로 예상됩니다. DECKER_PLUGIN_DIRS 환경 변수를 설정하여 추가 경로를 추가할 수 있습니다. DECKER_PLUGIN_DIRS가 설정되어도 기본 플러그인 경로는 계속 사용됩니다.
예: export DECKER_PLUGIN_DIRS="/path/to/my/plugins:/additional/path/to/plugins"
.so 파일 옆에 <decker binary>/internal/app/decker/plugins/<plugin name>/<plugin name>.hcl 파일이 있어야 하며, 이 파일은 해당 플러그인의 입력 및 출력을 정의합니다. 현재는 string, list, map 입력만 지원됩니다. 각 입력에는 다음과 같은 input 블록이 있어야 합니다:
input "my_input" {
type = "string"
default = "some default value"
}
.
├── 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 블록을 기반으로 적절한 플러그인을 로드하며, 지정된 입력으로 플러그인을 실행하는 역할을 합니다.decker를 시작하는 데 도움이 되는 몇 가지 예제 구성을 포함합니다. kali docker 이미지 (stevenaldinger/decker:kali)를 사용하면 모든 구성 파일에 대한 모든 종속성이 설치되어 원활하게 실행됩니다.decker 바이너리, 구성 파일, 플러그인 구성 파일 및 생성된 보고서의 파일 경로를 반환하는 역할을 합니다.