From 5c0654d07a56ebbd5399eba9f3714f6655ced243 Mon Sep 17 00:00:00 2001 From: MoSLoF <166967622+MoSLoF@users.noreply.github.com> Date: Tue, 11 Nov 2025 19:05:46 -0600 Subject: [PATCH] Add health check workflow integration --- HBV-Core.ps1 | 15 ++++ HBV-HealthCheck.ps1 | 182 ++++++++++++++++++++++++++++++++++++++++++++ README.md | 15 +++- 3 files changed, 211 insertions(+), 1 deletion(-) create mode 100644 HBV-HealthCheck.ps1 diff --git a/HBV-Core.ps1 b/HBV-Core.ps1 index 984004a..27a0935 100644 --- a/HBV-Core.ps1 +++ b/HBV-Core.ps1 @@ -9,6 +9,7 @@ • Optionally generates an undo script for the last posture change. • Drives repo_hunter.ps1 to maintain a local threat-intel snapshot. • Summarises hunting artefacts with auto_parse_hunting_results.ps1. + • Captures environment readiness reports through HBV-HealthCheck.ps1. The script writes an execution log under %USERPROFILE%\HoneyCoreLogs and returns a summary object for automation scenarios. @@ -38,6 +39,10 @@ param( [string]$HuntSummaryPath, + [switch]$RunHealthCheck, + + [string]$HealthReportPath, + [switch]$DryRun, [switch]$Quiet @@ -87,6 +92,7 @@ $summary = [ordered]@{ UndoScript = $null RepoSnapshot = $null HuntSummary = $null + HealthReport = $null DryRun = [bool]$DryRun Timestamp = Get-Date } @@ -176,6 +182,15 @@ try { $summary.HuntSummary = $huntResult.OutputPath } } + + if ($RunHealthCheck) { + $healthArgs = @{ Quiet = $true } + if ($HealthReportPath) { $healthArgs.OutputPath = $HealthReportPath } + $healthResult = Invoke-HBVModule -ScriptPath (Get-ModulePath 'HBV-HealthCheck.ps1') -Arguments $healthArgs + if ($healthResult) { + $summary.HealthReport = $healthResult + } + } } finally { Write-CoreLog -Message "=== HBV-Core completed @ $(Get-Date -Format 's') ===" diff --git a/HBV-HealthCheck.ps1 b/HBV-HealthCheck.ps1 new file mode 100644 index 0000000..cd75dd0 --- /dev/null +++ b/HBV-HealthCheck.ps1 @@ -0,0 +1,182 @@ +<# +.SYNOPSIS + Performs baseline environment validation for HoneyBadger Vanguard workflows. +.DESCRIPTION + HBV-HealthCheck.ps1 inspects a host and reports on prerequisites that help + the other automation entry points succeed. The script focuses on checks + that frequently break hardened lab deployments: + • PowerShell version and architecture details. + • Administrative privileges. + • Availability of networking cmdlets relied on by PimpMyWindows.ps1. + • Microsoft Defender service state (when present). + • Git availability for repo_hunter.ps1 cloning operations. + + Results are returned as an object for automation but can also be written to + a JSON file under %USERPROFILE%\HoneyCoreLogs by default. +#> + +[CmdletBinding()] +param( + [string]$OutputPath, + + [switch]$NoExport, + + [switch]$Quiet +) + +if (-not $IsWindows) { + throw 'HBV-HealthCheck.ps1 must be executed on a Windows host.' +} + +function Test-HBVAdministrator { + try { + $identity = [Security.Principal.WindowsIdentity]::GetCurrent() + $principal = [Security.Principal.WindowsPrincipal]::new($identity) + return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) + } + catch { + return $false + } +} + +function Get-HBVLogDirectory { + param([string]$Path) + if (-not (Test-Path -Path $Path)) { + New-Item -ItemType Directory -Path $Path -Force | Out-Null + } + return (Resolve-Path -Path $Path).Path +} + +$logRoot = Join-Path -Path $env:USERPROFILE -ChildPath 'HoneyCoreLogs' +if (-not $OutputPath -and -not $NoExport) { + $OutputPath = Join-Path -Path $logRoot -ChildPath ("HBV-HealthCheck-{0}.json" -f (Get-Date -Format 'yyyyMMdd-HHmmss')) +} + +$checks = New-Object System.Collections.Generic.List[object] + +function Add-HBVCheck { + param( + [string]$Name, + [ValidateSet('Pass', 'Warn', 'Fail', 'Info')] + [string]$Status, + [string]$Detail + ) + + $checks.Add([PSCustomObject]@{ + Name = $Name + Status = $Status + Detail = $Detail + }) | Out-Null +} + +$psVersion = $PSVersionTable.PSVersion +$versionStatus = if ($psVersion.Major -gt 5 -or ($psVersion.Major -eq 5 -and $psVersion.Minor -ge 1)) { 'Pass' } else { 'Warn' } +Add-HBVCheck -Name 'PowerShell Version' -Status $versionStatus -Detail "Detected version: $psVersion" + +$bitness = if ([Environment]::Is64BitProcess) { '64-bit' } else { '32-bit' } +Add-HBVCheck -Name 'PowerShell Architecture' -Status 'Info' -Detail "Process architecture: $bitness" + +$osInfo = $null +try { + $osInfo = Get-CimInstance -ClassName Win32_OperatingSystem -ErrorAction Stop + Add-HBVCheck -Name 'Operating System' -Status 'Info' -Detail "$($osInfo.Caption) ($($osInfo.Version))" +} +catch { + Add-HBVCheck -Name 'Operating System' -Status 'Warn' -Detail "Unable to query OS details: $_" +} + +if (Test-HBVAdministrator) { + Add-HBVCheck -Name 'Administrator Rights' -Status 'Pass' -Detail 'Current process is elevated.' +} +else { + Add-HBVCheck -Name 'Administrator Rights' -Status 'Warn' -Detail 'Not running with administrative privileges. Some modules require elevation.' +} + +if (Get-Command -Name Get-NetConnectionProfile -ErrorAction SilentlyContinue) { + try { + $profiles = Get-NetConnectionProfile -ErrorAction Stop + $profileSummary = if ($profiles) { + ($profiles | Select-Object -First 3 | ForEach-Object { + if ($_.Name) { $_.Name } elseif ($_.InterfaceAlias) { $_.InterfaceAlias } else { "InterfaceIndex:$($_.InterfaceIndex)" } + }) -join ', ' + } else { + 'No active profiles detected.' + } + Add-HBVCheck -Name 'NetTCPIP Module' -Status 'Pass' -Detail "Get-NetConnectionProfile accessible. Sample: $profileSummary" + } + catch { + Add-HBVCheck -Name 'NetTCPIP Module' -Status 'Warn' -Detail "Cmdlet available but failed to enumerate profiles: $_" + } +} +else { + Add-HBVCheck -Name 'NetTCPIP Module' -Status 'Warn' -Detail 'Get-NetConnectionProfile cmdlet not available. Network posture enforcement will be skipped.' +} + +try { + $defenderService = Get-Service -Name 'WinDefend' -ErrorAction Stop + $status = if ($defenderService.Status -eq 'Running') { 'Pass' } else { 'Warn' } + Add-HBVCheck -Name 'Microsoft Defender' -Status $status -Detail "Service state: $($defenderService.Status)" +} +catch { + Add-HBVCheck -Name 'Microsoft Defender' -Status 'Info' -Detail 'Service not found. Defender-specific actions will be skipped.' +} + +$git = Get-Command git -ErrorAction SilentlyContinue +if ($git) { + Add-HBVCheck -Name 'Git Availability' -Status 'Pass' -Detail "git located at $($git.Source)" +} +else { + Add-HBVCheck -Name 'Git Availability' -Status 'Warn' -Detail 'git executable not found in PATH. repo_hunter cloning will be disabled.' +} + +$report = [ordered]@{ + Generated = Get-Date + Computer = $env:COMPUTERNAME + Checks = $checks + ExportPath = $null +} + +if ($OutputPath -and -not $NoExport) { + $resolvedPath = if ([IO.Path]::IsPathRooted($OutputPath)) { + $OutputPath + } + else { + Join-Path -Path (Get-Location) -ChildPath $OutputPath + } + + try { + $directory = Split-Path -Path $resolvedPath -Parent + if ($directory) { + $resolvedDirectory = Get-HBVLogDirectory -Path $directory + $resolvedPath = Join-Path -Path $resolvedDirectory -ChildPath (Split-Path -Path $resolvedPath -Leaf) + } + $report.ExportPath = $resolvedPath + $report | ConvertTo-Json -Depth 5 | Out-File -FilePath $resolvedPath -Encoding utf8 + if (-not $Quiet) { + Write-Host "[HBV-HealthCheck] Report exported to $resolvedPath" -ForegroundColor Green + } + } + catch { + Add-HBVCheck -Name 'Report Export' -Status 'Warn' -Detail "Failed to write report to $resolvedPath : $_" + $report.ExportPath = $null + } +} +elseif ($NoExport) { + if (-not $Quiet) { + Write-Host '[HBV-HealthCheck] Export suppressed via -NoExport.' -ForegroundColor Yellow + } +} + +if (-not $Quiet) { + foreach ($check in $checks) { + $color = switch ($check.Status) { + 'Pass' { 'Green' } + 'Info' { 'Gray' } + 'Warn' { 'Yellow' } + 'Fail' { 'Red' } + } + Write-Host ("[{0}] {1} - {2}" -f $check.Status, $check.Name, $check.Detail) -ForegroundColor $color + } +} + +[PSCustomObject]$report diff --git a/README.md b/README.md index 5eb4097..0c90128 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ _Automates hardened lab environments, adversary emulation, and detection validat |--------|---------| | `PimpMyWindows.ps1` | GUI to toggle Secure Mode or Tradecraft Mode on Windows 11 | | `HBV-Core.ps1` | Master script for system tuning, logging, exclusions | +| `HBV-HealthCheck.ps1` | Validates host prerequisites and exports a readiness report | | `BOF_Hunter_GUI.ps1` | YARA + Volatility GUI for BOF memory triage | | `repo_hunter.ps1` | Clones & parses top cyber threat repos | | `auto_parse_hunting_results.ps1` | Builds Sigma/YARA rules from hunting results | @@ -47,7 +48,19 @@ _Automates hardened lab environments, adversary emulation, and detection validat .\BOF_Hunter_GUI.ps1 ``` -4. Auto-generate detection rules: +4. Validate the host posture: + ```powershell + .\HBV-HealthCheck.ps1 + ``` + +5. Auto-generate detection rules: ```powershell .\auto_parse_hunting_results.ps1 ``` + +## 🔍 Health Check Insights + +`HBV-HealthCheck.ps1` inspects the local workstation for common lab misconfigurations before you launch a full orchestration run. +It highlights missing prerequisites (such as Git or networking cmdlets) and exports a JSON report to `%USERPROFILE%\HoneyCoreLogs` that +can be archived with other HBV artefacts. Use the `-NoExport` switch to suppress file output or provide `-OutputPath` to control +where the report is written.