Skip to content

Latest commit

Β 

History

History
319 lines (237 loc) Β· 11.7 KB

File metadata and controls

319 lines (237 loc) Β· 11.7 KB

Contributing to WinFIRE πŸ”₯

Thank you for your interest in contributing to WinFIRE β€” the Windows Forensic Investigation & Response Engine. This guide will help you get started.

GitHub Issues GitHub Pull Requests

Repository: https://github.com/Masriyan/WinFire/

πŸ“‹ Table of Contents

🀝 Ways to Contribute

πŸ› Reporting Bugs

  1. Search existing issues first
  2. Create a new issue with:
    • Title: Clear, descriptive summary
    • Environment: Windows version, PowerShell version, WinFIRE version ($script:Version)
    • Steps to Reproduce: Detailed reproduction steps and the exact flags used
    • Expected vs Actual: What you expected vs what happened
    • Logs: Relevant lines from the case folder's winfire.log

πŸ’‘ Feature Requests

  1. Open an issue with the enhancement label
  2. Describe:
    • Forensic Value: Why is this artifact / detection important?
    • Use Case: When would an investigator need this?
    • Data Source: Where does the data come from (API, binary, registry, EVTX…)?
    • Findings: What severity / MITRE ATT&CK techniques would it emit?

πŸ“– Documentation Improvements

  • Fix typos or clarify existing documentation
  • Add usage examples or forensic context to usage-sample.md
  • Translate documentation to other languages

πŸ› οΈ Development Setup

Prerequisites

  • Windows 10/11 or Windows Server 2016+ (modules can be exercised cross-platform under PowerShell 7 with WINFIRE_ALLOW_NONWINDOWS=1; Windows-only probes simply collect nothing)
  • PowerShell 5.1+ (Windows PowerShell) or PowerShell 7
  • Pester and PSScriptAnalyzer for tests/lint
  • Git for version control
  • Administrator privileges for testing full coverage
Install-Module Pester, PSScriptAnalyzer -Scope CurrentUser

Setup Steps

# 1. Fork the repository on GitHub

# 2. Clone your fork
git clone https://github.com/YOUR-USERNAME/WinFire.git
cd WinFire

# 3. Add upstream remote
git remote add upstream https://github.com/Masriyan/WinFire.git

# 4. Create a feature branch
git checkout -b feature/your-feature-name

# 5. Keep your fork updated
git fetch upstream
git merge upstream/main

🧭 Architecture in 60 Seconds

WinFIRE.ps1 is a thin orchestrator. It owns a module registry ($script:Modules) that is the single source of truth for dispatch, -ListModules, and the docs. Each entry names a modules\*.psm1 file, the phase, the tools it needs, a Selected scriptblock (which flags turn it on), and an Invoke scriptblock (its entrypoint).

Every module receives the shared Context (Initialize-WinFIRESession) and returns zero or more normalized finding objects built with New-WinFIREFinding. The orchestrator collects them, and Report.psm1 + Mitre.psm1 render report.html + findings.json.

Core helpers you should reuse (all in modules/Core.psm1):

Helper Purpose
Write-WinFIRELog -Level INFO -Message … Console + winfire.log logging (-Quiet aware)
Invoke-WinFIRESafeOp -Name … -Operation { … } Non-terminating wrapper: logs, times, returns $null on failure
New-WinFIREFinding -Module … -Severity … -Title … The one normalized finding shape consumed by reporting
Save-WinFIREData -Context $ctx -Name … Persist raw objects to raw\ as JSON (+CSV when tabular)
Resolve-WinFIRETool -Context $ctx -Name yara Locate a bundled binary; returns $null so the module can degrade gracefully
Get-WinFIREFileHash, Invoke-WinFIREParallel, Test-WinFIREAdmin Hashing, PS5.1-compatible runspace fan-out, privilege checks

πŸ“ Code Guidelines

Naming Conventions

Element Convention Example
Module entrypoint Invoke-WinFIRE<Name> Invoke-WinFIRELiveTriage
Helper functions Verb-WinFIRE* Get-WinFIREHiddenFiles
Variables $camelCase $processData
Script Variables $script:PascalCase $script:Version
Parameters PascalCase [string]$OutputPath

Required Patterns

# βœ… Wrap probes in the safe-op wrapper β€” a single broken probe must never abort a run
$data = Invoke-WinFIRESafeOp -Name "Collect services" -Quiet:$ctx.Quiet -Operation {
    Get-CimInstance Win32_Service | Select-Object Name, PathName, StartName, State
}

# βœ… Log via the standard logger (respects -Quiet, always writes winfire.log)
Write-WinFIRELog -Level INFO -Message "Parsed $($data.Count) services."

# βœ… Persist raw artifacts to the case 'raw\' folder
Save-WinFIREData -Context $ctx -Name 'services' -Data $data | Out-Null

# βœ… Emit normalized findings β€” this is what the report renders
New-WinFIREFinding -Module 'LiveTriage' -Severity 'Medium' `
    -Title 'Unsigned service from a user-writable path' `
    -Target $svc.PathName -Mitre @('T1543.003') `
    -Detail 'Service binary is unsigned and lives under a writable directory.' `
    -Evidence @{ Name = $svc.Name; Path = $svc.PathName }

Code Quality

  • Handle null/empty data gracefully; never assume a probe returned rows
  • Degrade gracefully when a tool/privilege is absent β€” return an Info finding, don't throw
  • Use -ErrorAction SilentlyContinue where appropriate; let Invoke-WinFIRESafeOp catch the rest
  • Document each function with a <# .SYNOPSIS #> / comment block
  • Add [CmdletBinding()] to all functions (required for Set-StrictMode -Version Latest)
  • Keep lines under 120 characters
  • Use the $script:Version constant instead of hardcoding version strings
  • Use ASCII-only characters in string literals (no Unicode box-drawing) β€” the codebase runs on PS 5.1
  • Place $null on the left side of equality comparisons (if ($null -eq $x))
  • Avoid PowerShell automatic variable names ($profile, $event, $host, etc.)
  • No hardcoded paths β€” derive from $ctx / $PSScriptRoot / environment variables
  • No Write-Host outside the logger; route everything through Write-WinFIRELog

πŸ“ Module Template

Use this template when adding a new capability module under modules\:

# modules/MyFeature.psm1
function Invoke-WinFIREMyFeature {
    <#
    .SYNOPSIS
        One-line description of what this module hunts for / collects.
    .DESCRIPTION
        Detailed forensic value, data source, and the privilege/tooling it needs.
    #>
    [CmdletBinding()]
    param([Parameter(Mandatory)]$Context)

    $findings = New-Object System.Collections.Generic.List[object]

    # Optional: locate a bundled binary; degrade gracefully if absent.
    # $tool = Resolve-WinFIRETool -Context $Context -Name 'yara'
    # if (-not $tool) {
    #     $findings.Add((New-WinFIREFinding -Module 'MyFeature' -Severity 'Info' `
    #         -Title 'MyFeature engine unavailable' -Detail 'bin\yara64.exe not found; skipped.'))
    #     return $findings
    # }

    $data = Invoke-WinFIRESafeOp -Name 'MyFeature: collect' -Quiet:$Context.Quiet -Operation {
        # …your collection / analysis logic here…
    }

    if ($data) {
        Save-WinFIREData -Context $Context -Name 'myfeature' -Data $data | Out-Null
        foreach ($item in $data) {
            if ($item.IsSuspicious) {
                $findings.Add((New-WinFIREFinding -Module 'MyFeature' -Severity 'Medium' `
                    -Title 'Suspicious MyFeature artifact' -Target $item.Path `
                    -Mitre @('T1059') -Evidence @{ Detail = $item.Why }))
            }
        }
    }

    return $findings
}

Export-ModuleMember -Function Invoke-WinFIREMyFeature

Then register it in $script:Modules inside WinFIRE.ps1:

[pscustomobject]@{
    Name = 'MyFeature'; File = 'MyFeature.psm1'; Phase = 3; Status = 'Ready'
    Desc = 'Short description shown by -ListModules'
    Tools = @()                              # tool names from config/tools.json this module needs
    Selected = { $MyFeature -or $Full }      # which flags enable it
    Invoke   = { param($ctx) Invoke-WinFIREMyFeature -Context $ctx }
}

πŸ§ͺ Testing

Lint + unit tests

# Static analysis (uses tests/PSScriptAnalyzerSettings.psd1)
Invoke-ScriptAnalyzer -Recurse .

# Pester unit tests β€” pure helpers run cross-platform (no Windows required)
Invoke-Pester .\tests

Add Pester cases to tests\WinFIRE.Tests.ps1 for any new pure helper (parsing, scoring, classification). Windows-only probes that can't run under CI should be guarded so the suite still passes everywhere.

Manual smoke tests (on Windows, elevated)

.\WinFIRE.ps1 -ListModules                  # registry prints, every module visible
.\WinFIRE.ps1 -Quick   -CaseNumber TEST-01  # LiveTriage + registry/event-log YARA
.\WinFIRE.ps1 -Full    -CaseNumber TEST-02  # every available module
.\WinFIRE.ps1 -LiveTriage -Quiet -CaseNumber TEST-03

Verify Your Changes

  1. βœ… A case folder WinFIRE_<HOST>_<stamp>\ is created
  2. βœ… report.html and findings.json are written and open cleanly
  3. βœ… New findings carry a sensible Severity and MITRE technique(s)
  4. βœ… No unhandled exceptions in winfire.log
  5. βœ… The run still completes when the module's tool/privilege is missing (graceful Info finding)

πŸ“€ Pull Request Process

Before Submitting

  1. Update CHANGELOG.md with your changes (and bump $script:Version if releasing)
  2. Register any new module in $script:Modules
  3. Add/extend Pester tests in tests\WinFIRE.Tests.ps1
  4. Update README.md / usage-sample.md for user-visible features
  5. Run Invoke-ScriptAnalyzer -Recurse . and Invoke-Pester .\tests clean

PR Description Template

## Description

Brief description of changes.

## Type of Change

- [ ] Bug fix
- [ ] New module / capability
- [ ] Documentation update
- [ ] Performance improvement

## Testing Done

- [ ] `Invoke-Pester .\tests` passes
- [ ] `Invoke-ScriptAnalyzer -Recurse .` clean
- [ ] Smoke-tested on Windows 10/11 (`-Quick` / `-Full`)

## Checklist

- [ ] Code follows project style and degrades gracefully
- [ ] CHANGELOG.md updated
- [ ] Documentation updated

Review Process

  1. Maintainers will review within 1-2 weeks
  2. Address any requested changes
  3. Once approved, the PR will be merged

πŸ“œ Code of Conduct

Our Standards

  • βœ… Be respectful and inclusive
  • βœ… Focus on constructive feedback
  • βœ… Help others learn
  • βœ… Accept responsibility for mistakes
  • ❌ No harassment or discrimination
  • ❌ No personal attacks

Enforcement

Violations may result in:

  1. Warning
  2. Temporary ban
  3. Permanent ban

Report issues to: sudo3rs@protonmail.com

πŸ“ž Contact


Thank you for contributing to WinFIRE! πŸ”₯