Initial OfficeCom Sentinel client and deployment assets

This commit is contained in:
OfficeCom Codex
2026-07-17 00:39:28 +02:00
commit 7cdc0395c4
58 changed files with 6199 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
# AttackTracer Reverse Engineering Notes
## What the legacy app does
`AttackTracer` is a .NET Framework 4.5 WinForms application installed under `Servolutions\BotFence`.
Its main behavior is:
- scan Windows Event Logs for failed logins
- Security `4625` for Windows logons
- Application `18456` for SQL Server login failures
- Application `1035` for Exchange-related login failures
- scan IIS/FTP logs under `C:\inetpub\logs\LogFiles` and `D:\inetpub\logs\LogFiles`
- scan FileZilla Server logs under both `C:` and `D:`
- aggregate attacks by source IP
- geolocate IPs through `http://www.autotimezone.net/atzonline/atz.svc`
- render a top-10 result list and an HTML report
- optionally email the report through `http://pulse.serverpulse.com/PulseCounter/notifications.svc`
## Important weaknesses in the old design
- UI-first architecture
- the app is a desktop WinForms tool instead of a background service or scheduled automation
- hard-coded paths
- it only checks a few fixed IIS and FileZilla folders
- legacy external dependencies
- geolocation and email both depend on old unauthenticated HTTP WCF endpoints
- weak integration model
- results are shown locally or emailed, but not pushed into a central operations system
- mixed responsibilities
- scanning, aggregation, rendering, and notification all live inside the same form workflow
## Meaningful direction for a NinjaOne-connected replacement
Instead of reviving the WinForms app, the better replacement is a small service or scheduled CLI with this split:
1. collectors
- Windows Security/Event Log collector
- IIS/FTP log collector
- FileZilla collector
2. normalization
- normalize all findings into one event schema like:
- `timestamp`
- `sourceIp`
- `targetType`
- `username`
- `source`
3. correlation
- aggregate by IP and time window
- compute severity, velocity, and repeated targets
4. outputs
- JSON report on disk
- HTML report if needed
- NinjaOne-facing output channel
## Suggested NinjaOne integration patterns
Because there is no NinjaOne code in this repository yet, the safest first integration targets are:
- write a machine-readable JSON summary that a NinjaOne script can collect
- emit a plain-text summary to stdout for script-result capture
- optionally write a CSV or HTML artifact for technicians
- keep notification transport separate so we can later swap in a NinjaOne API client, webhook, or custom-field updater
## Practical next step
Build a new `AttackTracer` replacement around a headless scanner first, then add the NinjaOne transport as a separate adapter.
That lets us preserve the useful detection logic while dropping:
- WinForms
- WCF
- external HTTP dependencies
- vendor-specific mail plumbing

View File

@@ -0,0 +1,102 @@
# AttackTracer Ninja CLI
## Purpose
`AttackTracerNinjaCli` is the first headless replacement for the legacy `AttackTracer` WinForms tool.
It keeps the useful detection behavior, but drops the old UI and external WCF dependencies.
## Current inputs
- Windows Security Event Log `4625`
- Windows Application Event Log `18456`
- Windows Application Event Log `1035`
- IIS FTP logs under:
- `C:\inetpub\logs\LogFiles`
- `D:\inetpub\logs\LogFiles`
- FileZilla Server logs under:
- `C:\Program Files (x86)\FileZilla Server\Logs`
- `D:\Program Files (x86)\FileZilla Server\Logs`
## Current outputs
- human-readable console summary
- JSON report for later collection by `ninja1`
- optional `ATTACKTRACER_*` key/value lines for RMM parsing
- optional correlation with exported NinjaOne CVE data for the local device
## Usage
```powershell
dotnet run --project .\src\AttackTracerNinjaCli -- --output .\reports\attacktracer-summary.json
```
Or through the wrapper script:
```powershell
.\scripts\run-attacktracer-ninja.ps1 -LookbackDays 7 -TopCount 10 -FailOnThreshold
```
With vulnerability correlation:
```powershell
.\scripts\run-attacktracer-ninja.ps1 -LookbackDays 7 -TopCount 10 -VulnerabilityCsvPath .\samples\ninja-vulnerability-export.example.csv
```
Useful flags:
- `--json-only`
- `--lookback-days 7`
- `--top 20`
- `--config .\config\attacktracer-settings.example.json`
- `--ninja-output`
- `--fail-on-attacks`
- `--fail-on-threshold`
- `--vulnerability-csv .\path\to\ninja-export.csv`
## Configuration
A sample config is available at [config/attacktracer-settings.example.json](C:\Users\Besitzer\Documents\AttackTracerNinjaVersion\config\attacktracer-settings.example.json).
It currently supports:
- warning and critical thresholds
- correlation thresholds for local CVE findings
- FTP root overrides
- FileZilla root overrides
- source IP exclusions
## CVE correlation
You can correlate AttackTracer findings with exported vulnerability data for the current host.
Expected minimum CSV columns:
- a device-name column such as `device`, `hostname`, or `computername`
- a CVE column such as `cve` or `cve_id`
Optional columns:
- `severity`
- `cvss`
- `remediation`
A sample file is available at [samples/ninja-vulnerability-export.example.csv](C:\Users\Besitzer\Documents\AttackTracerNinjaVersion\samples\ninja-vulnerability-export.example.csv).
## Next integration step
The intended `ninja1` path is:
1. run the installed monitor wrapper from a NinjaOne script or scheduled task
2. let the monitor wrapper write endpoint-level NinjaOne custom fields when `Ninja-Property-Set` or `ninjarmm-cli` is available
3. collect the JSON artifact if you want deeper troubleshooting data
4. use the custom fields and/or `ATTACKTRACER_*` console lines for alerting
For organization-level reporting, you can mirror each device JSON report to a shared folder and render a local HTML summary using [docs/ninjaone-org-report-playbook.md](C:\Users\Besitzer\Documents\AttackTracerNinjaVersion\docs\ninjaone-org-report-playbook.md).
## Deliberate omissions for v1
- no geolocation
- no email sending
- no WinForms UI
- no dependency on legacy HTTP services

View File

@@ -0,0 +1,82 @@
# AttackTracer Ninja Server
> Legacy: This document describes the older share/server architecture. The recommended direction is now the V2 client + n8n + Postgres model documented in `attacktracer-ninja-v2-architecture.md`.
## Purpose
`AttackTracerNinjaServer` is the central companion package for one designated server.
It is separate from the normal endpoint client and is responsible for:
- reading mirrored JSON reports from the network share
- building the consolidated HTML report
- updating NinjaOne organization custom fields through the NinjaOne API
## Separation of roles
### Endpoint client
Install the standard `AttackTracerNinja` package on all monitored systems.
Use it to:
- scan local logs
- write device custom fields
- mirror JSON reports to the central share
### Server package
Install `AttackTracerNinjaServer` on exactly one central server.
Use it to:
- read `\\share\*.json`
- generate `attacktracer-org-report.html`
- update:
- `attacktracerorgstatus`
- `attacktracerorgsummary`
- `attacktracerorglastupdate`
- optionally update `attacktracerorgreport` through the API
## Installer
Build output:
- `artifacts\AttackTracerNinjaServerSetup.exe`
During installation, the server installer prompts for:
- Ninja base URL
- organization ID
- OAuth client ID
- OAuth client secret
- OAuth scope
- reports share path
- HTML output path
- target org field names
Suggested OAuth scope default:
- `monitoring management`
## Runtime command
Installed command:
```powershell
& "C:\Program Files\AttackTracerNinjaServer\scripts\run-attacktracer-ninja-server.ps1"
```
## OAuth requirements
Use a NinjaOne API client with at least:
- `Monitoring`
- `Management`
- `Client Credentials`
Relevant official references:
- [Client Credentials Flow](https://app.ninjarmm.com/apidocs-beta/authorization/flows/client-credentials-flow)
- [API OAuth Token Configuration](https://www.ninjaone.com/docs/application-programming-interface-api/oauth-token-configuration/)
- [Organization custom fields](https://app.ninjarmm.com/apidocs-beta/core-resources/operations/getNodeCustomFields_1)

View File

@@ -0,0 +1,469 @@
# AttackTracer Ninja V2 Architecture
## Goal
Build a lightweight but robust endpoint agent that:
- runs on every monitored Windows device
- reads local attack telemetry and optional local vulnerability exports
- writes device-level NinjaOne custom fields locally
- uploads signed JSON reports to a central n8n ingestion workflow
- receives updates through NinjaOne tasks from GitLab-hosted releases
This design replaces:
- the shared-folder aggregation model
- the dedicated `AttackTracerNinjaServer`
- organization-level field processing on an endpoint
Organization-wide correlation and NinjaOne organization API updates move to n8n.
## Core principles
1. Endpoint collection is local, central correlation is remote.
2. Device custom field writes stay local through NinjaOne-supported endpoint mechanisms.
3. Organization logic never depends on one central Windows server.
4. Update delivery is controlled by NinjaOne, with release artifacts hosted in GitLab.
5. Endpoint uploads are authenticated and tamper-evident.
6. The central pipeline treats endpoint data as useful but never fully trusted.
## Recommended component split
### 1. Endpoint agent
Use a compiled Windows agent written in C#.
Responsibilities:
- scan Windows Security/Application logs
- parse supported local logs such as FTP/FileZilla
- optionally ingest local exported vulnerability data
- build normalized JSON report
- print Ninja-style key/value status lines
- expose a command for device-local execution from NinjaOne
- upload signed report to n8n
Why compiled instead of PowerShell-only:
- harder to casually tamper with than plain scripts
- easier to sign
- easier to version and hash-verify
- simpler to protect internal protocol logic such as signing and replay prevention
### 2. Thin PowerShell deployment wrapper
Use PowerShell only for:
- install
- uninstall
- update
- scheduled execution wrapper
- NinjaOne field publishing wrapper when needed
This keeps operational flexibility while protecting core collection logic inside a signed binary.
### 3. GitLab release channel
GitLab hosts:
- release ZIP or installer
- version manifest
- SHA-256 checksum file
- optional detached signature
Recommended files per release:
- `AttackTracerNinjaClient-win-x64.zip`
- `version.json`
- `AttackTracerNinjaClient-win-x64.zip.sha256`
- `release-notes.md`
### 4. n8n ingestion pipeline
n8n receives endpoint JSON through an authenticated webhook and performs:
- signature validation
- timestamp and replay validation
- schema validation
- persistence to Postgres
- organization aggregation
- NinjaOne organization field updates
- optional notifications
### 5. Postgres as primary store
Postgres should be the system of record for incoming reports.
Recommended tables:
- `devices`
- `device_reports`
- `device_findings`
- `device_vulnerability_findings`
- `organization_rollups`
- `ingestion_events`
### 6. Optional Nextcloud archive
Nextcloud can be used for:
- archived JSON bundles
- generated HTML reports
- long-term human-readable reports
Do not use it as the primary operational datastore.
## Endpoint security model
## Threat assumptions
Assume an attacker may:
- modify files under the install directory
- stop scheduled tasks or Ninja jobs
- alter local logs
- replay older JSON uploads
- inspect locally stored configuration
Assume an attacker with full local admin or SYSTEM access can eventually subvert the endpoint. The architecture therefore aims to:
- raise the effort of tampering
- make tampering detectable
- reduce blast radius of stolen secrets
- preserve central evidence of missing or suspicious reporting
## Required protections
### Signed binaries
- Sign the compiled agent executable.
- Optionally sign the deployment PowerShell scripts.
- The updater must verify Authenticode signature and expected hash before replacing files.
### Protected local secrets
Do not embed one global master secret in all clients.
Use one of these approaches:
- per-tenant ingest token wrapped with DPAPI on each machine
- per-device secret provisioned during install and stored encrypted with DPAPI
- short-lived signed enrollment flow if you later want stronger provisioning
Minimum recommendation:
- store an n8n upload secret encrypted via DPAPI in a local config file readable only by SYSTEM/Administrators
### Signed report uploads
Each report upload should include:
- device identifier
- report timestamp in UTC
- monotonic nonce or GUID
- client version
- payload hash
- HMAC signature over canonicalized request fields
Suggested headers:
- `X-ATN-Device`
- `X-ATN-Timestamp`
- `X-ATN-Nonce`
- `X-ATN-Version`
- `X-ATN-Signature`
n8n must reject:
- stale timestamps outside tolerance
- duplicate nonce values
- invalid HMAC signatures
### Tamper evidence
The endpoint should include in its report:
- installed client version
- scanner execution start/end UTC
- whether upload succeeded
- hash of produced JSON payload
- optional configuration version
n8n should track:
- expected reporting cadence per device
- missing devices
- repeated version lag
- repeated upload failures
- sudden disappearance of formerly noisy devices
### Least-privilege local behavior
- install under `C:\Program Files\AttackTracerNinja`
- write mutable state under `C:\ProgramData\AttackTracerNinja`
- restrict config/log/state ACLs to `SYSTEM` and Administrators
- avoid storing writable binaries under user-controlled locations
## Update architecture
## Distribution model
NinjaOne remains the deployment engine.
Recommended flow:
1. Build signed release in CI.
2. Publish release artifact to GitLab.
3. Publish `version.json` with latest version metadata.
4. NinjaOne scheduled update task runs on endpoints.
5. Update task checks local version against GitLab manifest.
6. If newer, download artifact, verify hash/signature, install, and record result.
## Version manifest
Example `version.json`:
```json
{
"channel": "stable",
"version": "2.0.0",
"publishedAtUtc": "2026-07-16T18:00:00Z",
"artifactUrl": "https://gitlab.example.com/group/project/-/releases/v2.0.0/downloads/AttackTracerNinjaClient-win-x64.zip",
"sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
"minUpdaterVersion": "1.0.0"
}
```
## Endpoint update task
The NinjaOne update task should:
- run as SYSTEM
- read installed version
- fetch `version.json`
- compare versions
- download ZIP to a temporary directory
- verify SHA-256
- verify Authenticode signature on executable
- stop running agent if needed
- replace files atomically
- write update result to a local log
The update task should never install unsigned or hash-mismatched artifacts.
## Runtime execution model
Recommended commands:
- `AttackTracerNinjaCli.exe scan`
- `AttackTracerNinjaCli.exe scan --ninja-output`
- `AttackTracerNinjaCli.exe upload --report <path>`
- `AttackTracerNinjaCli.exe scan-and-upload`
The PowerShell wrapper invoked by NinjaOne should typically run:
```powershell
& "C:\Program Files\AttackTracerNinja\app\AttackTracerNinjaCli.exe" scan-and-upload --ninja-output
```
Wrapper responsibilities:
- ensure paths exist
- capture stdout/stderr to log
- set NinjaOne device custom fields from the produced status
- return a useful exit code for monitoring
## Suggested data flow
1. Endpoint agent scans local data.
2. Agent writes a JSON report locally.
3. Wrapper publishes device custom fields to NinjaOne.
4. Agent signs and uploads the JSON report to n8n.
5. n8n validates authenticity and freshness.
6. n8n stores raw and normalized data in Postgres.
7. n8n computes organization-level summaries.
8. n8n updates NinjaOne organization fields through the API.
9. Optional HTML and long-form artifacts are generated centrally.
## n8n workflow design
## Workflow A: ingest-device-report
Trigger:
- Webhook
Steps:
1. Validate required headers.
2. Validate timestamp tolerance.
3. Check nonce replay in Postgres.
4. Recompute HMAC and compare.
5. Validate JSON schema.
6. Upsert device metadata.
7. Insert raw report row.
8. Insert findings rows.
9. Mark ingestion success.
Failure handling:
- log validation error
- store rejected attempt metadata
- optionally alert on repeated bad signatures
## Workflow B: organization-rollup
Trigger:
- Cron every 5 or 15 minutes
Steps:
1. Query latest accepted report per device.
2. Compute org status and summary.
3. Detect stale devices and missing submissions.
4. Update NinjaOne organization fields:
- `attacktracerorgstatus`
- `attacktracerorgsummary`
- `attacktracerorglastupdate`
5. Optionally generate HTML and archive it
## Workflow C: stale-device-alerting
Trigger:
- Cron
Logic:
- find devices with no valid upload within expected interval
- raise notification or ticket
## Recommended report contract
Each JSON report should include:
```json
{
"schemaVersion": "2.0",
"machineName": "WSUS",
"deviceIdHint": "",
"organizationHint": "",
"generatedAtUtc": "2026-07-16T18:42:11Z",
"clientVersion": "2.0.0",
"lookbackDays": 7,
"baseStatus": "ok",
"alertState": "ok",
"totalEvents": 0,
"uniqueIpCount": 0,
"errorCount": 0,
"attackFindings": [],
"vulnerabilityCorrelation": {
"totalCount": 0,
"criticalCount": 0,
"highCvssCount": 0
},
"runtime": {
"startedAtUtc": "2026-07-16T18:42:09Z",
"finishedAtUtc": "2026-07-16T18:42:11Z",
"uploadAttempted": true
}
}
```
Authentication metadata should travel in headers, not inside the JSON body.
## Packaging recommendation
Use a ZIP-based package for GitLab delivery and NinjaOne installation.
Recommended layout:
```text
AttackTracerNinjaClient-win-x64.zip
app/
AttackTracerNinjaCli.exe
AttackTracerNinjaCli.dll
scripts/
install-attacktracer-ninja.ps1
uninstall-attacktracer-ninja.ps1
update-attacktracer-ninja.ps1
run-attacktracer-ninja.ps1
config/
attacktracer-settings.example.json
VERSION.txt
```
This avoids the operational overhead of a heavy GUI installer while staying easy to deploy from NinjaOne.
## Hardening recommendations
- enable script and binary code signing where possible
- set strict ACLs on `Program Files` and `ProgramData` content
- log every update attempt locally
- include a watchdog check for missing executions
- keep secrets out of command-line parameters where possible
- prefer HTTPS with certificate validation for all uploads
- optionally pin the server certificate thumbprint if your environment allows it
## Migration plan
### Phase 1: define v2 contract
- freeze current JSON model and derive `schemaVersion 2.0`
- define n8n webhook contract
- define version manifest format
### Phase 2: build central pipeline
- create Postgres schema
- create n8n ingest workflow
- create n8n rollup workflow
- test NinjaOne org field updates from n8n
### Phase 3: refactor endpoint client
- remove share mirroring logic
- remove organization/server logic from endpoint package
- add signed upload path
- add DPAPI-backed local secret storage
### Phase 4: implement update channel
- publish GitLab release artifacts
- implement version manifest check
- implement hash/signature validation
- implement NinjaOne update task
### Phase 5: controlled rollout
- pilot on a small device group
- validate upload cadence and rollups
- compare with old system
- then roll out to all devices
### Phase 6: retire old architecture
- stop `AttackTracerNinjaServer`
- remove share-based reporting dependency
- deprecate old org-report scripts
## Recommendation summary
Recommended final direction:
- keep a compiled endpoint agent
- use PowerShell only as thin install/update/run wrapper
- distribute and update through NinjaOne
- host signed release artifacts in GitLab
- upload signed JSON reports to n8n
- store operational data in Postgres
- perform organization-level NinjaOne API writes only from n8n
This gives the best balance of:
- endpoint robustness
- easier rollout
- central visibility
- reduced single-point-of-failure risk
- maintainable future growth

View File

@@ -0,0 +1,103 @@
# AttackTracer Ninja V2 Deployment
## Goal
Deploy and update the endpoint client through NinjaOne while hosting release artifacts in GitLab.
## Release assets
Each GitLab release should publish:
- `OCSentinelClient-win-x64.zip`
- `OCSentinelClient-win-x64.zip.sha256`
- `version.json`
Build these locally with:
```powershell
powershell -ExecutionPolicy Bypass -File .\build\build-client-package.ps1
powershell -ExecutionPolicy Bypass -File .\build\build-release-manifest.ps1 `
-ArtifactUrl "https://gitlab.example.com/group/project/-/releases/v2.0.0/downloads/OCSentinelClient-win-x64.zip"
```
See example manifest:
- [update-channel.example.json](C:/Users/Besitzer/Documents/AttackTracerNinjaVersion/config/update-channel.example.json)
## Endpoint package contents
The installed package should include:
- `app\OCSentinelCli.exe`
- `scripts\run-ocsentinel.ps1`
- `scripts\run-ocsentinel-monitor.ps1`
- `scripts\update-ocsentinel.ps1`
- `scripts\protect-ocsentinel-secret.ps1`
- `config\ocsentinel-settings.json`
- `config\ocsentinel-client.json`
## Initial install through NinjaOne
Recommended NinjaOne task:
```powershell
& "C:\Program Files\OCSentinel\scripts\update-ocsentinel.ps1" `
-ManifestUrl "https://gitlab.example.com/group/project/-/releases/permalink/latest/downloads/version.json" `
-Force
```
If the client is not installed yet, you can also first distribute a bootstrap ZIP or setup package, then switch to the updater-only model.
## Routine update task
Recommended scheduled task command:
```powershell
& "C:\Program Files\OCSentinel\scripts\update-ocsentinel.ps1" `
-ManifestUrl "https://gitlab.example.com/group/project/-/releases/permalink/latest/downloads/version.json"
```
## Behavior
The updater:
1. downloads the manifest
2. compares installed and available version
3. downloads the ZIP only when newer
4. validates SHA-256
5. validates Authenticode signature when present
6. runs the package installer
## Secret bootstrap
After installation, provision the upload secret once:
```powershell
& "C:\Program Files\OCSentinel\scripts\protect-ocsentinel-secret.ps1" `
-SecretValue "<shared-ingest-secret>"
```
This writes a DPAPI-protected file under:
- `C:\ProgramData\OCSentinel\secrets\ocsentinel-upload-secret.dat`
## Runtime task
Recommended runtime task:
```powershell
& "C:\Program Files\OCSentinel\scripts\run-ocsentinel-monitor.ps1" `
-Mode status `
-OutputPath "..\reports\attacktracer-summary.json"
```
Upload is enabled automatically when:
- `config\attacktracer-client.json` exists
- the protected secret file exists
Otherwise the client falls back to local scan behavior.
## Migration guidance
During migration you can keep old share-based logic disabled by default and only enable the new n8n upload path as secrets and webhook config become available.

View File

@@ -0,0 +1,131 @@
# AttackTracer Ninja V2 n8n Contract
## Purpose
This document defines the concrete webhook contract between the endpoint client and n8n.
## Request
Method:
- `POST`
Content type:
- `application/json`
Webhook URL:
- example: `https://n8n.example.com/webhook/attacktracer-ingest`
## Required headers
- `X-ATN-Device`
- `X-ATN-Timestamp`
- `X-ATN-Nonce`
- `X-ATN-Version`
- `X-ATN-Payload-SHA256`
- `X-ATN-Signature`
## Header semantics
- `X-ATN-Device`
- endpoint machine name used for attribution
- `X-ATN-Timestamp`
- UTC timestamp in ISO 8601 format
- `X-ATN-Nonce`
- unique per request, used for replay protection
- `X-ATN-Version`
- client version string
- `X-ATN-Payload-SHA256`
- SHA-256 over the JSON body, lowercase hex
- `X-ATN-Signature`
- HMAC-SHA256 over the canonical signing string, lowercase hex
## Canonical signing string
The client signs this exact string:
```text
device + "\n" + timestamp + "\n" + nonce + "\n" + version + "\n" + payloadSha256
```
## Signature algorithm
- `HMAC-SHA256`
## Recommended n8n validation
1. Reject when a required header is missing.
2. Reject when timestamp skew exceeds allowed tolerance.
3. Reject when nonce was already seen.
4. Recompute payload hash and compare to `X-ATN-Payload-SHA256`.
5. Recompute HMAC and compare to `X-ATN-Signature`.
6. Parse JSON only after headers and signature validation pass.
## Suggested timestamp tolerance
- 5 minutes
## Suggested replay protection persistence
Persist nonce records in Postgres with:
- nonce
- device
- timestamp
- first_seen_utc
## JSON body schema
The body is a `ScanResult` JSON document with schema version `2.0`.
Key fields:
- `schemaVersion`
- `machineName`
- `generatedAtUtc`
- `clientVersion`
- `lookbackDays`
- `alertState`
- `baseAlertState`
- `totalEvents`
- `uniqueIpCount`
- `errors`
- `vulnerabilityCorrelation`
- `runtime`
## Example body
See:
- [webhook-payload.example.json](C:/Users/Besitzer/Documents/AttackTracerNinjaVersion/samples/webhook-payload.example.json)
## n8n response recommendation
On success:
- HTTP `200` or `202`
- JSON body with minimal confirmation
Example:
```json
{
"accepted": true,
"device": "WSUS",
"nonce": "f53a3f0b0c2c466ea1717d88d55fd393"
}
```
On failure:
- HTTP `4xx` for validation/signature problems
- HTTP `5xx` for processing/storage problems
## Device identity guidance
The webhook should not trust `machineName` alone for authorization.
For initial rollout, use the shared secret as the trust anchor.
For later hardening, add a per-device secret or enrollment identity.

View File

@@ -0,0 +1,523 @@
# AttackTracer Ninja V2 Repo Plan
## Purpose
This document turns the V2 architecture into a concrete repository refactor plan.
It answers:
- which existing components should be removed or deprecated
- which new components should be created
- how the client package should be structured
- what the n8n webhook contract should look like
- in which order the migration should happen
## Target result
The repository should end up centered around one endpoint client package that:
- runs on every managed Windows device
- writes NinjaOne device fields locally
- uploads signed JSON reports to n8n
- can be installed and updated from NinjaOne using GitLab-hosted release artifacts
The repository should no longer rely on:
- share mirroring
- a central `AttackTracerNinjaServer`
- organization aggregation on a Windows endpoint
## Existing components to remove or deprecate
## Remove from active architecture
These should be retired from the primary product path:
- `scripts/build-attacktracer-org-report.ps1`
- `installer/runtime-build-attacktracer-org-report.ps1`
- `scripts/run-attacktracer-ninja-server.ps1`
- `installer/runtime-run-attacktracer-ninja-server.ps1`
- `scripts/build-attacktracer-server-installer.ps1`
- `installer/server-install-attacktracer-ninja-server.ps1`
- `installer/server-uninstall-attacktracer-ninja-server.ps1`
- `installer/AttackTracerNinjaServerBootstrapper/*`
- `docs/attacktracer-ninja-server.md`
- share-based org-report playbook content in `docs/ninjaone-org-report-playbook.md`
## Keep only as legacy reference
These can remain temporarily during migration but should be clearly marked legacy:
- `scripts/run-attacktracer-ninja-monitor.ps1`
- `scripts/run-attacktracer-ninja.ps1`
- `docs/ninjaone-monitoring-playbook.md`
- `config/attacktracer-settings.example.json`
## Existing components to preserve and refactor
These are still valuable and should become the base for V2:
- `src/AttackTracerNinjaCli/AttackScanner.cs`
- `src/AttackTracerNinjaCli/VulnerabilityCorrelation.cs`
- `src/AttackTracerNinjaCli/Models.cs`
- `src/AttackTracerNinjaCli/JsonOptions.cs`
- `src/AttackTracerNinjaCli/Program.cs`
- `src/AttackTracerNinjaCli/ScanOptions.cs`
Core scanning logic should remain in C#.
## New repository structure
Recommended target layout:
```text
src/
AttackTracerNinjaCli/
AttackTracerNinjaCli.csproj
Commands/
ScanCommand.cs
UploadCommand.cs
ScanAndUploadCommand.cs
VersionCommand.cs
Security/
HmacSigner.cs
NonceStore.cs
ProtectedSecretStore.cs
Transport/
N8nUploadClient.cs
UploadEnvelopeBuilder.cs
Models/
ReportEnvelope.cs
ScanReport.cs
UploadResult.cs
Configuration/
ClientConfiguration.cs
ConfigurationLoader.cs
scripts/
install-attacktracer-ninja.ps1
uninstall-attacktracer-ninja.ps1
update-attacktracer-ninja.ps1
run-attacktracer-ninja.ps1
publish-ninja-fields.ps1
config/
attacktracer-client.example.json
update-channel.example.json
docs/
attacktracer-ninja-v2-architecture.md
attacktracer-ninja-v2-repo-plan.md
attacktracer-ninja-v2-n8n-contract.md
attacktracer-ninja-v2-deployment.md
build/
build-client-package.ps1
build-release-manifest.ps1
samples/
webhook-payload.example.json
version.example.json
```
## New endpoint client responsibilities
## Binary responsibilities
The compiled client should do these jobs:
- local attack scanning
- vulnerability correlation
- JSON report generation
- report signing
- authenticated upload to n8n
- stable exit codes
- machine-readable output for NinjaOne wrappers
## Wrapper responsibilities
PowerShell wrappers should only do:
- install/uninstall
- update
- local config bootstrap
- invoking the binary
- publishing NinjaOne device custom fields
- logging wrapper-level failures
## New client command model
Recommended commands:
### `scan`
Performs local scan and writes a report file.
Example:
```powershell
AttackTracerNinjaCli.exe scan --output "C:\ProgramData\AttackTracerNinja\reports\latest.json" --ninja-output
```
### `upload`
Uploads an existing report to n8n.
Example:
```powershell
AttackTracerNinjaCli.exe upload --report "C:\ProgramData\AttackTracerNinja\reports\latest.json"
```
### `scan-and-upload`
Performs a scan and directly uploads the result.
Example:
```powershell
AttackTracerNinjaCli.exe scan-and-upload --output "C:\ProgramData\AttackTracerNinja\reports\latest.json" --ninja-output
```
### `version`
Prints installed version and build metadata.
## Config model
Recommended local config file:
- `C:\ProgramData\AttackTracerNinja\config\attacktracer-client.json`
Recommended fields:
```json
{
"schemaVersion": "2.0",
"environment": "production",
"lookbackDays": 7,
"topFindings": 10,
"n8nWebhookUrl": "https://n8n.example.com/webhook/attacktracer-ingest",
"deviceIdentifierMode": "machineName",
"uploadTimeoutSeconds": 30,
"enableVulnerabilityCorrelation": true,
"vulnerabilityCsvPath": "",
"secretReference": "device-default"
}
```
Secrets should not be stored here in clear text.
## Local secret handling plan
## Secret storage
Create a protected local secret file under:
- `C:\ProgramData\AttackTracerNinja\secrets\upload-secret.dat`
Use DPAPI machine protection to encrypt the secret.
## Secret bootstrap
Initial rollout options:
1. NinjaOne install task writes a tenant token once and immediately protects it with DPAPI.
2. Later evolution: unique per-device secret issued centrally.
Recommended first cut:
- tenant-level ingest secret wrapped with DPAPI
- HMAC signature over request metadata + payload hash
## n8n webhook contract
## Endpoint request
Method:
- `POST`
URL:
- provided via config, for example:
- `https://n8n.example.com/webhook/attacktracer-ingest`
Headers:
- `Content-Type: application/json`
- `X-ATN-Device`
- `X-ATN-Timestamp`
- `X-ATN-Nonce`
- `X-ATN-Version`
- `X-ATN-Payload-SHA256`
- `X-ATN-Signature`
Body:
- JSON scan report only
Signature input recommendation:
```text
device + "\n" + timestamp + "\n" + nonce + "\n" + version + "\n" + payloadSha256
```
Algorithm:
- `HMAC-SHA256`
## n8n validation rules
n8n should reject when:
- any required header is missing
- timestamp is outside tolerance
- nonce already exists
- payload hash mismatches body
- signature mismatches
- schema is invalid
## Suggested report payload schema
```json
{
"schemaVersion": "2.0",
"machineName": "WSUS",
"generatedAtUtc": "2026-07-16T19:12:00Z",
"clientVersion": "2.0.0",
"baseStatus": "ok",
"alertState": "ok",
"totalEvents": 0,
"uniqueIpCount": 0,
"errorCount": 0,
"attackFindings": [],
"vulnerabilityCorrelation": {
"totalCount": 0,
"criticalCount": 0,
"highCvssCount": 0
},
"runtime": {
"startedAtUtc": "2026-07-16T19:11:57Z",
"finishedAtUtc": "2026-07-16T19:12:00Z",
"uploadAttempted": true
}
}
```
## GitLab release plan
## Release artifacts
Each release should publish:
- `AttackTracerNinjaClient-win-x64.zip`
- `AttackTracerNinjaClient-win-x64.zip.sha256`
- `version.json`
## ZIP layout
```text
AttackTracerNinjaClient-win-x64.zip
app/
AttackTracerNinjaCli.exe
AttackTracerNinjaCli.dll
scripts/
install-attacktracer-ninja.ps1
uninstall-attacktracer-ninja.ps1
update-attacktracer-ninja.ps1
run-attacktracer-ninja.ps1
publish-ninja-fields.ps1
config/
attacktracer-client.example.json
VERSION.txt
```
## Manifest format
```json
{
"channel": "stable",
"version": "2.0.0",
"artifactUrl": "https://gitlab.example.com/group/project/-/releases/v2.0.0/downloads/AttackTracerNinjaClient-win-x64.zip",
"sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
"publishedAtUtc": "2026-07-16T19:15:00Z"
}
```
## NinjaOne task model
## Task A: install/update client
Runs as SYSTEM.
Responsibilities:
- fetch `version.json`
- compare with local version
- download artifact when newer
- verify SHA-256
- verify Authenticode signature on executable
- install or update package
## Task B: run scan
Runs as SYSTEM on each endpoint.
Responsibilities:
- invoke `run-attacktracer-ninja.ps1`
- publish device custom fields
- trigger upload to n8n
## Device custom field path
Keep the current device-level field strategy.
Wrappers should continue using:
- `Ninja-Property-Set` when available
- Ninja CLI fallback if needed
Fields to preserve:
- `attacktracerstatus`
- `attacktracerreason`
- `attacktracerbasestatus`
- `attacktracerevents`
- `attacktraceruniqueips`
- `attacktracercvecritical`
- `attacktracercvetotal`
- `attacktracermode`
- `attacktracertriggered`
- `attacktracerlastscanutc`
## Concrete code refactor plan
## Step 1: isolate scan model
Refactor current CLI so scan output is represented by one stable report class.
Create:
- `Models/ScanReport.cs`
Move report shape ownership there.
## Step 2: add transport layer
Create:
- `Transport/N8nUploadClient.cs`
- `Transport/UploadEnvelopeBuilder.cs`
Responsibilities:
- prepare headers
- hash payload
- sign request
- upload with timeout and retry policy
## Step 3: add secret protection
Create:
- `Security/ProtectedSecretStore.cs`
Responsibilities:
- store secret using DPAPI
- load secret at runtime
## Step 4: add nonce/replay support
Create:
- `Security/NonceStore.cs`
Local nonce history is optional, but useful for diagnostics.
## Step 5: split commands
Refactor `Program.cs` into command-oriented classes:
- `ScanCommand.cs`
- `UploadCommand.cs`
- `ScanAndUploadCommand.cs`
- `VersionCommand.cs`
## Step 6: simplify wrappers
Replace older server/share assumptions in wrappers.
`run-attacktracer-ninja.ps1` should become:
- invoke binary
- capture output
- write Ninja device fields
- exit with monitoring-friendly code
## Step 7: replace build pipeline
Create:
- `build/build-client-package.ps1`
- `build/build-release-manifest.ps1`
Deprecate:
- heavy installer-first flow if ZIP distribution is enough
## Step 8: deprecate server package
Mark these as legacy and remove from active release build:
- `AttackTracerNinjaServer*`
- org HTML writer logic
- share mirroring flow
## Implementation order
## Phase A: repo cleanup and design freeze
1. Mark server/share docs as legacy
2. Add new config and payload docs
3. Freeze V2 JSON schema
## Phase B: client refactor
1. Add command split
2. Add signed upload path
3. Add DPAPI secret handling
4. Keep existing scan logic intact
## Phase C: packaging
1. Build ZIP package
2. Build version manifest
3. Add install/update scripts
## Phase D: central integration
1. Build n8n ingest workflow
2. Build Postgres schema
3. Build NinjaOne org-field update workflow
## Phase E: rollout
1. Pilot group
2. Validate cadence and missing-report detection
3. Roll out widely
4. Retire server/share path
## Final recommendation
Implement V2 as:
- compiled endpoint collector
- PowerShell operational wrapper
- GitLab-hosted signed releases
- NinjaOne-based deployment and update
- n8n-based central ingestion and org aggregation
This gives a cleaner codebase and a safer operational model than extending the old share/server architecture further.

View File

@@ -0,0 +1,136 @@
# NinjaOne Monitoring Playbook
## Goal
Use `AttackTracerNinja` in NinjaOne with simple, predictable monitor behaviors and endpoint-visible custom-field data.
## Recommended scripts
Primary data collection:
- [scripts/run-attacktracer-ninja.ps1](C:\Users\Besitzer\Documents\AttackTracerNinjaVersion\scripts\run-attacktracer-ninja.ps1)
Monitor-oriented wrapper:
- [scripts/run-attacktracer-ninja-monitor.ps1](C:\Users\Besitzer\Documents\AttackTracerNinjaVersion\scripts\run-attacktracer-ninja-monitor.ps1)
## Recommended monitor layout
## Recommended custom fields
Create these device custom fields in NinjaOne and allow script write access:
- `attacktracerstatus`
- `attacktracerreason`
- `attacktracerbasestatus`
- `attacktracerevents`
- `attacktraceruniqueips`
- `attacktracercvecritical`
- `attacktracercvetotal`
- `attacktracermode`
- `attacktracertriggered`
- `attacktracerlastscanutc`
Suggested field types:
- text: `attacktracerstatus`, `attacktracerreason`, `attacktracerbasestatus`, `attacktracermode`, `attacktracerlastscanutc`
- number/integer: `attacktracerevents`, `attacktraceruniqueips`, `attacktracercvecritical`, `attacktracercvetotal`
- checkbox or text: `attacktracertriggered`
### 1. Attack status monitor
Purpose:
- trigger when the final correlated status is not `ok`
Suggested command:
```powershell
& "C:\Program Files\AttackTracerNinja\scripts\run-attacktracer-ninja-monitor.ps1" -Mode status -LookbackDays 7
```
Meaning:
- alerts on attack-only findings
- alerts on attack-plus-CVE escalation
### 2. Attack-only monitor
Purpose:
- trigger only on attack activity, ignoring pure CVE context
Suggested command:
```powershell
& "C:\Program Files\AttackTracerNinja\scripts\run-attacktracer-ninja-monitor.ps1" -Mode attack-only -LookbackDays 7
```
Meaning:
- good for brute-force / failed-login monitoring
- independent of vulnerability imports
### 3. Critical CVE monitor
Purpose:
- trigger when the imported NinjaOne vulnerability export shows critical/high CVEs for this device
Suggested command:
```powershell
& "C:\Program Files\AttackTracerNinja\scripts\run-attacktracer-ninja-monitor.ps1" -Mode cve-critical -LookbackDays 7 -VulnerabilityCsvPath "C:\Program Files\AttackTracerNinja\samples\ninja-vulnerability-export.example.csv"
```
Meaning:
- CVE-focused monitor
- no attack activity required
### 4. Attack plus CVE correlation monitor
Purpose:
- trigger only when this endpoint has attack activity and critical/high CVEs at the same time
Suggested command:
```powershell
& "C:\Program Files\AttackTracerNinja\scripts\run-attacktracer-ninja-monitor.ps1" -Mode attack-plus-cve -LookbackDays 7 -VulnerabilityCsvPath "C:\Program Files\AttackTracerNinja\samples\ninja-vulnerability-export.example.csv"
```
Meaning:
- highest-signal monitor
- ideal for priority triage
## Suggested alert interpretation
- `status`
- use for general security operations visibility
- `attack-only`
- use for incident-style login abuse detection
- `cve-critical`
- use for vulnerability backlog / patch pressure
- `attack-plus-cve`
- use for urgent escalation
## Useful output fields from the main runner
The main runner emits:
- `ATTACKTRACER_STATUS`
- `ATTACKTRACER_REASON`
- `ATTACKTRACER_BASE_STATUS`
- `ATTACKTRACER_EVENTS`
- `ATTACKTRACER_UNIQUE_IPS`
- `ATTACKTRACER_ERRORS`
- `ATTACKTRACER_CVE_TOTAL`
- `ATTACKTRACER_CVE_CRITICAL`
- `ATTACKTRACER_CVE_HIGH_CVSS`
These are useful if you prefer a condition-based script monitor rather than exit-code-only behavior.
The installed monitor wrapper also attempts to populate NinjaOne custom fields automatically using `Ninja-Property-Set` first and `C:\ProgramData\NinjaRMMAgent\ninjarmm-cli.exe` as a fallback.
## Practical recommendation
If you want the smallest workable setup, start with:
1. a scheduled script that runs `status` and updates the custom fields
2. a condition or device health check on `attacktracertriggered = true`
That gives you one broad monitor, keeps the latest values visible on the device, and avoids relying only on transient script output.

View File

@@ -0,0 +1,107 @@
# NinjaOne Organization Report Playbook
> Legacy: This playbook documents the older shared-folder organization reporting model. For the recommended replacement, use the V2 n8n-based design in `attacktracer-ninja-v2-architecture.md`.
## Goal
Build a central AttackTracer overview as a local HTML report generated from mirrored device reports.
## Recommended design
### Device layer
Each endpoint continues to write these device custom fields:
- `attacktracerstatus`
- `attacktracerreason`
- `attacktracerbasestatus`
- `attacktracerevents`
- `attacktraceruniqueips`
- `attacktracercvecritical`
- `attacktracercvetotal`
- `attacktracermode`
- `attacktracertriggered`
- `attacktracerlastscanutc`
Each endpoint can also mirror its JSON report to a shared folder:
```powershell
& "C:\Program Files\AttackTracerNinja\scripts\run-attacktracer-ninja-monitor.ps1" -Mode status -MirrorRoot "\\fileserver\AttackTracer\OrgA"
```
That will create one JSON file per machine, such as:
- `\\fileserver\AttackTracer\OrgA\WSUS.json`
- `\\fileserver\AttackTracer\OrgA\MILSRV222.json`
## Central report host
Use one always-on Windows server as the central report host:
- stable network path access to the mirrored report share
- enough permissions to read every mirrored JSON file
- optional browser/file access for opening the rendered HTML report
This host only builds the local HTML report. It does not write organization-level custom fields back into NinjaOne.
If your NinjaOne environment exposes `Set-NinjaOrganizationProperty` or `Ninja-Organization-Property-Set`, the same script can also update these text-based organization fields:
- `attacktracerorgstatus`
- `attacktracerorgsummary`
- `attacktracerorglastupdate`
## Org report generator
Use the organization generator script on the delegate machine:
- [scripts/build-attacktracer-org-report.ps1](C:\Users\Besitzer\Documents\AttackTracerNinjaVersion\scripts\build-attacktracer-org-report.ps1)
Installed path after setup:
- `C:\Program Files\AttackTracerNinja\scripts\build-attacktracer-org-report.ps1`
### Generate HTML only
```powershell
& "C:\Program Files\AttackTracerNinja\scripts\build-attacktracer-org-report.ps1" `
-ReportsRoot "\\fileserver\AttackTracer\OrgA" `
-OutputPath "..\reports\attacktracer-org-report.html"
```
### Recommended production command
```powershell
& "C:\Program Files\AttackTracerNinja\scripts\build-attacktracer-org-report.ps1" `
-ReportsRoot "\\fileserver\AttackTracer\OrgA" `
-OutputPath "\\fileserver\AttackTracer\OrgA\attacktracer-org-report.html"
```
### Optional: also update organization summary fields
```powershell
& "C:\Program Files\AttackTracerNinja\scripts\build-attacktracer-org-report.ps1" `
-ReportsRoot "\\fileserver\AttackTracer\OrgA" `
-OutputPath "\\fileserver\AttackTracer\OrgA\attacktracer-org-report.html" `
-WriteNinjaOrgSummary
```
## What the HTML contains
The generated HTML report includes:
- scanned device count
- alerting device count
- critical device count
- total event count
- unique source IP count
- an alert table with the most relevant rows
- a compact `Log sauber` device list
## Operational recommendation
Schedule it in two stages:
1. run the endpoint monitor script on all managed servers and mirror JSON output to the organization share
2. run the organization report generator on the central report host a few minutes later
This keeps the device logic simple and gives you one stable HTML organization summary to open locally or from the share.