#!/bin/bash # Smoke test for APT-Hunter: fetch sample EVTX, run, check outputs. # # Available SUBSET values (under test-data/sample-evtx/): # DeepBlueCLI 21 files, ~1min # YamatoSecurity 16 files, ~30s # EVTX-ATTACK-SAMPLES 278 files, ~10min # EVTX-to-MITRE-Attack 284 files, ~10min # "" 599 files, ~20min # # Env vars: TAG=ls-apthunter:test SUBSET=DeepBlueCLI KEEP_DATA=1 set -u TAG="${TAG:-ls-apthunter:test}" SUBSET="${SUBSET:-DeepBlueCLI}" KEEP_DATA="${KEEP_DATA:-0}" cd "$(dirname "$0")" ROOT="$(pwd)" DATA="$ROOT/test-data/sample-evtx" OUT="$(mktemp -d)" trap 'rm -rf "$OUT"; [ "$KEEP_DATA" = 0 ] && rm -rf "$ROOT/test-data"' EXIT pass=0; fail=0 ok() { echo "PASS $1"; pass=$((pass+1)); } bad() { echo "FAIL $1"; fail=$((fail+1)); } if docker image inspect "$TAG" >/dev/null 2>&1; then ok "image $TAG present" else bad "image $TAG not present"; exit 1 fi if [ ! -d "$DATA" ]; then echo "Fetching sample EVTX..." ./fetch-test-data.sh >/dev/null fi SCAN="$DATA/$SUBSET"; [ -z "$SUBSET" ] && SCAN="$DATA" n=$(find "$SCAN" -name "*.evtx" | wc -l | tr -d ' ') [ "$n" -gt 0 ] && ok "found $n EVTX in ${SUBSET:-}" || { bad "no EVTX"; exit 1; } echo "Running scan..." if docker run --rm --network=none -v "$SCAN:/data:ro" -v "$OUT:/output" "$TAG" >"$OUT/.run.log" 2>&1; then ok "container exited cleanly" else bad "container non-zero"; tail -20 "$OUT/.run.log" fi # APT-Hunter writes /output/apthunter_/output/apthunter__{Report.xlsx,TimeSketch.csv,...} xlsx=$(ls "$OUT"/apthunter_*/output/apthunter_*_Report.xlsx 2>/dev/null | head -1) ts=$(ls "$OUT"/apthunter_*/output/apthunter_*_TimeSketch.csv 2>/dev/null | head -1) [ -s "$xlsx" ] && ok "Excel report exists ($(du -h "$xlsx" | cut -f1))" || bad "xlsx missing" [ -s "$ts" ] && ok "TimeSketch CSV exists ($(du -h "$ts" | cut -f1))" || bad "csv missing" if [ -s "$ts" ]; then detections=$(($(wc -l < "$ts") - 1)) echo echo "Detections: $detections" fi echo echo "Summary: $pass pass, $fail fail" [ "$fail" -eq 0 ]