Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions HBV-Core.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -38,6 +39,10 @@ param(

[string]$HuntSummaryPath,

[switch]$RunHealthCheck,

[string]$HealthReportPath,

[switch]$DryRun,

[switch]$Quiet
Expand Down Expand Up @@ -87,6 +92,7 @@ $summary = [ordered]@{
UndoScript = $null
RepoSnapshot = $null
HuntSummary = $null
HealthReport = $null
DryRun = [bool]$DryRun
Timestamp = Get-Date
}
Expand Down Expand Up @@ -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') ==="
Expand Down
182 changes: 182 additions & 0 deletions HBV-HealthCheck.ps1
Original file line number Diff line number Diff line change
@@ -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.'
}
Comment on lines +27 to +29

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0 Badge Guard clause rejects PowerShell 5.1 on Windows

The new module immediately throws when $IsWindows is falsey, but $IsWindows is only defined in PowerShell 6+. On the default Windows PowerShell 5.1 the variable is $null, so this check always throws and the health check cannot run on supported Windows hosts. Consider using [Environment]::OSVersion.Platform or Get-CimInstance Win32_OperatingSystem to detect non‑Windows systems instead of relying on $IsWindows.

Useful? React with 👍 / 👎.


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
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand All @@ -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.