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.