Remove legacy AttackTracer repo content
Some checks failed
OfficeCom Sentinel Client / build-client (push) Has been cancelled
Some checks failed
OfficeCom Sentinel Client / build-client (push) Has been cancelled
This commit is contained in:
@@ -1,74 +0,0 @@
|
||||
# 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
|
||||
@@ -1,102 +0,0 @@
|
||||
# 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
|
||||
@@ -1,82 +0,0 @@
|
||||
# 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)
|
||||
@@ -1,469 +0,0 @@
|
||||
# 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
|
||||
@@ -1,131 +0,0 @@
|
||||
# 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.
|
||||
@@ -1,523 +0,0 @@
|
||||
# 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.
|
||||
@@ -1,136 +0,0 @@
|
||||
# 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.
|
||||
@@ -1,107 +0,0 @@
|
||||
# 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.
|
||||
28
docs/ocsentinel-architecture.md
Normal file
28
docs/ocsentinel-architecture.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# OfficeCom Sentinel Architecture
|
||||
|
||||
## Goal
|
||||
|
||||
OfficeCom Sentinel is a Windows endpoint client that:
|
||||
|
||||
- runs on every monitored device
|
||||
- reads local attack telemetry and optional local vulnerability exports
|
||||
- writes NinjaOne device custom fields locally
|
||||
- uploads signed JSON reports to n8n
|
||||
- receives updates through NinjaOne tasks from Gitea-hosted releases
|
||||
|
||||
## Current Model
|
||||
|
||||
The repository now keeps only the client-side architecture:
|
||||
|
||||
- endpoint scan and correlation
|
||||
- local NinjaOne field publishing
|
||||
- optional n8n upload
|
||||
- packaged ZIP release flow for NinjaOne deployment
|
||||
|
||||
## Removed Model
|
||||
|
||||
The following older pieces are intentionally no longer part of the repo:
|
||||
|
||||
- share-based organization aggregation
|
||||
- dedicated server-side collector package
|
||||
- server-side NinjaOne organization field updater
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
Deploy and update the endpoint client through NinjaOne while hosting release artifacts in Gitea.
|
||||
|
||||
## Release assets
|
||||
## Release Assets
|
||||
|
||||
Each Gitea release should publish:
|
||||
|
||||
@@ -20,13 +20,7 @@ powershell -ExecutionPolicy Bypass -File .\build\build-release-manifest.ps1 `
|
||||
-ArtifactUrl "https://gitea.officecom.cloud/officecom/oc-sentinel/releases/download/v2.0.0/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:
|
||||
## Installed Layout
|
||||
|
||||
- `app\OCSentinelCli.exe`
|
||||
- `scripts\run-ocsentinel.ps1`
|
||||
@@ -36,9 +30,9 @@ The installed package should include:
|
||||
- `config\ocsentinel-settings.json`
|
||||
- `config\ocsentinel-client.json`
|
||||
|
||||
## Initial install through NinjaOne
|
||||
## NinjaOne Tasks
|
||||
|
||||
Recommended NinjaOne task:
|
||||
Initial install/update:
|
||||
|
||||
```powershell
|
||||
& "C:\Program Files\OCSentinel\scripts\update-ocsentinel.ps1" `
|
||||
@@ -46,44 +40,14 @@ Recommended NinjaOne task:
|
||||
-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:
|
||||
Routine update:
|
||||
|
||||
```powershell
|
||||
& "C:\Program Files\OCSentinel\scripts\update-ocsentinel.ps1" `
|
||||
-ManifestUrl "https://gitea.officecom.cloud/officecom/oc-sentinel/releases/download/v2.0.0/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:
|
||||
Runtime:
|
||||
|
||||
```powershell
|
||||
& "C:\Program Files\OCSentinel\scripts\run-ocsentinel-monitor.ps1" `
|
||||
@@ -91,13 +55,13 @@ Recommended runtime task:
|
||||
-OutputPath "..\reports\ocsentinel-summary.json"
|
||||
```
|
||||
|
||||
Upload is enabled automatically when:
|
||||
## Secret Bootstrap
|
||||
|
||||
- `config\ocsentinel-client.json` exists
|
||||
- the protected secret file exists
|
||||
```powershell
|
||||
& "C:\Program Files\OCSentinel\scripts\protect-ocsentinel-secret.ps1" `
|
||||
-SecretValue "<shared-ingest-secret>"
|
||||
```
|
||||
|
||||
Otherwise the client falls back to local scan behavior.
|
||||
This writes:
|
||||
|
||||
## 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.
|
||||
- `C:\ProgramData\OCSentinel\secrets\ocsentinel-upload-secret.dat`
|
||||
27
docs/ocsentinel-n8n-contract.md
Normal file
27
docs/ocsentinel-n8n-contract.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# OfficeCom Sentinel n8n Contract
|
||||
|
||||
## Request
|
||||
|
||||
- method: `POST`
|
||||
- content type: `application/json`
|
||||
- example webhook: `https://n8n.example.com/webhook/ocsentinel-ingest`
|
||||
|
||||
## Required Payload Intent
|
||||
|
||||
The endpoint should send one signed JSON document per scan run containing:
|
||||
|
||||
- device identity
|
||||
- client version
|
||||
- scan metadata
|
||||
- attack findings
|
||||
- CVE correlation summary
|
||||
- raw status fields needed for downstream NinjaOne updates
|
||||
|
||||
## Expected Downstream Work
|
||||
|
||||
n8n is responsible for:
|
||||
|
||||
- ingest validation
|
||||
- storage in the central backend
|
||||
- organization-wide aggregation
|
||||
- NinjaOne organization API updates
|
||||
Reference in New Issue
Block a user