mirror of
https://github.com/BenjiTrapp/transportable-detonation-chamber
synced 2026-08-09 12:01:14 +00:00
Some rework for vagrant
This commit is contained in:
@@ -55,6 +55,9 @@ help:
|
||||
@echo " ================================"
|
||||
@echo " Platform: $(PLATFORM) Provider: $(PROVIDER) VM: $(VM_IP)"
|
||||
@echo ""
|
||||
@echo " Setup:"
|
||||
@echo " make prerequisites Check/install all prerequisites"
|
||||
@echo ""
|
||||
@echo " Local (no VM required):"
|
||||
@echo " make install Install Python venv + dependencies"
|
||||
@echo " make run Run the Web UI locally (port 9000)"
|
||||
@@ -95,6 +98,16 @@ help:
|
||||
|
||||
# --- Local Install (no VM required) ---
|
||||
|
||||
.PHONY: prerequisites
|
||||
prerequisites:
|
||||
@echo "[prerequisites] Checking system requirements..."
|
||||
@bash scripts/check-prerequisites.sh
|
||||
|
||||
.PHONY: prerequisites-fix
|
||||
prerequisites-fix:
|
||||
@echo "[prerequisites] Checking and fixing system requirements..."
|
||||
@bash scripts/check-prerequisites.sh --fix
|
||||
|
||||
VENV_DIR := webui/.venv
|
||||
PYTHON := $(VENV_DIR)/bin/python
|
||||
PIP := $(VENV_DIR)/bin/pip
|
||||
@@ -219,7 +232,7 @@ status:
|
||||
|
||||
.PHONY: services
|
||||
services:
|
||||
vagrant winrm -c "Write-Host ''; Write-Host ' SERVICE STATE'; Write-Host ' ------- -----'; @('DetonationChamberUI','Rustinel','DetonatorAgent','LitterBox','Fibratus','theZoo-WebUI') | ForEach-Object { $$st = Get-ScheduledTask -TaskName $$_ -EA SilentlyContinue; if($$st){Write-Host (' '+$$_.PadRight(22)+$$st.State)}else{Write-Host (' '+$$_.PadRight(22)+'NOT FOUND')}}; Write-Host (' Sysmon'.PadRight(24)+(Get-Service Sysmon64 -EA SilentlyContinue).Status); Write-Host ''"
|
||||
vagrant winrm -c "Write-Host ''; Write-Host ' SERVICE STATE'; Write-Host ' ------- -----'; @('DetonationChamberUI','Rustinel','DetonatorAgent','LitterBox','Fibratus','theZoo-WebUI') | ForEach-Object { $$st = Get-ScheduledTask -TaskName $$_ -EA SilentlyContinue; if($$st){Write-Host (' '+$$_.PadRight(22)+$$st.State)}else{Write-Host (' '+$$_.PadRight(22)+'NOT FOUND')}}; $$sysmon = Get-Service Sysmon64 -EA SilentlyContinue; if(-not $$sysmon){$$sysmon = Get-Service Sysmon64a -EA SilentlyContinue}; Write-Host (' Sysmon'.PadRight(24)+$$(if($$sysmon){$$sysmon.Status}else{'NOT FOUND'})); Write-Host ''"
|
||||
|
||||
.PHONY: alerts
|
||||
alerts:
|
||||
|
||||
+3
-2
@@ -63,7 +63,7 @@ Vagrant.configure("2") do |config|
|
||||
qe.machine = "virt,highmem=on"
|
||||
qe.cpu = "host"
|
||||
qe.smp = "cpus=4,sockets=1,cores=4,threads=1"
|
||||
qe.memory = "4G"
|
||||
qe.memory = "8G"
|
||||
qe.net_device = "virtio-net-pci"
|
||||
qe.ssh_port = 50222
|
||||
|
||||
@@ -90,9 +90,10 @@ Vagrant.configure("2") do |config|
|
||||
# Disable default synced folder
|
||||
config.vm.synced_folder ".", "/vagrant", disabled: true
|
||||
|
||||
# Copy config and webui into the VM via file provisioners
|
||||
# Copy config, webui, and rules into the VM via file provisioners
|
||||
config.vm.provision "file", source: "config", destination: "C:\\vagrant_config"
|
||||
config.vm.provision "file", source: "webui", destination: "C:\\vagrant\\webui"
|
||||
config.vm.provision "file", source: "rules", destination: "C:\\vagrant\\rules"
|
||||
|
||||
# Provisioning: run scripts in order
|
||||
# All scripts are architecture-aware (detect ARM64 vs x86_64 automatically)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
param(
|
||||
[Parameter(Position=0)]
|
||||
[ValidateSet(
|
||||
'help','install','run','run-debug','uninstall',
|
||||
'help','prerequisites','install','run','run-debug','uninstall',
|
||||
'up','halt','destroy','reload','provision','provision-webui',
|
||||
'deploy','deploy-app','restart','deploy-restart','open','logs',
|
||||
'ssh','rdp','status','services','alerts','test','submit',
|
||||
@@ -72,6 +72,9 @@ switch ($Target) {
|
||||
Write-Host " ================================"
|
||||
Write-Host " Platform: windows Provider: $Provider VM: $VMIp"
|
||||
Write-Host ""
|
||||
Write-Host " Setup:" -ForegroundColor Yellow
|
||||
Write-Host " .\make.ps1 prerequisites Check/install all prerequisites"
|
||||
Write-Host ""
|
||||
Write-Host " Local (no VM required):" -ForegroundColor Yellow
|
||||
Write-Host " .\make.ps1 install Install Python venv + dependencies"
|
||||
Write-Host " .\make.ps1 run Run the Web UI locally (port 9000)"
|
||||
@@ -112,6 +115,16 @@ switch ($Target) {
|
||||
|
||||
# --- Local Install ---
|
||||
|
||||
'prerequisites' {
|
||||
Write-Host "[prerequisites] Checking system requirements..." -ForegroundColor Cyan
|
||||
$scriptPath = Join-Path $PSScriptRoot "scripts\check-prerequisites.ps1"
|
||||
if (Test-Path $scriptPath) {
|
||||
& $scriptPath
|
||||
} else {
|
||||
Write-Host "ERROR: scripts\check-prerequisites.ps1 not found" -ForegroundColor Red
|
||||
}
|
||||
}
|
||||
|
||||
'install' {
|
||||
$VenvDir = "webui\.venv"
|
||||
Write-Host "[install] Setting up local development environment..." -ForegroundColor Cyan
|
||||
@@ -373,7 +386,9 @@ switch ($Target) {
|
||||
Write-Host "NOT FOUND" -ForegroundColor DarkGray
|
||||
}
|
||||
}
|
||||
# Check both Sysmon64 (x64) and Sysmon64a (ARM64) service names
|
||||
$sysmon = Get-Service Sysmon64 -ErrorAction SilentlyContinue
|
||||
if (-not $sysmon) { $sysmon = Get-Service Sysmon64a -ErrorAction SilentlyContinue }
|
||||
Write-Host (" Sysmon".PadRight(24)) -NoNewline
|
||||
if ($sysmon -and $sysmon.Status -eq 'Running') {
|
||||
Write-Host $sysmon.Status -ForegroundColor Green
|
||||
|
||||
@@ -0,0 +1,301 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Checks and installs all prerequisites for the Transportable Detonation Chamber
|
||||
on Windows (Hyper-V provider).
|
||||
|
||||
.DESCRIPTION
|
||||
Validates that all required tools and system features are available:
|
||||
1. Windows 10/11 with Hyper-V enabled
|
||||
2. Administrator privileges
|
||||
3. Vagrant >= 2.4
|
||||
4. Sufficient disk space (30 GB+)
|
||||
5. Sufficient RAM (8 GB minimum)
|
||||
6. Windows 11 Vagrant box (auto-downloaded from Vagrant Cloud)
|
||||
7. Project files intact
|
||||
|
||||
.PARAMETER Fix
|
||||
Automatically install/enable missing dependencies where possible.
|
||||
|
||||
.EXAMPLE
|
||||
.\scripts\check-prerequisites.ps1
|
||||
.\scripts\check-prerequisites.ps1 -Fix
|
||||
#>
|
||||
|
||||
param(
|
||||
[switch]$Fix
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Continue"
|
||||
Set-StrictMode -Version Latest
|
||||
|
||||
# --- Tracking ---
|
||||
$script:Errors = 0
|
||||
$script:Warnings = 0
|
||||
|
||||
# --- Helpers ---
|
||||
function Write-Ok { param($Msg) Write-Host "[+] $Msg" -ForegroundColor Green }
|
||||
function Write-Warn { param($Msg) Write-Host "[!] $Msg" -ForegroundColor Yellow; $script:Warnings++ }
|
||||
function Write-Fail { param($Msg) Write-Host "[-] $Msg" -ForegroundColor Red; $script:Errors++ }
|
||||
function Write-Info { param($Msg) Write-Host "[*] $Msg" -ForegroundColor Cyan }
|
||||
function Write-Header { param($Msg) Write-Host "`n--- $Msg ---" -ForegroundColor White }
|
||||
|
||||
# ============================================================================
|
||||
Write-Host ""
|
||||
Write-Host " Transportable Detonation Chamber - Prerequisites Check" -ForegroundColor Cyan
|
||||
Write-Host " ======================================================" -ForegroundColor Cyan
|
||||
Write-Host " Platform: Windows (Hyper-V)" -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
|
||||
# ============================================================================
|
||||
Write-Header "Administrator Privileges"
|
||||
# ============================================================================
|
||||
|
||||
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(
|
||||
[Security.Principal.WindowsBuiltInRole]::Administrator
|
||||
)
|
||||
if ($isAdmin) {
|
||||
Write-Ok "Running as Administrator"
|
||||
} else {
|
||||
Write-Warn "Not running as Administrator"
|
||||
Write-Info "Hyper-V operations require elevation. Re-run as Admin if 'vagrant up' fails."
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
Write-Header "Windows Version"
|
||||
# ============================================================================
|
||||
|
||||
$osVersion = [System.Environment]::OSVersion.Version
|
||||
$osBuild = (Get-CimInstance Win32_OperatingSystem).BuildNumber
|
||||
$osName = (Get-CimInstance Win32_OperatingSystem).Caption
|
||||
|
||||
if ($osVersion.Major -ge 10 -and [int]$osBuild -ge 19041) {
|
||||
Write-Ok "$osName (Build $osBuild)"
|
||||
} else {
|
||||
Write-Fail "Windows 10 version 2004+ or Windows 11 required (detected Build $osBuild)"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
Write-Header "Hyper-V"
|
||||
# ============================================================================
|
||||
|
||||
$hyperv = Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -ErrorAction SilentlyContinue
|
||||
if ($hyperv -and $hyperv.State -eq "Enabled") {
|
||||
Write-Ok "Hyper-V enabled"
|
||||
} else {
|
||||
Write-Fail "Hyper-V is not enabled"
|
||||
if ($Fix -and $isAdmin) {
|
||||
Write-Info "Enabling Hyper-V (requires reboot)..."
|
||||
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-All -NoRestart -ErrorAction SilentlyContinue
|
||||
$script:Errors--
|
||||
Write-Ok "Hyper-V enabled - REBOOT REQUIRED"
|
||||
Write-Warn "Please reboot and re-run this script"
|
||||
} else {
|
||||
Write-Info "Enable with (Admin PowerShell):"
|
||||
Write-Info " Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-All"
|
||||
Write-Info " # Then reboot"
|
||||
}
|
||||
}
|
||||
|
||||
# Also check Hyper-V management tools
|
||||
$hypervMgmt = Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-Management-PowerShell -ErrorAction SilentlyContinue
|
||||
if ($hypervMgmt -and $hypervMgmt.State -eq "Enabled") {
|
||||
Write-Ok "Hyper-V PowerShell management tools enabled"
|
||||
} else {
|
||||
Write-Warn "Hyper-V PowerShell tools not enabled (vagrant may still work)"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
Write-Header "Vagrant"
|
||||
# ============================================================================
|
||||
|
||||
$vagrantCmd = Get-Command vagrant -ErrorAction SilentlyContinue
|
||||
if ($vagrantCmd) {
|
||||
$vagrantVersion = (vagrant --version 2>$null)
|
||||
Write-Ok "Vagrant installed ($vagrantVersion)"
|
||||
|
||||
# Check version >= 2.4
|
||||
if ($vagrantVersion -match '(\d+)\.(\d+)') {
|
||||
$major = [int]$Matches[1]
|
||||
$minor = [int]$Matches[2]
|
||||
if ($major -gt 2 -or ($major -eq 2 -and $minor -ge 4)) {
|
||||
Write-Ok "Vagrant version >= 2.4"
|
||||
} else {
|
||||
Write-Warn "Vagrant version < 2.4 detected. Upgrade recommended for best Hyper-V support."
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Fail "Vagrant not installed"
|
||||
if ($Fix) {
|
||||
# Try winget first, then chocolatey
|
||||
$winget = Get-Command winget -ErrorAction SilentlyContinue
|
||||
if ($winget) {
|
||||
Write-Info "Installing Vagrant via winget..."
|
||||
winget install HashiCorp.Vagrant --accept-source-agreements --accept-package-agreements
|
||||
$script:Errors--
|
||||
Write-Ok "Vagrant installed (restart terminal to use)"
|
||||
} else {
|
||||
$choco = Get-Command choco -ErrorAction SilentlyContinue
|
||||
if ($choco) {
|
||||
Write-Info "Installing Vagrant via Chocolatey..."
|
||||
choco install vagrant -y
|
||||
$script:Errors--
|
||||
Write-Ok "Vagrant installed (restart terminal to use)"
|
||||
} else {
|
||||
Write-Info "Install Vagrant from: https://developer.hashicorp.com/vagrant/install"
|
||||
Write-Info " or: winget install HashiCorp.Vagrant"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Info "Install with: winget install HashiCorp.Vagrant"
|
||||
Write-Info " or download from: https://developer.hashicorp.com/vagrant/install"
|
||||
}
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
Write-Header "Vagrant Box (gusztavvargadr/windows-11)"
|
||||
# ============================================================================
|
||||
|
||||
if ($vagrantCmd) {
|
||||
$boxes = vagrant box list 2>$null
|
||||
if ($boxes -match "gusztavvargadr/windows-11") {
|
||||
Write-Ok "Windows 11 box available (cached locally)"
|
||||
} else {
|
||||
Write-Warn "Windows 11 box not cached locally"
|
||||
Write-Info "It will be auto-downloaded on first 'vagrant up' (~6 GB download)"
|
||||
Write-Info "To pre-download: vagrant box add gusztavvargadr/windows-11 --provider hyperv"
|
||||
|
||||
if ($Fix) {
|
||||
Write-Info "Pre-downloading Windows 11 box (this may take a while)..."
|
||||
vagrant box add gusztavvargadr/windows-11 --provider hyperv 2>$null
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
$script:Warnings--
|
||||
Write-Ok "Windows 11 box downloaded"
|
||||
} else {
|
||||
Write-Warn "Box download failed - will retry on 'vagrant up'"
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Warn "Cannot check box status (Vagrant not installed)"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
Write-Header "System Resources"
|
||||
# ============================================================================
|
||||
|
||||
# RAM check
|
||||
$totalRamGB = [math]::Round((Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory / 1GB)
|
||||
if ($totalRamGB -ge 16) {
|
||||
Write-Ok "RAM: ${totalRamGB} GB (8 GB allocated to VM, plenty for host)"
|
||||
} elseif ($totalRamGB -ge 8) {
|
||||
Write-Warn "RAM: ${totalRamGB} GB (VM uses up to 8 GB dynamic - may be tight)"
|
||||
Write-Info "Close memory-heavy applications before running the VM"
|
||||
} else {
|
||||
Write-Fail "RAM: ${totalRamGB} GB (minimum 8 GB required, 16 GB recommended)"
|
||||
}
|
||||
|
||||
# Disk space check
|
||||
$drive = (Get-Location).Drive
|
||||
$freeGB = [math]::Round((Get-PSDrive $drive.Name).Free / 1GB)
|
||||
if ($freeGB -ge 30) {
|
||||
Write-Ok "Disk space: ${freeGB} GB free on $($drive.Name): (30 GB needed)"
|
||||
} elseif ($freeGB -ge 15) {
|
||||
Write-Warn "Disk space: ${freeGB} GB free on $($drive.Name): (30 GB recommended)"
|
||||
} else {
|
||||
Write-Fail "Disk space: ${freeGB} GB free on $($drive.Name): (30 GB needed for VM)"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
Write-Header "Network (WinRM / PS Remoting)"
|
||||
# ============================================================================
|
||||
|
||||
# Check if WinRM client is configured to allow connections to the VM
|
||||
$trustedHosts = (Get-Item WSMan:\localhost\Client\TrustedHosts -ErrorAction SilentlyContinue).Value
|
||||
if ($trustedHosts -eq "*" -or $trustedHosts -match "172\.17\." -or $trustedHosts -match "detonation") {
|
||||
Write-Ok "WinRM TrustedHosts configured ($trustedHosts)"
|
||||
} else {
|
||||
Write-Warn "WinRM TrustedHosts may need configuration for PS Remoting to the VM"
|
||||
Write-Info "Current value: '$trustedHosts'"
|
||||
Write-Info "For 'make.ps1 deploy/services' to work, run (Admin):"
|
||||
Write-Info " Set-Item WSMan:\localhost\Client\TrustedHosts -Value '*' -Force"
|
||||
|
||||
if ($Fix -and $isAdmin) {
|
||||
Set-Item WSMan:\localhost\Client\TrustedHosts -Value '*' -Force
|
||||
$script:Warnings--
|
||||
Write-Ok "WinRM TrustedHosts set to '*'"
|
||||
}
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
Write-Header "Project Files"
|
||||
# ============================================================================
|
||||
|
||||
$projectDir = Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path)
|
||||
if (-not $projectDir) { $projectDir = Get-Location }
|
||||
|
||||
$requiredDirs = @("config", "webui", "rules", "scripts")
|
||||
foreach ($dir in $requiredDirs) {
|
||||
$path = Join-Path $projectDir $dir
|
||||
if (Test-Path $path) {
|
||||
Write-Ok "Directory exists: $dir\"
|
||||
} else {
|
||||
Write-Fail "Missing directory: $dir\"
|
||||
}
|
||||
}
|
||||
|
||||
$requiredFiles = @(
|
||||
"Vagrantfile",
|
||||
"config\rustinel-config.toml",
|
||||
"config\fibratus.yml",
|
||||
"webui\app.py",
|
||||
"webui\requirements.txt"
|
||||
)
|
||||
foreach ($file in $requiredFiles) {
|
||||
$path = Join-Path $projectDir $file
|
||||
if (Test-Path $path) {
|
||||
Write-Ok "File exists: $file"
|
||||
} else {
|
||||
Write-Fail "Missing file: $file"
|
||||
}
|
||||
}
|
||||
|
||||
# Check rules
|
||||
$sigmaCount = (Get-ChildItem -Path (Join-Path $projectDir "rules\sigma") -Filter "*.yml" -ErrorAction SilentlyContinue | Measure-Object).Count
|
||||
$yaraCount = (Get-ChildItem -Path (Join-Path $projectDir "rules\yara") -Filter "*.yar" -ErrorAction SilentlyContinue | Measure-Object).Count
|
||||
if ($sigmaCount -gt 0) {
|
||||
Write-Ok "Sigma rules: $sigmaCount files"
|
||||
} else {
|
||||
Write-Warn "No Sigma rules found in rules\sigma\"
|
||||
}
|
||||
if ($yaraCount -gt 0) {
|
||||
Write-Ok "YARA rules: $yaraCount files"
|
||||
} else {
|
||||
Write-Warn "No YARA rules found in rules\yara\"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
Write-Header "Summary"
|
||||
# ============================================================================
|
||||
|
||||
Write-Host ""
|
||||
if ($script:Errors -eq 0 -and $script:Warnings -eq 0) {
|
||||
Write-Host " All prerequisites met! Ready to run:" -ForegroundColor Green
|
||||
Write-Host " .\make.ps1 up" -ForegroundColor White
|
||||
Write-Host ""
|
||||
} elseif ($script:Errors -eq 0) {
|
||||
Write-Host " Prerequisites met with $($script:Warnings) warning(s)." -ForegroundColor Yellow
|
||||
Write-Host " You can proceed, but review the warnings above." -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
Write-Host " .\make.ps1 up" -ForegroundColor White
|
||||
Write-Host ""
|
||||
} else {
|
||||
Write-Host " $($script:Errors) error(s) and $($script:Warnings) warning(s) found." -ForegroundColor Red
|
||||
if (-not $Fix) {
|
||||
Write-Host ""
|
||||
Write-Host " Run with -Fix to auto-install missing dependencies:" -ForegroundColor Yellow
|
||||
Write-Host " .\scripts\check-prerequisites.ps1 -Fix" -ForegroundColor White
|
||||
}
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
exit $script:Errors
|
||||
@@ -0,0 +1,469 @@
|
||||
#!/usr/bin/env bash
|
||||
# check-prerequisites.sh
|
||||
# Checks and installs all prerequisites for the Transportable Detonation Chamber
|
||||
# on macOS with Apple Silicon (UTM/QEMU provider)
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/check-prerequisites.sh # Check only
|
||||
# ./scripts/check-prerequisites.sh --fix # Check and auto-install missing dependencies
|
||||
#
|
||||
# Prerequisites checked:
|
||||
# 1. macOS on Apple Silicon (M1/M2/M3/M4)
|
||||
# 2. Homebrew
|
||||
# 3. QEMU (with EFI firmware)
|
||||
# 4. Vagrant
|
||||
# 5. vagrant-qemu plugin
|
||||
# 6. Windows 11 ARM64 box (win11-arm)
|
||||
# 7. Sufficient disk space (80 GB)
|
||||
# 8. Sufficient RAM (16 GB recommended, 8 GB minimum)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# --- Colors ---
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[0;33m'
|
||||
CYAN='\033[0;36m'
|
||||
BOLD='\033[1m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# --- Globals ---
|
||||
FIX_MODE=false
|
||||
ERRORS=0
|
||||
WARNINGS=0
|
||||
|
||||
if [[ "${1:-}" == "--fix" || "${1:-}" == "-f" ]]; then
|
||||
FIX_MODE=true
|
||||
fi
|
||||
|
||||
# --- Helpers ---
|
||||
info() { echo -e "${CYAN}[*]${NC} $1"; }
|
||||
ok() { echo -e "${GREEN}[+]${NC} $1"; }
|
||||
warn() { echo -e "${YELLOW}[!]${NC} $1"; ((WARNINGS++)); }
|
||||
fail() { echo -e "${RED}[-]${NC} $1"; ((ERRORS++)); }
|
||||
header() { echo -e "\n${BOLD}--- $1 ---${NC}"; }
|
||||
|
||||
# --- ISO download helper ---
|
||||
WIN11_ISO_DIR="$HOME/.cache/detonation-chamber"
|
||||
WIN11_ISO_NAME="Win11_ARM64.iso"
|
||||
WIN11_ISO_PATH="$WIN11_ISO_DIR/$WIN11_ISO_NAME"
|
||||
# Microsoft's UUP dump or direct download URL for Windows 11 ARM64 evaluation
|
||||
# Note: Microsoft doesn't provide a direct stable URL for ARM64 ISOs.
|
||||
# Users need to get it from: https://www.microsoft.com/software-download/windows11arm64
|
||||
# or via UUP dump: https://uupdump.net/
|
||||
WIN11_DOWNLOAD_PAGE="https://www.microsoft.com/software-download/windows11arm64"
|
||||
|
||||
# ============================================================================
|
||||
header "Platform Detection"
|
||||
# ============================================================================
|
||||
|
||||
# Check macOS
|
||||
if [[ "$(uname -s)" != "Darwin" ]]; then
|
||||
fail "This script is for macOS. On Windows, use: .\\scripts\\check-prerequisites.ps1"
|
||||
exit 1
|
||||
fi
|
||||
ok "macOS detected"
|
||||
|
||||
# Check Apple Silicon
|
||||
ARCH=$(uname -m)
|
||||
if [[ "$ARCH" != "arm64" ]]; then
|
||||
fail "Apple Silicon (ARM64) required. Detected: $ARCH"
|
||||
fail "The UTM/QEMU setup requires an M1/M2/M3/M4 Mac"
|
||||
exit 1
|
||||
fi
|
||||
ok "Apple Silicon ($ARCH) detected"
|
||||
|
||||
# ============================================================================
|
||||
header "Homebrew"
|
||||
# ============================================================================
|
||||
|
||||
if command -v brew &>/dev/null; then
|
||||
BREW_VERSION=$(brew --version | head -1)
|
||||
ok "Homebrew installed ($BREW_VERSION)"
|
||||
else
|
||||
fail "Homebrew not installed"
|
||||
if $FIX_MODE; then
|
||||
info "Installing Homebrew..."
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
eval "$(/opt/homebrew/bin/brew shellenv)"
|
||||
ok "Homebrew installed"
|
||||
((ERRORS--))
|
||||
else
|
||||
info "Install with: /bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""
|
||||
fi
|
||||
fi
|
||||
|
||||
# ============================================================================
|
||||
header "QEMU"
|
||||
# ============================================================================
|
||||
|
||||
if command -v qemu-system-aarch64 &>/dev/null; then
|
||||
QEMU_VERSION=$(qemu-system-aarch64 --version | head -1)
|
||||
ok "QEMU installed ($QEMU_VERSION)"
|
||||
else
|
||||
fail "QEMU not installed"
|
||||
if $FIX_MODE; then
|
||||
info "Installing QEMU via Homebrew..."
|
||||
brew install qemu
|
||||
ok "QEMU installed"
|
||||
((ERRORS--))
|
||||
else
|
||||
info "Install with: brew install qemu"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check EFI firmware
|
||||
EFI_PATH="/opt/homebrew/share/qemu/edk2-aarch64-code.fd"
|
||||
if [[ -f "$EFI_PATH" ]]; then
|
||||
ok "EFI firmware found: $EFI_PATH"
|
||||
else
|
||||
# Try alternate locations
|
||||
ALT_EFI="/usr/local/share/qemu/edk2-aarch64-code.fd"
|
||||
if [[ -f "$ALT_EFI" ]]; then
|
||||
ok "EFI firmware found: $ALT_EFI"
|
||||
warn "EFI firmware is at $ALT_EFI, but Vagrantfile.utm expects $EFI_PATH"
|
||||
info "You may need to update Vagrantfile.utm or create a symlink"
|
||||
else
|
||||
fail "EFI firmware not found at $EFI_PATH"
|
||||
if $FIX_MODE; then
|
||||
info "Reinstalling QEMU to ensure firmware files are present..."
|
||||
brew reinstall qemu
|
||||
if [[ -f "$EFI_PATH" ]]; then
|
||||
ok "EFI firmware now available"
|
||||
((ERRORS--))
|
||||
else
|
||||
fail "EFI firmware still not found after reinstall"
|
||||
fi
|
||||
else
|
||||
info "This should be installed with QEMU. Try: brew reinstall qemu"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# ============================================================================
|
||||
header "Vagrant"
|
||||
# ============================================================================
|
||||
|
||||
if command -v vagrant &>/dev/null; then
|
||||
VAGRANT_VERSION=$(vagrant --version)
|
||||
ok "Vagrant installed ($VAGRANT_VERSION)"
|
||||
else
|
||||
fail "Vagrant not installed"
|
||||
if $FIX_MODE; then
|
||||
info "Installing Vagrant via Homebrew..."
|
||||
brew install --cask vagrant
|
||||
ok "Vagrant installed"
|
||||
((ERRORS--))
|
||||
else
|
||||
info "Install with: brew install --cask vagrant"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check vagrant-qemu plugin
|
||||
if command -v vagrant &>/dev/null; then
|
||||
if vagrant plugin list 2>/dev/null | grep -q "vagrant-qemu"; then
|
||||
PLUGIN_VERSION=$(vagrant plugin list 2>/dev/null | grep "vagrant-qemu" | awk '{print $2}')
|
||||
ok "vagrant-qemu plugin installed $PLUGIN_VERSION"
|
||||
else
|
||||
fail "vagrant-qemu plugin not installed"
|
||||
if $FIX_MODE; then
|
||||
info "Installing vagrant-qemu plugin..."
|
||||
vagrant plugin install vagrant-qemu
|
||||
ok "vagrant-qemu plugin installed"
|
||||
((ERRORS--))
|
||||
else
|
||||
info "Install with: vagrant plugin install vagrant-qemu"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# ============================================================================
|
||||
header "Windows 11 ARM64 Vagrant Box"
|
||||
# ============================================================================
|
||||
|
||||
if command -v vagrant &>/dev/null; then
|
||||
if vagrant box list 2>/dev/null | grep -q "win11-arm"; then
|
||||
BOX_INFO=$(vagrant box list 2>/dev/null | grep "win11-arm")
|
||||
ok "win11-arm box found: $BOX_INFO"
|
||||
else
|
||||
fail "win11-arm Vagrant box not found"
|
||||
echo ""
|
||||
info "A Windows 11 ARM64 Vagrant box is required. Options:"
|
||||
echo ""
|
||||
echo " Option A - Download ISO and build with Packer (recommended):"
|
||||
echo " 1. Download Windows 11 ARM64 ISO from:"
|
||||
echo " $WIN11_DOWNLOAD_PAGE"
|
||||
echo " 2. Use this script with --fix to set up the Packer build"
|
||||
echo ""
|
||||
echo " Option B - Import a pre-built .box file:"
|
||||
echo " vagrant box add win11-arm /path/to/windows11-arm.box --provider qemu"
|
||||
echo ""
|
||||
echo " Option C - Create manually in UTM, then package:"
|
||||
echo " 1. Create Windows 11 ARM VM in UTM"
|
||||
echo " 2. Install & configure WinRM:"
|
||||
echo " winrm quickconfig -force"
|
||||
echo " winrm set winrm/config/service '@{AllowUnencrypted=\"true\"}'"
|
||||
echo " winrm set winrm/config/service/auth '@{Basic=\"true\"}'"
|
||||
echo " 3. Create vagrant user (password: vagrant) with admin rights"
|
||||
echo " 4. Export QCOW2 and package:"
|
||||
echo " vagrant package --base <vm-name> --output win11-arm.box"
|
||||
echo ""
|
||||
|
||||
if $FIX_MODE; then
|
||||
echo ""
|
||||
info "Checking for Windows 11 ARM64 ISO..."
|
||||
mkdir -p "$WIN11_ISO_DIR"
|
||||
|
||||
if [[ -f "$WIN11_ISO_PATH" ]]; then
|
||||
ok "ISO already downloaded: $WIN11_ISO_PATH"
|
||||
else
|
||||
# Check if user has an ISO anywhere obvious
|
||||
FOUND_ISO=""
|
||||
for search_dir in "$HOME/Downloads" "$HOME/Desktop" "$HOME/Documents"; do
|
||||
if [[ -d "$search_dir" ]]; then
|
||||
found=$(find "$search_dir" -maxdepth 2 -iname "*win*11*arm*iso" -o -iname "*windows*11*arm*iso" 2>/dev/null | head -1)
|
||||
if [[ -n "$found" ]]; then
|
||||
FOUND_ISO="$found"
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -n "$FOUND_ISO" ]]; then
|
||||
info "Found existing ISO: $FOUND_ISO"
|
||||
info "Copying to cache directory..."
|
||||
cp "$FOUND_ISO" "$WIN11_ISO_PATH"
|
||||
ok "ISO cached at: $WIN11_ISO_PATH"
|
||||
else
|
||||
warn "No Windows 11 ARM64 ISO found locally."
|
||||
echo ""
|
||||
echo " Microsoft requires manual download (no direct URL available)."
|
||||
echo " Please download from: $WIN11_DOWNLOAD_PAGE"
|
||||
echo ""
|
||||
echo " After downloading, either:"
|
||||
echo " - Place it in ~/Downloads/ and re-run this script with --fix"
|
||||
echo " - Or copy it to: $WIN11_ISO_PATH"
|
||||
echo ""
|
||||
|
||||
# Attempt to open the download page in the browser
|
||||
info "Opening Microsoft download page in browser..."
|
||||
open "$WIN11_DOWNLOAD_PAGE" 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
|
||||
# If we have the ISO, offer to set up Packer
|
||||
if [[ -f "$WIN11_ISO_PATH" ]]; then
|
||||
echo ""
|
||||
info "ISO available. Setting up Packer build environment..."
|
||||
|
||||
# Check for Packer
|
||||
if ! command -v packer &>/dev/null; then
|
||||
info "Installing Packer via Homebrew..."
|
||||
brew install hashicorp/tap/packer
|
||||
fi
|
||||
|
||||
# Create a minimal Packer template for Windows 11 ARM64
|
||||
PACKER_DIR="$WIN11_ISO_DIR/packer-win11-arm"
|
||||
mkdir -p "$PACKER_DIR"
|
||||
|
||||
if [[ ! -f "$PACKER_DIR/win11-arm.pkr.hcl" ]]; then
|
||||
cat > "$PACKER_DIR/win11-arm.pkr.hcl" << 'PACKER_EOF'
|
||||
# Packer template for Windows 11 ARM64 Vagrant box (QEMU provider)
|
||||
# This creates a minimal Windows 11 ARM64 box with WinRM enabled
|
||||
#
|
||||
# Usage:
|
||||
# cd ~/.cache/detonation-chamber/packer-win11-arm
|
||||
# packer init .
|
||||
# packer build .
|
||||
# vagrant box add win11-arm output/win11-arm.box --provider qemu
|
||||
|
||||
packer {
|
||||
required_plugins {
|
||||
qemu = {
|
||||
version = ">= 1.1.0"
|
||||
source = "github.com/hashicorp/qemu"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variable "iso_path" {
|
||||
type = string
|
||||
default = "../Win11_ARM64.iso"
|
||||
}
|
||||
|
||||
variable "output_dir" {
|
||||
type = string
|
||||
default = "output"
|
||||
}
|
||||
|
||||
source "qemu" "win11-arm" {
|
||||
iso_url = var.iso_path
|
||||
iso_checksum = "none"
|
||||
output_directory = var.output_dir
|
||||
vm_name = "win11-arm.qcow2"
|
||||
|
||||
accelerator = "hvf"
|
||||
machine_type = "virt,highmem=on"
|
||||
cpu_type = "host"
|
||||
|
||||
memory = 4096
|
||||
cpus = 4
|
||||
disk_size = "80G"
|
||||
|
||||
qemu_binary = "qemu-system-aarch64"
|
||||
qemuargs = [
|
||||
["-bios", "/opt/homebrew/share/qemu/edk2-aarch64-code.fd"],
|
||||
["-device", "virtio-gpu-pci"],
|
||||
["-device", "qemu-xhci"],
|
||||
["-device", "usb-kbd"],
|
||||
["-device", "usb-tablet"],
|
||||
["-drive", "file=${var.iso_path},media=cdrom,if=none,id=cdrom0"],
|
||||
["-device", "usb-storage,drive=cdrom0"],
|
||||
]
|
||||
|
||||
communicator = "winrm"
|
||||
winrm_username = "vagrant"
|
||||
winrm_password = "vagrant"
|
||||
winrm_timeout = "60m"
|
||||
|
||||
boot_wait = "5s"
|
||||
shutdown_command = "shutdown /s /t 10 /f"
|
||||
}
|
||||
|
||||
build {
|
||||
sources = ["source.qemu.win11-arm"]
|
||||
|
||||
# Enable WinRM and configure vagrant user
|
||||
provisioner "powershell" {
|
||||
inline = [
|
||||
"Set-ExecutionPolicy Bypass -Scope Process -Force",
|
||||
"winrm quickconfig -force",
|
||||
"winrm set winrm/config/service '@{AllowUnencrypted=\"true\"}'",
|
||||
"winrm set winrm/config/service/auth '@{Basic=\"true\"}'",
|
||||
"Set-ItemProperty -Path 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System' -Name 'LocalAccountTokenFilterPolicy' -Value 1 -Force",
|
||||
]
|
||||
}
|
||||
|
||||
post-processor "vagrant" {
|
||||
output = "${var.output_dir}/win11-arm.box"
|
||||
vagrantfile_template = null
|
||||
provider_override = "qemu"
|
||||
}
|
||||
}
|
||||
PACKER_EOF
|
||||
ok "Packer template created at: $PACKER_DIR/win11-arm.pkr.hcl"
|
||||
echo ""
|
||||
info "To build the box:"
|
||||
echo " cd $PACKER_DIR"
|
||||
echo " packer init ."
|
||||
echo " packer build ."
|
||||
echo " vagrant box add win11-arm output/win11-arm.box --provider qemu"
|
||||
echo ""
|
||||
warn "NOTE: Windows 11 ARM64 ISO requires manual interaction during install."
|
||||
info "For a fully automated build, you need an Autounattend.xml file."
|
||||
info "See: https://github.com/StefanScherer/packer-windows for reference templates."
|
||||
else
|
||||
ok "Packer template already exists at: $PACKER_DIR/win11-arm.pkr.hcl"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# ============================================================================
|
||||
header "System Resources"
|
||||
# ============================================================================
|
||||
|
||||
# Check available disk space
|
||||
DISK_AVAIL_GB=$(df -g . | awk 'NR==2 {print $4}')
|
||||
if [[ "$DISK_AVAIL_GB" -ge 80 ]]; then
|
||||
ok "Disk space: ${DISK_AVAIL_GB} GB available (80 GB needed)"
|
||||
elif [[ "$DISK_AVAIL_GB" -ge 40 ]]; then
|
||||
warn "Disk space: ${DISK_AVAIL_GB} GB available (80 GB recommended, may be tight)"
|
||||
else
|
||||
fail "Disk space: ${DISK_AVAIL_GB} GB available (80 GB needed for VM disk)"
|
||||
fi
|
||||
|
||||
# Check RAM
|
||||
TOTAL_RAM_GB=$(( $(sysctl -n hw.memsize) / 1073741824 ))
|
||||
if [[ "$TOTAL_RAM_GB" -ge 16 ]]; then
|
||||
ok "RAM: ${TOTAL_RAM_GB} GB total (8 GB allocated to VM)"
|
||||
elif [[ "$TOTAL_RAM_GB" -ge 8 ]]; then
|
||||
warn "RAM: ${TOTAL_RAM_GB} GB total (8 GB allocated to VM - this leaves little for macOS)"
|
||||
info "Consider reducing VM memory in Vagrantfile.utm if you experience issues"
|
||||
else
|
||||
fail "RAM: ${TOTAL_RAM_GB} GB total (minimum 8 GB needed, 16 GB recommended)"
|
||||
fi
|
||||
|
||||
# ============================================================================
|
||||
header "Project Files"
|
||||
# ============================================================================
|
||||
|
||||
# Check that required directories exist
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
|
||||
REQUIRED_DIRS=("config" "webui" "rules" "scripts")
|
||||
for dir in "${REQUIRED_DIRS[@]}"; do
|
||||
if [[ -d "$PROJECT_DIR/$dir" ]]; then
|
||||
ok "Directory exists: $dir/"
|
||||
else
|
||||
fail "Missing directory: $dir/"
|
||||
fi
|
||||
done
|
||||
|
||||
# Check key files
|
||||
REQUIRED_FILES=(
|
||||
"Vagrantfile.utm"
|
||||
"config/rustinel-config.toml"
|
||||
"config/fibratus.yml"
|
||||
"webui/app.py"
|
||||
"webui/requirements.txt"
|
||||
)
|
||||
for file in "${REQUIRED_FILES[@]}"; do
|
||||
if [[ -f "$PROJECT_DIR/$file" ]]; then
|
||||
ok "File exists: $file"
|
||||
else
|
||||
fail "Missing file: $file"
|
||||
fi
|
||||
done
|
||||
|
||||
# Check rules directory has content
|
||||
SIGMA_COUNT=$(find "$PROJECT_DIR/rules/sigma" -name "*.yml" 2>/dev/null | wc -l | tr -d ' ')
|
||||
YARA_COUNT=$(find "$PROJECT_DIR/rules/yara" -name "*.yar" 2>/dev/null | wc -l | tr -d ' ')
|
||||
if [[ "$SIGMA_COUNT" -gt 0 ]]; then
|
||||
ok "Sigma rules: $SIGMA_COUNT files"
|
||||
else
|
||||
warn "No Sigma rules found in rules/sigma/"
|
||||
fi
|
||||
if [[ "$YARA_COUNT" -gt 0 ]]; then
|
||||
ok "YARA rules: $YARA_COUNT files"
|
||||
else
|
||||
warn "No YARA rules found in rules/yara/"
|
||||
fi
|
||||
|
||||
# ============================================================================
|
||||
header "Summary"
|
||||
# ============================================================================
|
||||
|
||||
echo ""
|
||||
if [[ $ERRORS -eq 0 && $WARNINGS -eq 0 ]]; then
|
||||
echo -e "${GREEN}${BOLD}All prerequisites met! Ready to run:${NC}"
|
||||
echo " make up"
|
||||
echo " # or: VAGRANT_VAGRANTFILE=Vagrantfile.utm vagrant up --provider=qemu"
|
||||
elif [[ $ERRORS -eq 0 ]]; then
|
||||
echo -e "${YELLOW}${BOLD}Prerequisites met with $WARNINGS warning(s).${NC}"
|
||||
echo "You can proceed, but review the warnings above."
|
||||
echo ""
|
||||
echo " make up"
|
||||
else
|
||||
echo -e "${RED}${BOLD}$ERRORS error(s) and $WARNINGS warning(s) found.${NC}"
|
||||
if ! $FIX_MODE; then
|
||||
echo ""
|
||||
echo "Run with --fix to auto-install missing dependencies:"
|
||||
echo " ./scripts/check-prerequisites.sh --fix"
|
||||
fi
|
||||
fi
|
||||
echo ""
|
||||
|
||||
exit $ERRORS
|
||||
@@ -67,12 +67,12 @@ function Register-ServiceTask {
|
||||
Write-Host "`n--- Configuring Firewall ---" -ForegroundColor Cyan
|
||||
# Remove old rules and create consolidated one
|
||||
Get-NetFirewallRule -DisplayName "Detonation Chamber*" -ErrorAction SilentlyContinue | Remove-NetFirewallRule -ErrorAction SilentlyContinue
|
||||
New-NetFirewallRule -DisplayName "Detonation Chamber - All Services" -Direction Inbound -LocalPort 5000,8000,8080,9000,1337 -Protocol TCP -Action Allow -Profile Any -ErrorAction SilentlyContinue | Out-Null
|
||||
New-NetFirewallRule -DisplayName "Detonation Chamber - All Services" -Direction Inbound -LocalPort 5000,8000,8080,9000,1337,8888 -Protocol TCP -Action Allow -Profile Any -ErrorAction SilentlyContinue | Out-Null
|
||||
# Program-level rule for Python processes
|
||||
New-NetFirewallRule -DisplayName "Detonation Chamber - Python" -Direction Inbound -Program "C:\DetonationChamberUI\venv\Scripts\python.exe" -Action Allow -Profile Any -ErrorAction SilentlyContinue | Out-Null
|
||||
New-NetFirewallRule -DisplayName "Detonation Chamber - Python (Detonator)" -Direction Inbound -Program "C:\detonator\.venv\Scripts\python.exe" -Action Allow -Profile Any -ErrorAction SilentlyContinue | Out-Null
|
||||
New-NetFirewallRule -DisplayName "Detonation Chamber - Python (LitterBox)" -Direction Inbound -Program "C:\LitterBox\venv\Scripts\python.exe" -Action Allow -Profile Any -ErrorAction SilentlyContinue | Out-Null
|
||||
Write-Host "[+] Firewall rules configured for ports 5000, 8000, 8080, 9000, 1337" -ForegroundColor Green
|
||||
Write-Host "[+] Firewall rules configured for ports 5000, 8000, 8080, 9000, 1337, 8888" -ForegroundColor Green
|
||||
|
||||
# --- Sample / Infected folder ---
|
||||
Write-Host "`n--- Sample Directories ---" -ForegroundColor Cyan
|
||||
|
||||
Reference in New Issue
Block a user