Back to All Modules

Scope and Workspace

#Scope Files

Use separate files for domains, IP addresses, CIDR ranges, and exclusions. One value per line keeps tools composable and makes the authorized target set reviewable.

scope/
  domains.txt       # example.com
  ips.txt           # 192.0.2.10
  cidrs.txt         # 198.51.100.0/28
  exclude.txt       # explicit exclusions in the same formats
TEXT

Do not add hosts discovered through ASN, certificate, DNS, or cloud metadata until ownership and scope have been confirmed.

#Paste-Ready Workspace Initializer

Save as new-engagement.sh, make it executable, and pass a short engagement name plus the directory containing the approved scope files.

#!/usr/bin/env bash
set -Eeuo pipefail
umask 077

usage() {
  echo "Usage: $0 <engagement-name> <scope-directory>"
  exit 1
}

[[ $# -eq 2 ]] || usage
NAME="$1"
SCOPE_DIR="$(realpath "$2")"
[[ "$NAME" =~ ^[A-Za-z0-9._-]+$ ]] || { echo "Invalid engagement name"; exit 1; }
[[ -d "$SCOPE_DIR" ]] || { echo "Scope directory not found: $SCOPE_DIR"; exit 1; }

STAMP="$(date -u +%Y%m%dT%H%M%SZ)"
ROOT="$PWD/engagements/${NAME}-${STAMP}"
mkdir -p "$ROOT"/{scope,logs,raw,normalized,evidence,notes,tmp}

for file in domains.txt ips.txt cidrs.txt exclude.txt; do
  if [[ -f "$SCOPE_DIR/$file" ]]; then
    sed -e 's/#.*$//' -e '/^[[:space:]]*$/d' "$SCOPE_DIR/$file" \
      | sort -u > "$ROOT/scope/$file"
  else
    : > "$ROOT/scope/$file"
  fi
done

cat > "$ROOT/engagement.env" <<EOF
export ENGAGEMENT_ROOT="$ROOT"
export SCOPE_DIR="$ROOT/scope"
export RAW_DIR="$ROOT/raw"
export NORMALIZED_DIR="$ROOT/normalized"
export EVIDENCE_DIR="$ROOT/evidence"
export LOG_DIR="$ROOT/logs"
export SCAN_RATE="500"
export HTTP_RATE="25"
EOF

{
  echo "created_utc=$STAMP"
  echo "operator=${USER:-unknown}"
  echo "host=$(hostname)"
  find "$ROOT/scope" -type f -maxdepth 1 -print0 | sort -z | xargs -0 sha256sum
} > "$ROOT/evidence/manifest.txt"

echo "Workspace: $ROOT"
echo "Load variables with: source '$ROOT/engagement.env'"
BASH

#Scope Membership Helper

Use this helper before passing a discovered hostname to an active tool. It accepts exact authorized domains and their descendants.

in_domain_scope() {
  local candidate="${1,,}" domain
  while IFS= read -r domain; do
    domain="${domain,,}"
    [[ -z "$domain" ]] && continue
    [[ "$candidate" == "$domain" || "$candidate" == *".$domain" ]] && return 0
  done < "$SCOPE_DIR/domains.txt"
  return 1
}
BASH

IP and CIDR authorization should be enforced by feeding active scanners only the reviewed ips.txt and cidrs.txt files. Do not derive a wider network from a discovered address.

#Logging Wrapper

run_logged() {
  local label="$1"
  shift
  local log="$LOG_DIR/${label}-$(date -u +%Y%m%dT%H%M%SZ).log"
  printf '[%s] command:' "$(date -u +%FT%TZ)" | tee -a "$log"
  printf ' %q' "$@" | tee -a "$log"
  printf '\n' | tee -a "$log"
  "$@" 2>&1 | tee -a "$log"
}
BASH

#Evidence Checklist

  • Record tool versions in evidence/tool-versions.txt.
  • Keep unmodified scanner output under raw/.
  • Write parsed and deduplicated results under normalized/.
  • Store screenshots and protocol transcripts under evidence/.
  • Record every manually added target and the scope justification in notes/.
  • Hash deliverable evidence before cleanup or transfer.