chore: Add missing deliverable files (team guide, backlog, sample engagement)
This commit is contained in:
@@ -0,0 +1,514 @@
|
|||||||
|
# Assessment Team Guide: Technical Execution of the Brownhat Diagnostic
|
||||||
|
|
||||||
|
> *"The workshop tells you what the client thinks is happening. The tools tell you what is actually happening. Run the tools before the second session — the findings change the conversation."*
|
||||||
|
|
||||||
|
This guide covers the technical execution of the Brownhat Diagnostic. It is the companion to the [NIST CSF 2.0 Baseline Assessment](nist-csf-baseline.md), which covers the workshop methodology. Read both before your first diagnostic.
|
||||||
|
|
||||||
|
**Division of labour**: The workshop facilitator runs the NIST CSF sessions and manages the client conversation. The technical assessor runs the tools, collects evidence, and builds the findings. These can be the same person in smaller engagements, but if you have two people, split them — the findings from Day 2 tool runs should inform the workshop conversation, not interrupt it.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Before You Arrive: Pre-Engagement Preparation
|
||||||
|
|
||||||
|
### Access to Request (Before Kickoff)
|
||||||
|
|
||||||
|
Send this checklist to the client IT lead at least 5 business days before Day 1. Missing access on Day 1 is the most common cause of diagnostic delay.
|
||||||
|
|
||||||
|
**M365 / Entra ID**:
|
||||||
|
- [ ] Global Reader role in Entra ID (read-only; sufficient for most checks)
|
||||||
|
- [ ] Entra ID audit log access (to verify logging is enabled before PULSAR deploys)
|
||||||
|
- [ ] Exchange admin centre read access
|
||||||
|
- [ ] SharePoint admin centre read access
|
||||||
|
- [ ] Intune read access (Device Management / Endpoint Manager)
|
||||||
|
- [ ] Microsoft Secure Score access
|
||||||
|
- [ ] Conditional Access policies read access
|
||||||
|
|
||||||
|
**Active Directory**:
|
||||||
|
- [ ] Domain User account on the domain(s) — BloodHound collection only needs this
|
||||||
|
- [ ] Read access to ADUC (Active Directory Users and Computers)
|
||||||
|
- [ ] Ability to run PowerShell on a domain-joined machine (for BloodHound collector and Elysium — see notes below on Elysium privilege requirements)
|
||||||
|
|
||||||
|
**Network / Infrastructure**:
|
||||||
|
- [ ] Access to firewall management interface (read-only; to review ruleset)
|
||||||
|
- [ ] VPN access or on-site working arrangement for Day 2 tool runs
|
||||||
|
- [ ] Previous pentest or audit reports (if any exist)
|
||||||
|
|
||||||
|
**Documents to request**:
|
||||||
|
- [ ] Network diagram (any version, however outdated — better than none)
|
||||||
|
- [ ] Asset inventory or CMDB export (even a spreadsheet)
|
||||||
|
- [ ] Previous security audit or pentest report
|
||||||
|
- [ ] List of third-party SaaS tools (from procurement or IT)
|
||||||
|
- [ ] Organisational chart for IT/security team
|
||||||
|
|
||||||
|
> **What to do if access is not ready**: Do not delay the workshop waiting for full access. Start Session 1 with what you have. Deploy ASTRAL and PULSAR as soon as any M365 access is confirmed — they produce value from minute one. Tool runs that need AD access can happen Day 2–3 once an account is provisioned.
|
||||||
|
|
||||||
|
### Tool Preparation
|
||||||
|
|
||||||
|
Have these ready to deploy before Day 1. Do not learn a tool at a client's expense.
|
||||||
|
|
||||||
|
| Tool | Preparation | Time to deploy |
|
||||||
|
|------|-------------|---------------|
|
||||||
|
| ASTRAL | ADO project created; pipeline YAMLs ready; `bootstrap-tenant.ps1` reviewed | 2–4 hours on-site |
|
||||||
|
| PULSAR | Docker Compose environment ready; `bootstrap-tenant.ps1` reviewed | 1–2 hours on-site |
|
||||||
|
| BloodHound CE | Installed on assessment laptop; SharpHound collector downloaded | 15 minutes |
|
||||||
|
| Elysium | Cloned and tested in lab; KHDB download initiated (large file — download before arriving) | 30 min setup; KHDB download 30–60 min |
|
||||||
|
| CAExporter | Downloaded and tested | 10 minutes |
|
||||||
|
| Purple Knight | Downloaded from Semperis (free, requires registration) | 15 minutes |
|
||||||
|
| E8-CAT | Downloaded and tested (for Australian clients or E8-aligned clients) | 10 minutes |
|
||||||
|
| Nmap / Shodan | Nmap installed; Shodan account active (free tier sufficient) | Ready |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Day 1: Deploy First, Ask Questions Later
|
||||||
|
|
||||||
|
The single most important discipline: **deploy ASTRAL and PULSAR before the first workshop session begins.** The baseline they capture is a point-in-time snapshot. If you wait until after the workshops, the baseline may already reflect changes the client made in response to your questions.
|
||||||
|
|
||||||
|
### Morning: Deploy Listening Tools
|
||||||
|
|
||||||
|
Before Session 1 starts, or during the first 30-minute introductions slot:
|
||||||
|
|
||||||
|
**Step 1 — ASTRAL deployment** (~2 hours, can run in background)
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# On the client's Azure DevOps or your assessment instance
|
||||||
|
.\deploy\bootstrap-tenant.ps1 -TenantName "<client>.onmicrosoft.com"
|
||||||
|
```
|
||||||
|
|
||||||
|
Follow the [ASTRAL onboarding runbook](https://github.com/cqrenet/astral/blob/main/deploy/onboarding-runbook.md). The initial full backup pipeline run captures the complete M365 configuration baseline. This is your "before" snapshot — everything you find during the assessment is measured against this.
|
||||||
|
|
||||||
|
**What ASTRAL captures on first run**:
|
||||||
|
- All Intune profiles, policies, compliance policies, applications, scripts
|
||||||
|
- All Conditional Access policies (with full named-object resolution via CAExporter integration)
|
||||||
|
- All Entra ID app registrations and enterprise applications
|
||||||
|
- All authentication methods and named locations
|
||||||
|
- Produces HTML/PDF as-built documentation automatically
|
||||||
|
|
||||||
|
**Step 2 — PULSAR deployment** (~1 hour, can run in background)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp .env.example .env
|
||||||
|
# Fill in CLIENT_ID, CLIENT_SECRET, TENANT_ID from bootstrap output
|
||||||
|
docker compose up --build -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Once running, trigger a manual fetch to confirm audit log ingestion is working:
|
||||||
|
|
||||||
|
```
|
||||||
|
GET http://localhost:8000/api/fetch-audit-logs
|
||||||
|
```
|
||||||
|
|
||||||
|
**What PULSAR captures immediately**: All M365 admin audit events from the Management Activity API (Exchange, SharePoint, Teams, Entra, Intune). Retention starts from this moment — every admin action from here forward is permanently searchable. For clients with no prior log retention, this is instant value.
|
||||||
|
|
||||||
|
**Step 3 — Microsoft Secure Score baseline** (10 minutes)
|
||||||
|
|
||||||
|
Navigate to `security.microsoft.com → Secure Score`. Screenshot the current score and the top 10 recommended actions. This is a quick reference point for the workshop conversation and gives the client a number they immediately understand.
|
||||||
|
|
||||||
|
**Step 4 — Passive external scan** (runs in background during workshop)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# From your assessment machine
|
||||||
|
nmap -sV --open -p 80,443,8080,8443,3389,22,21,25,993,995 [client-public-IPs]
|
||||||
|
|
||||||
|
# Shodan CLI for ASN-based discovery
|
||||||
|
shodan search "org:[client-org-name]" --fields ip_str,port,banner,product
|
||||||
|
```
|
||||||
|
|
||||||
|
Also check:
|
||||||
|
- Certificate transparency logs: `crt.sh/?q=[client-domain]` — reveals subdomains, expired certs, shadow IT domains
|
||||||
|
- Shodan for the VPN endpoint specifically: firmware version, known CVEs
|
||||||
|
- `whois` and reverse DNS for all IP ranges the client mentions
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## During the Workshops: What to Listen For
|
||||||
|
|
||||||
|
The [NIST CSF Baseline](nist-csf-baseline.md) has the full question set. Below are the specific signals to listen for that indicate P0/P1 findings. Note these immediately — they feed the technical checklist for Day 2.
|
||||||
|
|
||||||
|
| What the client says | What it likely means | Check on Day 2 |
|
||||||
|
|---------------------|---------------------|----------------|
|
||||||
|
| "We haven't tested our backups recently" | No restore has ever been done | Recovery drill required; check backup destination |
|
||||||
|
| "We use shared admin accounts" | Multiple people using one credential | Elysium; AD audit; no MFA possible on shared account |
|
||||||
|
| "Contractors have the same access as employees" | Likely no offboarding process; stale accounts | Elysium; AD account audit; HR cross-reference |
|
||||||
|
| "We have MFA but I think some people have exemptions" | CA policies in report-only or with large exclusion groups | CAExporter; Entra ID CA policy review |
|
||||||
|
| "The acquisition brought in a second AD" | Forest trusts; uncharted attack paths; duplicate admin accounts | BloodHound must cover both domains |
|
||||||
|
| "We use [legacy on-prem system] with its own accounts" | Shadow identity; service accounts not in scope of central IAM | Manual AD service account audit |
|
||||||
|
| "IT handles offboarding when HR tells us" | Offboarding depends on HR notification — often delayed | Elysium; compare AD accounts to HR list |
|
||||||
|
| "I'm not sure who all has admin access" | No privileged access inventory | BloodHound; ADUC privileged group audit |
|
||||||
|
| "We have a firewall but nobody has reviewed the rules in years" | Accumulated rules; likely any/any entries; retired services still open | Firewall rule export and review |
|
||||||
|
| "Some of our developers have direct access to production" | Uncontrolled privileged access to production systems | Scope question for Module 6 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Day 2–3: Technical Tool Runs
|
||||||
|
|
||||||
|
Run tools in this order. Earlier tools inform later ones.
|
||||||
|
|
||||||
|
### 1. CAExporter — Conditional Access Baseline (30 minutes)
|
||||||
|
|
||||||
|
Run first. The CA policy export reveals whether MFA is actually enforced or just configured. This is consistently the most surprising finding in M365 environments.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Requires Entra ID reader access
|
||||||
|
.\CAExporter.ps1 -TenantId <tenant-id> -OutputPath .\ca-export\
|
||||||
|
```
|
||||||
|
|
||||||
|
**What to look for**:
|
||||||
|
- Policies in **Report-Only** mode (not enforced — common; clients assume they are protected when they are not)
|
||||||
|
- Large **exclusion groups** containing most users ("AllUsers_ExceptionGroup" type)
|
||||||
|
- Policies that claim to block legacy authentication but have exclusions that defeat the purpose
|
||||||
|
- No policy enforcing device compliance
|
||||||
|
- Multiple overlapping policies with unclear precedence
|
||||||
|
|
||||||
|
**Output**: Excel workbook with one row per policy, conditions and controls expanded, groups and apps named rather than showing GUIDs. This is the CA baseline document.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. BloodHound — AD Attack Path Analysis (1–2 hours collection + analysis)
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Run SharpHound from a domain-joined machine using the assessor domain account
|
||||||
|
.\SharpHound.exe -c All --zipfilename nexus-bloodhound.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy the zip to your assessment machine and import into BloodHound CE.
|
||||||
|
|
||||||
|
**Required queries** (run these first, every engagement):
|
||||||
|
|
||||||
|
```cypher
|
||||||
|
-- Shortest paths to Domain Admin from all non-admin users
|
||||||
|
MATCH p=shortestPath((u:User {admincount:false})-[*1..]->(g:Group {name:"DOMAIN ADMINS@DOMAIN.LOCAL"})) RETURN p
|
||||||
|
|
||||||
|
-- All Domain Admin members with direct login sessions on workstations
|
||||||
|
MATCH (u:User)-[:MemberOf]->(g:Group {name:"DOMAIN ADMINS@DOMAIN.LOCAL"})
|
||||||
|
MATCH (u)-[:HasSession]->(c:Computer) WHERE NOT c.name CONTAINS "DC" RETURN u.name, c.name
|
||||||
|
|
||||||
|
-- Kerberoastable accounts with high privilege
|
||||||
|
MATCH (u:User {hasspn:true}) WHERE u.admincount=true RETURN u.name, u.serviceprincipalnames
|
||||||
|
|
||||||
|
-- ASREPRoastable accounts (no Kerberos pre-auth)
|
||||||
|
MATCH (u:User {dontreqpreauth:true}) RETURN u.name, u.enabled
|
||||||
|
|
||||||
|
-- Service accounts with paths to Domain Admin
|
||||||
|
MATCH p=shortestPath((u:User)-[*1..5]->(g:Group {name:"DOMAIN ADMINS@DOMAIN.LOCAL"}))
|
||||||
|
WHERE u.name CONTAINS "$" OR u.name CONTAINS "SVC" OR u.name CONTAINS "SERVICE"
|
||||||
|
RETURN p
|
||||||
|
```
|
||||||
|
|
||||||
|
**What to document**:
|
||||||
|
- Number of paths to Domain Admin from non-admin users (the "847 paths" number from the sample)
|
||||||
|
- Shortest path length and the specific nodes on it — this is your kill chain
|
||||||
|
- Domain Admins with sessions on non-DC workstations — P1 finding in almost every environment
|
||||||
|
- Any service accounts that are Kerberoastable and have high privilege — often P0
|
||||||
|
- KRBTGT last password set date (check in ADUC or PowerShell)
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# KRBTGT last password set
|
||||||
|
Get-ADUser krbtgt -Properties PasswordLastSet | Select PasswordLastSet
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. Elysium — Password Audit (2–4 hours, requires elevated AD access)
|
||||||
|
|
||||||
|
> **Privilege requirement**: Elysium requires Domain Admin or equivalent (DSInternals needs to read password hashes). Confirm this access before scheduling. If it cannot be arranged during the diagnostic, schedule it for week 1 of Module 6.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Run from a domain controller or with delegated rights
|
||||||
|
.\Elysium.ps1 -Domain <domain-fqdn> -OutputPath .\elysium-output\
|
||||||
|
```
|
||||||
|
|
||||||
|
**What Elysium finds**:
|
||||||
|
- Accounts matching known-breached password hashes (from the KHDB — download before arriving)
|
||||||
|
- Accounts with blank passwords
|
||||||
|
- Accounts with passwords matching dictionary patterns
|
||||||
|
- Duplicate passwords across accounts (shared credential detection)
|
||||||
|
|
||||||
|
**Output to document**:
|
||||||
|
- Total accounts audited
|
||||||
|
- Accounts matching KHDB (breached) — split by privileged vs non-privileged
|
||||||
|
- Accounts with common passwords
|
||||||
|
- Any privileged account with a compromised or weak password → immediate P0
|
||||||
|
|
||||||
|
**Privacy handling**: Elysium does not transmit usernames or plaintext passwords. The KHDB comparison is local. The output is a list of SAMAccountNames to reset — not passwords. Communicate this clearly to the client before running.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. Purple Knight — AD Security Scoring (30 minutes)
|
||||||
|
|
||||||
|
Purple Knight (Semperis, free) runs a broad checklist of AD security misconfigurations. Run it from any domain-joined machine.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\PurpleKnight.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
The report scores against ~100 indicators. **Focus on**:
|
||||||
|
- LDAP signing and channel binding status
|
||||||
|
- AdminSDHolder unusual members
|
||||||
|
- Protected Users group membership (or absence of it for admins)
|
||||||
|
- Reversible encryption enabled accounts
|
||||||
|
- Unconstrained delegation (computers and users)
|
||||||
|
- Machine account quota (default 10 — often abused for relay attacks)
|
||||||
|
- Exchange permissions on AD objects (if Exchange exists on-prem)
|
||||||
|
|
||||||
|
Cross-reference Purple Knight findings with BloodHound. Purple Knight finds the indicators; BloodHound shows how they chain together into attack paths.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 5. Entra ID Manual Checks (1 hour)
|
||||||
|
|
||||||
|
These cannot be automated — they require visual inspection in the Entra admin centre.
|
||||||
|
|
||||||
|
**App registrations and enterprise applications**:
|
||||||
|
- Navigate to: `Entra ID → App registrations → All applications`
|
||||||
|
- Filter by: "High privilege permissions" — look for `Mail.ReadWrite`, `Directory.ReadWrite.All`, `User.ReadWrite.All`
|
||||||
|
- Note any apps with these permissions that are: (a) published by unknown parties, (b) have no documented owner, (c) were consented to by users rather than admins
|
||||||
|
- This is consistently where the most surprising findings live — OAuth consent abuse is underdetected in every mid-market environment
|
||||||
|
|
||||||
|
**Guest accounts**:
|
||||||
|
- Navigate to: `Entra ID → Users → Filter: User type = Guest`
|
||||||
|
- How many guests are there? When was their last sign-in? Are any of them former contractors?
|
||||||
|
|
||||||
|
**MFA registration status**:
|
||||||
|
- Navigate to: `Entra ID → Users → Per-user MFA` (legacy view) OR `Identity Protection → Monitoring → Authentication methods → User registration details`
|
||||||
|
- What % of users have MFA registered? What % have it enforced?
|
||||||
|
- Are there any break-glass accounts? Are they properly protected and audited?
|
||||||
|
|
||||||
|
**Entra ID Connect sync account** (hybrid environments only):
|
||||||
|
- Navigate to: `Entra ID → App registrations → find the sync account`
|
||||||
|
- Check what rights it has in Entra ID
|
||||||
|
- Cross-reference with on-prem AD: does this account have DCSync rights? (BloodHound query: search for the account name and check its paths)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 6. Intune / Endpoint Check (30 minutes — via ASTRAL output or direct)
|
||||||
|
|
||||||
|
ASTRAL's first run will have produced an Intune inventory. Review:
|
||||||
|
|
||||||
|
- **Enrollment rate**: What % of devices are enrolled? What platforms?
|
||||||
|
- **Compliance policy coverage**: Is there a compliance policy? What does it enforce? Is it assigned to all devices?
|
||||||
|
- **Conditional Access integration**: Is the "Require compliant device" CA policy active — or in report-only?
|
||||||
|
- **Stale devices**: Devices with last check-in > 90 days are likely personal devices or ghost entries. Note the count.
|
||||||
|
- **Script inventory**: What PowerShell scripts are deployed via Intune? Any that look unfamiliar?
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 7. External Attack Surface (30–60 minutes)
|
||||||
|
|
||||||
|
By Day 2, the Nmap and Shodan scans from Day 1 should have results.
|
||||||
|
|
||||||
|
**Review**:
|
||||||
|
- Any RDP (3389) exposed to internet → P0 in almost every context
|
||||||
|
- Any management interfaces (firewalls, switches, VPN management) accessible from internet
|
||||||
|
- Any services with outdated banners suggesting old software versions
|
||||||
|
- Certificate expiry on any internet-facing service
|
||||||
|
- VPN endpoint firmware version → check against vendor advisory for known CVEs
|
||||||
|
|
||||||
|
**Additional check — subdomain enumeration**:
|
||||||
|
```bash
|
||||||
|
# Using crt.sh results and DNS brute force
|
||||||
|
cat crt-sh-results.txt | grep "<client-domain>" | sort -u
|
||||||
|
# For each subdomain found: what is it? Is it documented? Is it still active?
|
||||||
|
```
|
||||||
|
|
||||||
|
Undocumented subdomains pointing to forgotten services are a regular P1 finding.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 8. Firewall Rule Review (30–60 minutes)
|
||||||
|
|
||||||
|
Request an export of the firewall ruleset. Most firewall platforms support CSV or XML export.
|
||||||
|
|
||||||
|
**What to look for**:
|
||||||
|
- Rules with `source = ANY` and `destination = ANY` (any/any) → almost always P2 but sometimes P1 if it covers a sensitive segment
|
||||||
|
- Rules allowing direct internet access from server VLANs → P1
|
||||||
|
- Rules created for a specific project that are still active years later → P2
|
||||||
|
- Rules referencing IP addresses that no longer correspond to live systems
|
||||||
|
- No rule for blocking outbound traffic (egress filtering absent) → P1 for environments with sensitive data
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 9. Backup and Recovery Spot Check (30 minutes)
|
||||||
|
|
||||||
|
Ask the IT lead to show you, live:
|
||||||
|
- Where backups are stored (destination)
|
||||||
|
- When the last backup ran and whether it completed successfully
|
||||||
|
- Whether the backup destination is on the same network segment as the system being backed up
|
||||||
|
- Whether anyone has ever triggered a test restore and what the result was
|
||||||
|
|
||||||
|
> **The standard answer**: "Backups run every night and we get a green tick." The right follow-up: "Show me the most recent successful restore test." In most environments, one has never been performed.
|
||||||
|
|
||||||
|
Document: backup target, last run, completion status, last restore test (date or "never").
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Synthesising Findings: From Data to Kill Chain
|
||||||
|
|
||||||
|
After tool runs are complete, before writing the report, do this step explicitly. Sit with your notes and answer one question:
|
||||||
|
|
||||||
|
**"What is the shortest sequence of steps an adversary with no prior access could take to cause the organisation to fail to operate?"**
|
||||||
|
|
||||||
|
Build the kill chain step by step:
|
||||||
|
1. Start from the outside (what can be accessed without credentials?)
|
||||||
|
2. What is the first credential gain? (phishing, password spray against legacy auth, VPN without MFA)
|
||||||
|
3. What does that credential give access to? (M365 if MFA is not enforced; VPN if no MFA there)
|
||||||
|
4. What can you do with M365 access? (read all email, access SharePoint, escalate via app permissions)
|
||||||
|
5. What is the path from M365 access to domain admin? (Entra ID admin → AD Connect sync account → DCSync)
|
||||||
|
6. What does domain admin give you? (everything on-prem, including ERP, backup servers)
|
||||||
|
7. What is the impact? (data exfiltration, ransomware, operational disruption)
|
||||||
|
|
||||||
|
Write this as a chain, not a list. The [sample engagement kill chain](sample-engagement-mid-market.md#kill-chain-assessment) shows the format.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Finding Triage and Priority Assignment
|
||||||
|
|
||||||
|
For every finding, apply the kill chain test:
|
||||||
|
|
||||||
|
| Question | Priority |
|
||||||
|
|----------|----------|
|
||||||
|
| Is this a node on the kill chain? | **P0** — fix before anything else |
|
||||||
|
| If exploited, does material harm result even if not on the kill chain? | **P1** — fix this engagement |
|
||||||
|
| Real finding, real risk, but not on the kill chain and not immediately material? | **P2** — housekeeping queue |
|
||||||
|
| Best practice recommendation with no exploitable risk? | **Observation** — note in report, do not count as a finding |
|
||||||
|
|
||||||
|
**Common priority inflation mistakes**:
|
||||||
|
- Marking "no security awareness training programme" as P0 — it is P2 at most
|
||||||
|
- Marking every missing patch as P0 — only patches for internet-facing or kill-chain systems
|
||||||
|
- Marking "weak password policy" as P0 when Elysium shows no actual weak passwords — the policy is P2; actual weak credentials on privileged accounts are P0
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Quick Wins Identification
|
||||||
|
|
||||||
|
A quick win must pass three tests:
|
||||||
|
1. **Closeable in hours or days, not weeks** — requires no procurement, no change window longer than one day, no significant testing
|
||||||
|
2. **Uses only existing tools and permissions** — no new purchase, no new deployment
|
||||||
|
3. **Meaningfully reduces risk** — not cosmetic
|
||||||
|
|
||||||
|
For M365/AD environments, the standard quick wins checklist:
|
||||||
|
|
||||||
|
- [ ] Activate CA policies already in Report-Only mode
|
||||||
|
- [ ] Remove large exception groups from CA compliance policies
|
||||||
|
- [ ] Block legacy authentication (CA policy template exists in every tenant)
|
||||||
|
- [ ] Enforce MFA at organisation level in GitHub / other SaaS tools
|
||||||
|
- [ ] Disable accounts confirmed as departed contractors (HR-verified, scripted disable)
|
||||||
|
- [ ] Enable audit logging where it is off (often disabled on legacy servers to save disk)
|
||||||
|
- [ ] Revoke suspicious OAuth app permissions (for obvious unknowns with high privilege)
|
||||||
|
- [ ] Change default credentials on any system where they are confirmed unchanged
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Report Structure
|
||||||
|
|
||||||
|
The Brownhat Diagnostic report has five sections. Target length: 15–25 pages. Not more — if it is longer, it will not be read.
|
||||||
|
|
||||||
|
### 1. Executive Summary (2 pages)
|
||||||
|
|
||||||
|
- Current state in one paragraph — honest, not alarming
|
||||||
|
- Kill chain: the specific path, named, diagrammed if possible
|
||||||
|
- P0 count, P1 count, P2 count
|
||||||
|
- Quick wins: what was closed immediately (if Day 1 quick wins were executed)
|
||||||
|
- Recommended first module and rationale
|
||||||
|
- NIS2 compliance gap summary (if applicable): which Article 21 measures have evidence, which do not
|
||||||
|
|
||||||
|
### 2. Methodology (0.5 pages)
|
||||||
|
|
||||||
|
- Workshop dates, attendees
|
||||||
|
- Tools used (ASTRAL, PULSAR, BloodHound, Elysium, Purple Knight, CAExporter, external scan)
|
||||||
|
- Access used (read-only Entra ID, domain user for BloodHound, domain admin for Elysium)
|
||||||
|
- What was NOT assessed (explicitly scoped out — sets expectations)
|
||||||
|
|
||||||
|
### 3. Findings (8–15 pages)
|
||||||
|
|
||||||
|
Organise by priority tier, not by domain.
|
||||||
|
|
||||||
|
**P0 — Kill Chain Nodes**: Each finding gets a half-page: the finding in one sentence, the evidence, the business impact in non-technical language, and the remediation. Name the specific accounts, policies, or systems involved. "Admin accounts lack MFA" is a weak finding. "3 of 5 Global Administrator accounts — `admin@nexus.onmicrosoft.com`, `it-admin@nexus.onmicrosoft.com`, and the break-glass account — can authenticate without MFA because the Conditional Access policy 'Require MFA' is in Report-Only mode" is a finding.
|
||||||
|
|
||||||
|
**P1 — Material Risk**: Same format, briefer. One paragraph per finding.
|
||||||
|
|
||||||
|
**P2 — Housekeeping Queue**: Table format only. ID, finding, why it matters in one sentence.
|
||||||
|
|
||||||
|
### 4. Module Recommendation (2 pages)
|
||||||
|
|
||||||
|
- Recommended sequence with rationale
|
||||||
|
- What each module closes (map to specific P0/P1 findings)
|
||||||
|
- Timeline estimate
|
||||||
|
- Investment estimate (effort ranges, not day rates — rates go in the proposal)
|
||||||
|
|
||||||
|
### 5. Quick Wins Closed (0.5 pages)
|
||||||
|
|
||||||
|
List what was already fixed during the diagnostic. This is the most important page for client confidence — they paid for the diagnostic and something is already better.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Backlog Population
|
||||||
|
|
||||||
|
Before leaving the client site (or within 24 hours):
|
||||||
|
|
||||||
|
1. Create the ADO Work Items project (or agree on the tool with Ondřej)
|
||||||
|
2. Enter every finding as a Work Item: ID, finding text (one sentence), source (Brownhat Diagnostic), priority (P0/P1/P2), owner (named person)
|
||||||
|
3. Move quick wins to Closed with the date they were resolved
|
||||||
|
4. Brief the named IT lead on the backlog: where it lives, how the monthly cycle works, who owns what
|
||||||
|
5. Pin the ADO board as a Teams tab if applicable
|
||||||
|
|
||||||
|
The backlog handover is not optional. A diagnostic that produces a report but no maintained tracking system has a half-life of one steering committee meeting.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ASTRAL and PULSAR Handover
|
||||||
|
|
||||||
|
By the end of the diagnostic engagement:
|
||||||
|
|
||||||
|
**ASTRAL**:
|
||||||
|
- First full backup has run and committed to the ADO repository
|
||||||
|
- Client IT lead can access the ADO project and review the baseline
|
||||||
|
- Drift detection is live — the first drift PR, if one occurs, should be reviewed together with the client as a training exercise
|
||||||
|
- Reviewer notification configured to email or Teams-notify Ondřej
|
||||||
|
|
||||||
|
**PULSAR**:
|
||||||
|
- Audit events ingesting and searchable
|
||||||
|
- Teams tab pinned in the IT channel
|
||||||
|
- Basic search walkthrough done with client IT lead: show them how to find a specific event, how to filter by actor and operation
|
||||||
|
- No alert rules yet — those come in Module 2/3 when there is a hardened baseline to alert against
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Common Mistakes in Assessment Execution
|
||||||
|
|
||||||
|
**Starting tool runs before access is confirmed.** Tool runs that fail eat time and erode confidence. Confirm credentials work before you need them.
|
||||||
|
|
||||||
|
**Running Elysium without telling the client what it does.** "We are going to compare your password hashes against a database of known-compromised credentials" needs to be explained before it happens. Most clients are fine with it once they understand the privacy model. Zero clients want a surprise.
|
||||||
|
|
||||||
|
**Presenting findings before you have run BloodHound.** The kill chain often only becomes clear once BloodHound has shown how the pieces connect. Do not anchor the client on an incomplete kill chain in Session 2 and then have to walk it back.
|
||||||
|
|
||||||
|
**Marking everything P0.** If you present 15 P0 findings, the client has no way to act. Real P0 items are rare — typically 3–8 in a first diagnostic. If you have more, re-examine your priority assignments.
|
||||||
|
|
||||||
|
**Leaving without a named owner for every P0.** The diagnostic ends. The report goes out. Nobody fixes the P0 items because nobody has their name on them. Get owner names in the room before you leave.
|
||||||
|
|
||||||
|
**Forgetting to document what you ran and what access you used.** The methodology section of the report should be written from notes taken during the assessment, not reconstructed from memory three days later.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Post-Assessment Checklist
|
||||||
|
|
||||||
|
Before submitting the report:
|
||||||
|
|
||||||
|
- [ ] Kill chain written as a chain, not a list
|
||||||
|
- [ ] Every P0 finding has: evidence citation, specific named assets, remediation steps, named owner
|
||||||
|
- [ ] Quick wins section lists what was already fixed
|
||||||
|
- [ ] Module recommendation is tied to specific findings ("Module 2 closes P0-001, P0-002, P1-001, P1-004")
|
||||||
|
- [ ] ASTRAL baseline committed and accessible to client
|
||||||
|
- [ ] PULSAR ingesting and accessible to client
|
||||||
|
- [ ] Findings backlog populated in agreed tool, owners assigned
|
||||||
|
- [ ] Report reviewed for any claim that is an assertion rather than evidence (replace with what was found)
|
||||||
|
- [ ] NIS2 compliance map completed if client is in scope
|
||||||
|
- [ ] Next steps section includes: module recommendation, first meeting date, decision required from client
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Companion documents:*
|
||||||
|
*[NIST CSF 2.0 Baseline Assessment](nist-csf-baseline.md) — workshop methodology and questionnaires*
|
||||||
|
*[Sample Engagement: Mid-Market Hybrid](../playbooks/sample-engagement-mid-market.md) — calibration reference for findings and recommendations*
|
||||||
|
*[Findings Backlog](findings-backlog.md) — where findings land and how the housekeeping stream works*
|
||||||
|
*[Sovereign Tool Stack](../playbooks/sovereign-tool-stack.md) — full tool reference with deployment guidance*
|
||||||
|
*[Module Menu](../core/modular-engagements.md) — module selection after the diagnostic*
|
||||||
@@ -0,0 +1,216 @@
|
|||||||
|
# Findings Backlog
|
||||||
|
|
||||||
|
> *"A finding without a home is a finding that will never be fixed. The risk register is the right home. The backlog is the one that actually exists."*
|
||||||
|
|
||||||
|
## The Problem This Solves
|
||||||
|
|
||||||
|
Every assessment, module, and engagement produces findings. Some get fixed immediately. Most do not. In organisations with mature risk management, findings go into a risk register, get assigned owners, get reviewed quarterly, and get closed over time.
|
||||||
|
|
||||||
|
In practice, most organisations do not have a working risk register. They have a template someone downloaded, a spreadsheet that was last updated during the ISO 27001 attempt three years ago, or a GRC tool that nobody logs into. Findings that go into these systems disappear.
|
||||||
|
|
||||||
|
The **findings backlog** is the pragmatic alternative. It is not a replacement for a formal risk register — it is the lightweight, maintainable system that fills the gap between "finding documented in a report" and "finding tracked to closure." For organisations that eventually build a working risk register, the backlog feeds into it. For organisations that never do, the backlog is their risk register in all but name.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Deployment Options
|
||||||
|
|
||||||
|
Three options, in order of preference. Choose based on what the client will actually open.
|
||||||
|
|
||||||
|
### Option 1 — Azure DevOps Work Items (recommended for ASTRAL clients)
|
||||||
|
|
||||||
|
If ASTRAL is deployed, the client already has an ADO project. Work Items are built in — no additional tooling, no additional cost, same context as the ASTRAL drift PRs and restore pipeline. This is the default.
|
||||||
|
|
||||||
|
**Setup**: Create a Work Item type called "Security Finding" (or use the built-in Bug or Task type with a tag). Create a board with columns: `New → Triaged → In Progress → Blocked → Closed`. Add custom fields: Priority (P0/P1/P2), Source (Brownhat / BloodHound / Elysium / ASTRAL / PULSAR / Module N), and Target Date.
|
||||||
|
|
||||||
|
**Why it works**: Consultants who are already reviewing ASTRAL drift PRs see the backlog in the same tool. The client's IT lead who owns remediation works in the same project. No context switching.
|
||||||
|
|
||||||
|
**Teams tab**: Pin the ADO board directly into the relevant Teams channel as a tab — built into the Azure DevOps app for Teams, no additional setup. The IT lead who lives in Teams can view and update Work Items without opening ADO in a browser. This is the recommended surface for non-technical owners: it is always visible, requires no context switch, and keeps the canonical data in ADO.
|
||||||
|
|
||||||
|
**Power Automate (optional)**: If you need to push notifications into Teams or create tasks in Planner when a P0 item is opened or a target date is missed, Power Automate can bridge ADO to the M365 ecosystem. This adds complexity and a dependency on Power Automate flows — use it only if the Teams tab alone is not driving the right behaviour. There is no native ADO → Planner sync without Power Automate.
|
||||||
|
|
||||||
|
**ASTRAL integration**: When ASTRAL raises a drift PR for an unauthorised configuration change that cannot be immediately restored, link the ADO Work Item to the ASTRAL PR. The PR description, the before/after diff, and the reviewer decision are all in the same project — the Work Item is the remediation task, the ASTRAL PR is the evidence.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Option 2 — CISO Assistant (upgrade path for clients building toward GRC)
|
||||||
|
|
||||||
|
[CISO Assistant](https://github.com/intuitem/ciso-assistant-community) is an open-source GRC platform already in the [Sovereign Tool Stack](../playbooks/sovereign-tool-stack.md). It provides risk register functionality, compliance framework mapping (NIS2, ISO 27001, DORA), evidence tracking, and audit-ready reporting — all self-hosted.
|
||||||
|
|
||||||
|
**When to use it instead of ADO Work Items**: When the client has an intent to build a formal risk management programme and needs a tool that can grow into it. CISO Assistant bridges the gap between a pragmatic backlog and a formal risk register: the same findings that start as backlog items can be promoted to documented risks with treatment plans, residual risk assessments, and compliance evidence links.
|
||||||
|
|
||||||
|
**How the backlog feeds CISO Assistant**: During each module, findings are entered into the backlog in ADO or a flat file. At quarterly review, P1 and significant P2 items that are not yet closed are promoted to CISO Assistant as risk entries with the evidence collected during the engagement. The backlog is operational; CISO Assistant is the strategic record.
|
||||||
|
|
||||||
|
**Deployment**: Docker Compose, ~30 minutes. Self-hosted on the client's infrastructure or on a VPS. See the sovereign tool stack for deployment guidance.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Option 3 — Git flat file (fallback for clients without ADO or preference for simplicity)
|
||||||
|
|
||||||
|
A Markdown file committed to the same repository as ASTRAL (or a dedicated security repository). Zero additional tooling. Fully auditable via Git history. Works offline.
|
||||||
|
|
||||||
|
**When to use it**: Clients who have the technical capability to maintain a Markdown file in Git and prefer minimal tooling. Also useful as a transitional format before ADO Work Items are fully configured.
|
||||||
|
|
||||||
|
**Limitation**: No native assignment notifications, no Planner sync, no board view. Progress is visible only to people who look at the repository. For clients where the IT lead needs to be nudged, a flat file will be ignored. Use ADO Work Items or CISO Assistant instead.
|
||||||
|
|
||||||
|
The flat file template is provided below.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Design Principles
|
||||||
|
|
||||||
|
**It must live where the client actually opens things.** If the backlog is in a tool the client never looks at, it does not exist. The three options above are ordered by likelihood of adoption. ADO Work Items wins because ASTRAL is already there — the path of least resistance is the path most likely to be walked.
|
||||||
|
|
||||||
|
**Every finding has an owner.** A finding without a named owner is not tracked — it is archived. The owner does not need to be the person who fixes it. They need to be the person who is accountable for whether it gets fixed.
|
||||||
|
|
||||||
|
**Priority drives the housekeeping stream.** The backlog is the input queue for Rule 4 (housekeeping as a permanent stream). The monthly housekeeping cycle picks from the backlog, resolves what it can, and updates statuses. Without the backlog, the housekeeping stream has no queue to work from.
|
||||||
|
|
||||||
|
**It accumulates from all sources.** Every diagnostic, every module, every ASTRAL drift alert, every PULSAR-flagged event, every BloodHound finding, every Elysium result feeds the backlog. Not just the big assessments. The backlog is the single source of truth for everything that has been found and not yet fixed.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## The Format
|
||||||
|
|
||||||
|
A minimal backlog entry has six fields. Do not add more until the client is actually maintaining this one.
|
||||||
|
|
||||||
|
| Field | What it contains |
|
||||||
|
|-------|-----------------|
|
||||||
|
| **ID** | Sequential identifier (B-001, B-002…). Never reuse an ID. |
|
||||||
|
| **Finding** | One sentence: what is wrong. Not "review accounts" — "47 user accounts belong to staff who have left; credentials remain valid." |
|
||||||
|
| **Source** | Which assessment or tool produced this: Brownhat Diagnostic, BloodHound, Elysium, ASTRAL drift, PULSAR alert, Module 6, etc. |
|
||||||
|
| **Priority** | P0 / P1 / P2 — using the kill chain test (see below) |
|
||||||
|
| **Owner** | Named person, not a team. "AD Team" is not an owner. "Marek Novák" is. |
|
||||||
|
| **Status** | Open / In Progress / Blocked / Closed |
|
||||||
|
|
||||||
|
Optional fields that add value once the basic discipline is established:
|
||||||
|
|
||||||
|
| Field | What it contains |
|
||||||
|
|-------|-----------------|
|
||||||
|
| **Target date** | The date by which this should be resolved. Not when the project ends — when this specific item should be done. |
|
||||||
|
| **Effort** | S / M / L — rough estimate; S = fixable in a day or less, M = a few days, L = needs planning |
|
||||||
|
| **Notes** | Blockers, context, related items, change window requirements |
|
||||||
|
| **Closed date** | When it was actually closed. Important for demonstrating progress to auditors. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Priority Assignment
|
||||||
|
|
||||||
|
Use the kill chain test from the [Consultant Field Guide](../core/consultant-field-guide.md):
|
||||||
|
|
||||||
|
**P0 — Kill chain node.** If exploited, the organisation fails to operate. Fix before anything else. Examples: admin accounts without MFA, unpatched internet-facing system with known active exploit, backup that has never been restored, KRBTGT password over 365 days old.
|
||||||
|
|
||||||
|
**P1 — Material damage.** If exploited, significant harm results but the organisation survives. Fix within the current engagement. Examples: service accounts with non-expiring passwords, open RDP from internet, legacy authentication not blocked, stale privileged accounts.
|
||||||
|
|
||||||
|
**P2 — Should be fixed.** Real finding, real risk, but not existential. Goes into the housekeeping queue for the next available cycle. Examples: weak password policy on non-privileged accounts, missing DNS security filtering, unreviewed firewall rules from two years ago, undocumented vendor access with low privilege.
|
||||||
|
|
||||||
|
> **On priority inflation**: The most common backlog failure is everything being marked P0. If everything is urgent, nothing is. Be ruthless. An environment with more than 5–10 P0 items either has a genuinely catastrophic security posture (in which case the immediate conversation is with the executive sponsor) or the priority assignments are wrong.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Backlog Template (Flat File Version)
|
||||||
|
|
||||||
|
For clients whose teams work in a repository (preferred — the backlog lives alongside ASTRAL):
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Findings Backlog
|
||||||
|
|
||||||
|
Last reviewed: [DATE] | Owner: [NAME] | Next review: [DATE]
|
||||||
|
|
||||||
|
## P0 — Kill Chain (fix immediately)
|
||||||
|
|
||||||
|
| ID | Finding | Source | Owner | Status | Target |
|
||||||
|
|----|---------|--------|-------|--------|--------|
|
||||||
|
| B-001 | | | | | |
|
||||||
|
|
||||||
|
## P1 — Material Risk (fix this engagement)
|
||||||
|
|
||||||
|
| ID | Finding | Source | Owner | Status | Target |
|
||||||
|
|----|---------|--------|-------|--------|--------|
|
||||||
|
| B-010 | | | | | |
|
||||||
|
|
||||||
|
## P2 — Housekeeping Queue (monthly cycle)
|
||||||
|
|
||||||
|
| ID | Finding | Source | Owner | Status | Target |
|
||||||
|
|----|---------|--------|-------|--------|--------|
|
||||||
|
| B-100 | | | | | |
|
||||||
|
|
||||||
|
## Closed
|
||||||
|
|
||||||
|
| ID | Finding | Closed date | Closed by |
|
||||||
|
|----|---------|-------------|-----------|
|
||||||
|
| | | | |
|
||||||
|
```
|
||||||
|
|
||||||
|
Use ID ranges to signal priority at a glance: B-001–B-009 for P0, B-010–B-099 for P1, B-100+ for P2.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Populating the Backlog
|
||||||
|
|
||||||
|
### On Day 30 (from the Brownhat Diagnostic)
|
||||||
|
|
||||||
|
The Brownhat Diagnostic produces the first population of the backlog. Every finding from the diagnostic gets an entry. Quick wins that are closed immediately during the engagement go straight to Closed with the closing date. Everything else — including findings the client acknowledges but cannot act on immediately — goes into the backlog with the appropriate priority.
|
||||||
|
|
||||||
|
The consultant populates the initial backlog as part of the diagnostic deliverable. It is not a separate engagement. It is what happens to findings instead of filing them in a PDF.
|
||||||
|
|
||||||
|
### From subsequent modules
|
||||||
|
|
||||||
|
Every module completion package includes an update to the backlog:
|
||||||
|
- Findings that were closed by the module move to Closed
|
||||||
|
- New findings discovered during the module are added
|
||||||
|
- The risk register update in the module completion package cross-references the backlog IDs
|
||||||
|
|
||||||
|
### From continuous tools (ASTRAL, PULSAR, Elysium)
|
||||||
|
|
||||||
|
- **ASTRAL** — when a drift PR is raised for an unauthorised configuration change, a backlog entry is created if the change is not immediately remediated. The ASTRAL PR link goes in the Notes field.
|
||||||
|
- **PULSAR** — when an alert is investigated and reveals a structural gap (not just an event), a backlog entry is created. The PULSAR event ID goes in the Notes field.
|
||||||
|
- **Elysium** (quarterly run) — each new compromised or weak credential that cannot be immediately reset gets a backlog entry.
|
||||||
|
- **BloodHound** (quarterly run) — new or persistent attack paths get backlog entries with the path description.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## The Housekeeping Cycle
|
||||||
|
|
||||||
|
The monthly housekeeping cycle (Rule 4 of [Move Fast and Fix Things](../core/move-fast-and-fix-things.md)) works from the backlog. The cycle has a simple structure:
|
||||||
|
|
||||||
|
1. **Review open P0 items.** If any P0 is still open and not blocked by an external dependency, it is the first priority. If it has been open more than 30 days without progress, it escalates to the executive sponsor.
|
||||||
|
2. **Work P1 items.** Each cycle resolves at least one P1 item. If no P1 items are being resolved, the housekeeping stream is not functioning — find the blocker.
|
||||||
|
3. **Advance P2 items.** Move through the P2 queue at the capacity available. Not every cycle will close P2 items. Every cycle should move at least one P2 item to In Progress.
|
||||||
|
4. **Review and reprioritise.** As the environment changes, priorities shift. A P2 item that has been open for six months may be a P0 in disguise if nothing above it has been fixed.
|
||||||
|
5. **Update statuses.** Every item touched in the cycle gets a status update, even if the update is "Blocked — waiting for change window."
|
||||||
|
|
||||||
|
The output of each cycle is a one-page summary: items closed this cycle, items In Progress, blockers, and the current P0/P1 count. This summary goes to the named client lead. If retained capability is in scope, it goes to the CQRE consultant as well.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Relationship to the Risk Register
|
||||||
|
|
||||||
|
If the client has a working risk register, the backlog and the risk register coexist:
|
||||||
|
|
||||||
|
- The backlog is **operational** — it is where findings live while they are being worked
|
||||||
|
- The risk register is **strategic** — it captures the risk that the finding represents, the treatment decision, and the residual risk after treatment
|
||||||
|
- When a P0 or P1 item is closed, the consultant works with the client to create or update the corresponding risk register entry with the closure evidence
|
||||||
|
|
||||||
|
If the client does not have a working risk register, the backlog is effectively doing the risk register's job at a reduced level of formality. Do not pretend otherwise. If the client ever needs to demonstrate risk management to a regulator or auditor, the backlog — with its closure dates, ownership, and priority history — is defensible evidence. A GRC tool with empty fields is not.
|
||||||
|
|
||||||
|
For clients who want to build a proper risk register: the backlog entries, once they have closure evidence attached, become the input for the risk register's treatment and closure records. The backlog is not wasted effort — it is the work that feeds the register.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Backlog Health Indicators
|
||||||
|
|
||||||
|
These are warning signs that the backlog is not functioning:
|
||||||
|
|
||||||
|
| Indicator | What it means |
|
||||||
|
|-----------|--------------|
|
||||||
|
| P0 items open for more than 30 days with no progress | Executive escalation required; a P0 that nobody is moving is a political problem, not a technical one |
|
||||||
|
| More than 20 items in the backlog with no owner | The backlog was populated but not handed over properly; go back and assign owners |
|
||||||
|
| No items closed in the last monthly cycle | The housekeeping stream is not running; find the responsible person and re-establish the cadence |
|
||||||
|
| All items are P2 | Priority inflation has happened in reverse; the consultant needs to revisit severity assignments |
|
||||||
|
| The backlog has not been updated since the last engagement | The backlog is a report, not a system; the client has reverted to treating findings as documentation rather than as work |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Related: [Module Completion Report](module-completion-report.md) — each module updates the backlog as part of its completion package.*
|
||||||
|
*Related: [Antifragile Risk Register](antifragile-risk-register.md) — the formal risk register template; the backlog feeds into it.*
|
||||||
|
*Related: [Move Fast and Fix Things — Rule 4](../core/move-fast-and-fix-things.md#rule-4-run-housekeeping-as-a-permanent-stream) — the backlog is the queue that Rule 4 works from.*
|
||||||
|
*Related: [Engagement Model](../core/engagement-model.md) — backlog setup is part of every module kickoff.*
|
||||||
@@ -0,0 +1,334 @@
|
|||||||
|
# Sample Engagement: Mid-Market Hybrid Organisation
|
||||||
|
|
||||||
|
> *This document is a calibration reference for consultants. It walks through a realistic engagement for a specific client profile from first contact through Day 180. Use it to calibrate your own scope estimates, find comparable findings for risk register entries, and understand what a complete engagement looks like for this type of organisation.*
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Client Profile: Nexus Operations s.r.o.
|
||||||
|
|
||||||
|
**Fictional client. All details are representative of a real mid-market profile.**
|
||||||
|
|
||||||
|
| Attribute | Detail |
|
||||||
|
|-----------|--------|
|
||||||
|
| **Size** | 500 employees, 10 IT/admin staff |
|
||||||
|
| **Sector** | Professional services (management consulting + outsourced IT services) — NIS2 **important entity** under digital infrastructure provisions |
|
||||||
|
| **Identity** | Active Directory (on-premises, single forest, two domains — legacy acquisition) + Entra ID (hybrid join, Azure AD Connect sync) |
|
||||||
|
| **M365 licensing** | E3 — includes Entra ID P1 (Conditional Access), Defender for Endpoint Plan 1, Intune, Exchange Online, SharePoint, Teams. No E5 features: no PIM, no Defender for Identity, no Sentinel, no Purview advanced. |
|
||||||
|
| **Endpoint management** | Intune deployed 18 months ago; ~70% Windows enrollment, ~30% macOS enrollment; no iOS/Android policy; Intune used primarily for app deployment, not compliance enforcement |
|
||||||
|
| **Third-party tools** | Jira (cloud), GitHub (cloud, mix of org/personal accounts), Confluence (cloud), a legacy on-prem ERP (SAP), an on-prem file server (Windows Server 2016), a CRM (Salesforce), and approximately 12 other SaaS tools identified in procurement; shadow IT suspected |
|
||||||
|
| **Infrastructure** | Three offices (Prague HQ, Brno, Warsaw); hybrid work standard; ~80 external contractors at any given time; site-to-site VPN between offices; split DNS; no SD-WAN |
|
||||||
|
| **Current security** | No dedicated security tool beyond Defender AV. Microsoft Secure Score: 42%. No SIEM. No SOC. Previous pentest 2 years ago (report available). Previous ISO 27001 attempt abandoned 18 months ago. |
|
||||||
|
| **NIS2 status** | In-scope as important entity; national transposition deadline passed; supervisory authority has sent initial questionnaire; response due in 90 days |
|
||||||
|
| **Trigger** | NIS2 questionnaire received; CTO has seen the [Brownhat Diagnostic](../assessment-templates/nist-csf-baseline.md) approach referenced by a peer; CISO role vacant (they are looking) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Engagement Context
|
||||||
|
|
||||||
|
### Why They Called
|
||||||
|
|
||||||
|
The NIS2 questionnaire is the proximate trigger but not the underlying problem. The CTO's real concern, surfaced in the discovery call: "We have been growing fast, the acquisition two years ago added a lot of mess, and I genuinely do not know what we would do if we had a serious incident. We have contractors everywhere and I am not sure all of them are properly offboarded when their engagement ends."
|
||||||
|
|
||||||
|
This is a common and honest framing. The NIS2 deadline creates a compliance urgency, but the actual risk is operational — undocumented access, accumulated technical debt from the acquisition, and no detection capability.
|
||||||
|
|
||||||
|
### What the Discovery Call Revealed
|
||||||
|
|
||||||
|
**The trigger question** ("What happened recently that made you call us?") produced: the NIS2 questionnaire, plus a near-miss three months ago — a contractor who had left six months previously used their still-active account to access a SharePoint site. Nobody noticed until the contractor themselves mentioned it to their former manager. No data exfiltration confirmed but not verified.
|
||||||
|
|
||||||
|
**The accountability question**: Named IT lead is the senior sysadmin, Ondřej Blaha. CTO is the executive sponsor. CISO role vacant — the IT lead is acting as de facto security lead without the title or dedicated time.
|
||||||
|
|
||||||
|
**The tools question**: E3 confirmed. Intune confirmed but underutilised. No SIEM. Previous pentest report available (2 years old). Defender AV on all Windows endpoints; coverage on macOS "mostly."
|
||||||
|
|
||||||
|
**The success question**: "Pass the NIS2 questionnaire. Know that if something happens, we can respond. And if I hire a CISO in six months, I want there to be something to hand over."
|
||||||
|
|
||||||
|
This is an excellent brief. Concrete, honest, achievable.
|
||||||
|
|
||||||
|
### What Disqualifies This Client?
|
||||||
|
|
||||||
|
Nothing. All green lights:
|
||||||
|
- Named executive sponsor with budget authority (CTO)
|
||||||
|
- Named IT lead with operational access (Ondřej)
|
||||||
|
- Real trigger with a deadline (NIS2 response in 90 days)
|
||||||
|
- Honest assessment of current state
|
||||||
|
- Realistic success criteria
|
||||||
|
|
||||||
|
**One flag to manage**: The NIS2 questionnaire response is due in 90 days. This creates urgency that may pressure the client to skip the Brownhat Diagnostic and go straight to "give us a report for the regulator." Resist this. The diagnostic *is* the report — it produces evidence directly usable in the NIS2 response. Skipping it produces a worse outcome for both the client and the regulator.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Brownhat Diagnostic Findings
|
||||||
|
|
||||||
|
*What a competent two-day diagnostic would find in this environment. Presented as the consultant would present it to the CTO.*
|
||||||
|
|
||||||
|
### Kill Chain Assessment
|
||||||
|
|
||||||
|
The shortest path from "nothing bad has happened yet" to "Nexus Operations cannot operate" runs through identity.
|
||||||
|
|
||||||
|
```
|
||||||
|
Compromised contractor credential (still active after offboarding)
|
||||||
|
→ Access to M365 (no MFA enforced, or legacy auth bypasses MFA)
|
||||||
|
→ Access to SharePoint / Teams (all data)
|
||||||
|
→ Access to Exchange (all email, calendar, contacts)
|
||||||
|
→ Password spray against Entra ID → escalate to admin account
|
||||||
|
→ Domain Admin via Entra ID Connect sync account
|
||||||
|
→ Full AD compromise → all on-prem systems
|
||||||
|
→ ERP (SAP) → financial data, operational disruption
|
||||||
|
```
|
||||||
|
|
||||||
|
This is not theoretical. The six-month-old contractor account near-miss is one credential spray away from the beginning of this chain.
|
||||||
|
|
||||||
|
**Secondary kill chain** (on-prem):
|
||||||
|
```
|
||||||
|
Internet-facing VPN endpoint (legacy firmware, no MFA)
|
||||||
|
→ Internal network access
|
||||||
|
→ Lateral movement via NTLM relay (expected: NTLM not disabled)
|
||||||
|
→ File server → ERP → AD
|
||||||
|
```
|
||||||
|
|
||||||
|
### Findings by Priority
|
||||||
|
|
||||||
|
#### P0 — Kill Chain Nodes
|
||||||
|
|
||||||
|
| ID | Finding | Evidence |
|
||||||
|
|----|---------|----------|
|
||||||
|
| P0-001 | **No MFA enforced for remote access or M365** | Entra ID sign-in logs show 34% of sign-ins in past 30 days without MFA; Conditional Access policies exist but are in Report-Only mode, never activated |
|
||||||
|
| P0-002 | **Active contractor accounts: 23 confirmed stale** | Elysium identifies 23 accounts with last login > 90 days owned by contractors whose engagements are confirmed ended in HR system; 6 have been inactive for > 6 months |
|
||||||
|
| P0-003 | **KRBTGT password never rotated** | Last rotation: 847 days (default since domain creation). Any Golden Ticket attack persists across credential resets until KRBTGT is rotated. |
|
||||||
|
| P0-004 | **Azure AD Connect sync account has excessive privilege** | The sync service account has DCSync rights on the on-premises domain. Compromise of Entra ID admin → on-prem domain compromise via this account. |
|
||||||
|
| P0-005 | **VPN endpoint: no MFA, outdated firmware** | Cisco ASA, firmware 18 months out of date; no MFA for VPN authentication; used by all contractors and remote employees |
|
||||||
|
| P0-006 | **No tested backup restore** | Backups run nightly (confirmed); no restore has ever been tested; ERP backup destination is on the same network segment as the ERP server |
|
||||||
|
|
||||||
|
#### P1 — Material Risk
|
||||||
|
|
||||||
|
| ID | Finding | Evidence |
|
||||||
|
|----|---------|----------|
|
||||||
|
| P1-001 | **Legacy authentication not blocked** | Sign-in logs: 847 legacy auth attempts in past 30 days from 34 unique accounts; these bypass MFA regardless of CA policy |
|
||||||
|
| P1-002 | **Domain Admins using workstations for email and browsing** | BloodHound: 4 of 5 Domain Admin accounts have interactive logon events from standard workstations; no PAW architecture |
|
||||||
|
| P1-003 | **Service accounts: 31 with non-expiring passwords, 12 with unknown owners** | AD audit; 7 service accounts have Domain Admin-equivalent rights with no documented purpose |
|
||||||
|
| P1-004 | **Intune compliance not enforced in Conditional Access** | Compliant device requirement is in CA policy but excluded for all users via the "AllUsers_ExceptionGroup" group containing 489 of 500 users |
|
||||||
|
| P1-005 | **Third-party SaaS access not reviewed** | 12 known SaaS tools; Entra ID app registrations show 47 enterprise applications with consent grants; 11 have "Mail.ReadWrite" or equivalent scopes from unidentified sources |
|
||||||
|
| P1-006 | **No MFA on GitHub** | GitHub org admin accounts without MFA enforced at org level; mix of personal and managed accounts; no SSO integration with Entra |
|
||||||
|
| P1-007 | **SAP ERP on-prem: default admin credentials not changed on secondary instance** | Confirmed during document review of previous pentest report |
|
||||||
|
| P1-008 | **No logging beyond M365 default 90-day retention** | No SIEM; no secondary log retention; M365 audit log at 90-day E3 default; ERP and file server logs local only, 30-day retention |
|
||||||
|
|
||||||
|
#### P2 — Housekeeping Queue
|
||||||
|
|
||||||
|
| ID | Finding |
|
||||||
|
|----|---------|
|
||||||
|
| P2-001 | NTLM not disabled; NTLMv1 still permitted in GPO |
|
||||||
|
| P2-002 | Basic authentication still enabled for Exchange (in addition to legacy auth block needed above) |
|
||||||
|
| P2-003 | 89 stale AD accounts (not contractors — former employees; some date to 2019) |
|
||||||
|
| P2-004 | DNS records for 14 decommissioned services still exist |
|
||||||
|
| P2-005 | Firewall ruleset last reviewed 3 years ago; 23 rules with "any/any" destination |
|
||||||
|
| P2-006 | macOS endpoints: Defender coverage patchy; 31 devices not enrolled in Intune |
|
||||||
|
| P2-007 | No documented vendor access procedure; contractors provisioned ad hoc |
|
||||||
|
| P2-008 | Windows Server 2016 file server: extended support ends October 2026 |
|
||||||
|
| P2-009 | Jira/Confluence: 67 former employee accounts still active |
|
||||||
|
| P2-010 | SharePoint external sharing enabled globally with no policy; 14 sites have external links active |
|
||||||
|
|
||||||
|
### Quick Wins (Closeable Before Day 30)
|
||||||
|
|
||||||
|
1. **Activate CA policies** — already in Report-Only; switch to Enabled. MFA enforcement for all sign-ins with zero new tooling. (2 hours)
|
||||||
|
2. **Disable 23 confirmed stale contractor accounts** — HR-confirmed departures; disable immediately. (1 hour, needs HR sign-off already obtained)
|
||||||
|
3. **Remove AllUsers_ExceptionGroup from CA compliance policy** — 489 users are excepted from device compliance for no documented reason. Remove the exception. (30 minutes)
|
||||||
|
4. **Block legacy authentication** — CA policy for legacy auth block already exists in the tenant (Microsoft provides a template); activate it. Test first with sign-in log review. (4 hours including testing)
|
||||||
|
5. **Enforce MFA on GitHub org** — Organisation setting, 2 minutes to enable; will force any admin without MFA to enrol at next login. (5 minutes)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Module Recommendation and Rationale
|
||||||
|
|
||||||
|
### Recommended Sequence
|
||||||
|
|
||||||
|
```
|
||||||
|
Brownhat Diagnostic + Quick Wins (Weeks 1-4)
|
||||||
|
↓
|
||||||
|
Module 2: M365 Identity Security (Weeks 4-10) ← Primary kill chain
|
||||||
|
↓
|
||||||
|
Module 6: On-Premise AD Hardening (Weeks 8-14) ← Runs in parallel from week 8
|
||||||
|
↓
|
||||||
|
Module 1: Endpoint Management (Weeks 14-18) ← Hardens existing Intune
|
||||||
|
↓
|
||||||
|
Module 7: Recovery & Resilience (Weeks 16-20) ← Runs in parallel from week 16
|
||||||
|
```
|
||||||
|
|
||||||
|
### Rationale
|
||||||
|
|
||||||
|
**Why Module 2 first**: The kill chain runs through identity. P0-001 (no MFA enforced), P0-002 (stale contractor accounts), and P1-001 (legacy auth) are all Module 2 work. These are also the fastest path to demonstrable NIS2 evidence — Article 21 explicitly requires MFA and access control measures.
|
||||||
|
|
||||||
|
**Why Module 6 second, partially parallel**: P0-003 (KRBTGT rotation), P0-004 (AD Connect privilege), and P1-002 (Domain Admins on standard workstations) require AD access and change windows. This work can start in week 8 as Module 2 is closing — the identity team has already been engaged, the change management process is established.
|
||||||
|
|
||||||
|
**Why Module 1 third, not first**: Intune is already deployed and roughly functional. It is not the kill chain. Hardening Intune (compliance policies, CA integration, full macOS enrollment) is important but secondary to closing the identity gaps. It belongs in Week 14 when identity work is complete.
|
||||||
|
|
||||||
|
**Why Module 7 matters here**: The ERP backup (P0-006) is a kill chain node. Recovery and Resilience validates backup integrity and produces the restore test evidence that NIS2 business continuity requirements directly demand. Starting Module 7 in parallel with Module 1 from Week 16 gets this done within 180 days.
|
||||||
|
|
||||||
|
**Not recommended in this engagement**:
|
||||||
|
- Module 5 (AI Sovereignty Bridge): not in the kill chain; deferred to Phase 4
|
||||||
|
- Module 10 (Red Team): requires a hardened foundation; schedule at 12 months post-engagement
|
||||||
|
- Module 12 (Blue/Purple Team): requires detection infrastructure not yet deployed; follow-on engagement
|
||||||
|
- Module 8 (OT): not applicable — no OT environment
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Day 30 / Day 90 / Day 180: This Specific Client
|
||||||
|
|
||||||
|
### Day 30 Deliverables
|
||||||
|
|
||||||
|
| # | Deliverable | Nexus-specific detail |
|
||||||
|
|---|-------------|----------------------|
|
||||||
|
| 1 | Brownhat Diagnostic report | Kill chain documented (identity → AD → ERP); 5 quick wins; module roadmap |
|
||||||
|
| 2 | ASTRAL deployed | Intune + Entra ID baseline committed; Azure DevOps project `ASTRAL-Nexus` created; drift detection live |
|
||||||
|
| 3 | PULSAR deployed | M365 audit events ingesting; Ondřej confirmed as reviewer; Teams tab pinned in IT channel |
|
||||||
|
| 4 | T0 accounts hardened | 3 Global Admins: MFA enforced, dedicated admin accounts separated from daily-use accounts |
|
||||||
|
| 5 | Attack surface report | VPN endpoint flagged (P0-005); external-facing services enumerated |
|
||||||
|
| 6 | Quick wins closed | CA policies activated; 23 contractor accounts disabled; legacy auth blocked; GitHub MFA enforced; Intune compliance exception removed |
|
||||||
|
| 7 | Findings backlog opened | All diagnostic findings entered in ADO Work Items; Ondřej named as owner for P0/P1; CTO briefed on P0 count (6) and quick wins status |
|
||||||
|
|
||||||
|
> **NIS2 value at Day 30**: The Brownhat Diagnostic report and the quick wins closure log constitute direct evidence for NIS2 Article 21 (access control, MFA, asset management). PULSAR starts accumulating the audit log retention the questionnaire will ask about.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Day 90 Deliverables
|
||||||
|
|
||||||
|
| # | Deliverable | Nexus-specific detail |
|
||||||
|
|---|-------------|----------------------|
|
||||||
|
| 8 | MFA for all users enforced | CA policy covering all 500 users; verified via sign-in logs; helpdesk prepared for exceptions (expected: ~15 users requiring assisted enrolment) |
|
||||||
|
| 9 | Legacy auth blocked | Verified: zero legacy auth sign-ins in past 7 days in PULSAR |
|
||||||
|
| 10 | CA baseline deployed | Device compliance required; location-based policies for Warsaw office (different risk profile); sign-in risk policy active |
|
||||||
|
| 11 | P0 vulnerabilities closed | P0-002 (contractors) ✓ Day 30; P0-003 (KRBTGT) rotated with two-rotation process; P0-004 (AD Connect account) de-privileged; P0-005 (VPN MFA) enforced |
|
||||||
|
| 12 | AD attack path reduction | BloodHound before/after: paths to Domain Admin reduced from 847 to <50; service accounts with Domain Admin rights reduced from 7 to 0 |
|
||||||
|
| 13 | Vendor access hardened | Contractor provisioning procedure documented; offboarding checklist created and linked to HR process; Ondřej named as monthly reviewer |
|
||||||
|
| 14 | T0 backup integrity | ERP backup tested and restored to isolated environment; restore time documented (target: <4 hours); backup destination moved off same network segment |
|
||||||
|
| 15 | ASTRAL: first restore drill | Intentional test change made and restored via pipeline; process documented |
|
||||||
|
| 16 | PULSAR: top 5 alert rules | CA policy modification; new Global Admin assignment; bulk mailbox export; new high-privilege app consent; VPN authentication failure spike |
|
||||||
|
|
||||||
|
> **NIS2 value at Day 90**: MFA enforcement (Article 21c), access control and account management (Article 21i), audit log retention accumulating since Day 30 (Article 21j), backup integrity evidence (Article 21c business continuity). Sufficient to respond to the NIS2 questionnaire with evidence, not assertions.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Day 180 Deliverables
|
||||||
|
|
||||||
|
| # | Deliverable | Nexus-specific detail |
|
||||||
|
|---|-------------|----------------------|
|
||||||
|
| 17 | Alert runbooks | 5 PULSAR alert runbooks signed off by Ondřej; escalation path to CTO documented |
|
||||||
|
| 18 | Custom detection rules | Contractor account creation outside HR-approved window; SAP admin login outside business hours; bulk SharePoint download |
|
||||||
|
| 19 | Client independence | Ondřej completes live walkthrough: reviews ASTRAL PR, investigates a PULSAR event, resets a compromised Elysium-flagged account |
|
||||||
|
| 20 | Housekeeping: 3 cycles | Cycles 1–3 completed; 67 Jira/Confluence accounts resolved; 89 stale AD accounts processed (disabled with justification per account); DNS cleanup in progress |
|
||||||
|
| 21 | Module completion packages | Module 2, Module 6, Module 1 completion packages delivered to `nexus-security` ADO repository |
|
||||||
|
| 22 | Risk register closure | Before/after comparison: P0 count 6 → 0; P1 count 8 → 2 (P1-007 SAP default credentials and P1-005 app consent review in housekeeping queue) |
|
||||||
|
| 23 | Retained capability scope | Agreed quarterly scope: monthly ASTRAL drift review, quarterly BloodHound + Elysium run, PULSAR health check, housekeeping queue advancement |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Findings Backlog — Initial Population
|
||||||
|
|
||||||
|
*Pre-populated from the Brownhat Diagnostic. Consultants: adapt IDs and details to your actual findings.*
|
||||||
|
|
||||||
|
**ADO Work Items project**: `ASTRAL-Nexus` (same project as ASTRAL deployment)
|
||||||
|
**Owner**: Ondřej Blaha
|
||||||
|
**Cadence**: Monthly housekeeping review, first Thursday of each month
|
||||||
|
|
||||||
|
### P0 — Kill Chain (all closed by Day 90)
|
||||||
|
|
||||||
|
| ID | Finding | Source | Owner | Status | Target |
|
||||||
|
|----|---------|--------|-------|--------|--------|
|
||||||
|
| B-001 | No MFA enforced: 34% of sign-ins without MFA | Brownhat | Ondřej | **Closed** Day 30 | Day 30 |
|
||||||
|
| B-002 | 23 stale contractor accounts with valid credentials | Elysium | Ondřej | **Closed** Day 30 | Day 30 |
|
||||||
|
| B-003 | KRBTGT password 847 days old | BloodHound | Ondřej | **Closed** Day 75 | Day 60 |
|
||||||
|
| B-004 | AD Connect sync account has DCSync rights | BloodHound | Ondřej | **Closed** Day 70 | Day 60 |
|
||||||
|
| B-005 | VPN: no MFA, firmware 18 months outdated | Brownhat | Ondřej | **Closed** Day 80 | Day 90 |
|
||||||
|
| B-006 | No tested ERP backup restore | Brownhat | Ondřej | **Closed** Day 85 | Day 90 |
|
||||||
|
|
||||||
|
### P1 — Material Risk
|
||||||
|
|
||||||
|
| ID | Finding | Source | Owner | Status | Target |
|
||||||
|
|----|---------|--------|-------|--------|--------|
|
||||||
|
| B-010 | Legacy auth not blocked: 847 sign-ins in 30 days | PULSAR | Ondřej | **Closed** Day 30 | Day 30 |
|
||||||
|
| B-011 | Domain Admins using standard workstations | BloodHound | Ondřej | **Closed** Day 65 | Day 60 |
|
||||||
|
| B-012 | 7 service accounts with Domain Admin rights, no documented purpose | AD audit | Ondřej | **Closed** Day 72 | Day 60 |
|
||||||
|
| B-013 | Intune compliance exception covers 489/500 users | ASTRAL | Ondřej | **Closed** Day 30 | Day 30 |
|
||||||
|
| B-014 | 47 Entra app registrations with Mail.ReadWrite or higher scope | Entra audit | Ondřej | In Progress | Day 120 |
|
||||||
|
| B-015 | GitHub org: no MFA enforcement, personal/managed account mix | Brownhat | Ondřej | **Closed** Day 30 | Day 30 |
|
||||||
|
| B-016 | SAP secondary instance: default admin credentials not changed | Pentest report | IT Lead (SAP) | Open | Day 90 |
|
||||||
|
| B-017 | No audit log retention beyond 90 days | Brownhat | Ondřej | **Closed** Day 1 (PULSAR) | Day 30 |
|
||||||
|
|
||||||
|
### P2 — Housekeeping Queue
|
||||||
|
|
||||||
|
| ID | Finding | Source | Owner | Status | Target |
|
||||||
|
|----|---------|--------|-------|--------|--------|
|
||||||
|
| B-100 | NTLM not disabled; NTLMv1 permitted | AD audit | Ondřej | Open | Q3 |
|
||||||
|
| B-101 | 89 stale AD accounts from former employees | Elysium | Ondřej | In Progress (Cycle 2) | Q3 |
|
||||||
|
| B-102 | 14 DNS records for decommissioned services | AD audit | Ondřej | Open | Q3 |
|
||||||
|
| B-103 | 23 firewall rules with any/any destination | Firewall review | Network | Open | Q4 |
|
||||||
|
| B-104 | 31 macOS devices not enrolled in Intune | ASTRAL/Intune | Ondřej | In Progress (Module 1) | Day 180 |
|
||||||
|
| B-105 | No documented vendor access procedure | Brownhat | Ondřej | **Closed** Day 85 | Day 90 |
|
||||||
|
| B-106 | Windows Server 2016 file server: EOL Oct 2026 | Brownhat | CTO | Open | Oct 2026 |
|
||||||
|
| B-107 | 67 former employee accounts in Jira/Confluence | Brownhat | Ondřej | In Progress (Cycle 1) | Q3 |
|
||||||
|
| B-108 | SharePoint external sharing: 14 sites with active external links | ASTRAL | Ondřej | Open | Q3 |
|
||||||
|
| B-109 | Basic auth still enabled for Exchange | Brownhat | Ondřej | Open | Q2 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## NIS2 Article 21 Compliance Map
|
||||||
|
|
||||||
|
*Evidence produced by this engagement against the Article 21 measures. Use this table in the NIS2 questionnaire response.*
|
||||||
|
|
||||||
|
| Article 21 Measure | Requirement | Evidence from this engagement |
|
||||||
|
|--------------------|-------------|-------------------------------|
|
||||||
|
| **21(2)(a)** Policies on risk analysis and information security | Documented policies | Brownhat Diagnostic report; module completion packages; risk register |
|
||||||
|
| **21(2)(b)** Incident handling | Detection and response capability | PULSAR alert rules + runbooks; incident escalation procedure |
|
||||||
|
| **21(2)(c)** Business continuity, backup, DR | Tested backup and recovery | Module 7: ERP backup restore test report; Recovery Time documented |
|
||||||
|
| **21(2)(d)** Supply chain security | Vendor/supplier risk management | Contractor access procedure; vendor access inventory; offboarding checklist |
|
||||||
|
| **21(2)(e)** Security in acquisition, development | Secure development and procurement | (Partial — addressed in Phase 4; not covered in 180-day programme) |
|
||||||
|
| **21(2)(f)** Policies to assess effectiveness | Metrics and review cadence | ASTRAL drift history; PULSAR event summaries; quarterly BloodHound/Elysium; housekeeping cycle reports |
|
||||||
|
| **21(2)(g)** Cyber hygiene and training | Basic hygiene and awareness | MFA enforcement; CA policies; device compliance; housekeeping stream |
|
||||||
|
| **21(2)(h)** Cryptography and encryption | Encryption standards | (Addressed via CA device compliance and baseline — documented) |
|
||||||
|
| **21(2)(i)** HR security, access control, asset management | Identity governance, privileged access | Module 2: MFA, CA, privileged account management; Module 6: AD hardening; stale account process |
|
||||||
|
| **21(2)(j)** Authentication, MFA | MFA for all users | CA policy enforced for all 500 users; verified via sign-in log (Day 90 deliverable #8) |
|
||||||
|
|
||||||
|
**For the supervisory authority questionnaire**: The strongest evidence package is: (1) the Brownhat Diagnostic report showing risk analysis was conducted, (2) the ASTRAL baseline showing configuration management is operational, (3) the PULSAR deployment showing logging and monitoring is in place, and (4) the Day 90 MFA enforcement verification via sign-in logs. These four items directly answer the most common questions in NIS2 supervisory questionnaires.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Investment Estimate
|
||||||
|
|
||||||
|
*Effort ranges using the module investment levels from [Modular Engagements](../core/modular-engagements.md). Day rates applied per engagement proposal.*
|
||||||
|
|
||||||
|
| Phase | Activity | Estimated Effort |
|
||||||
|
|-------|----------|-----------------|
|
||||||
|
| Brownhat Diagnostic | 2-day workshop + report | 16–20 consultant hours |
|
||||||
|
| Quick wins implementation | CA policies, account disables, GitHub MFA | 8–12 hours (same week as diagnostic) |
|
||||||
|
| Module 2: M365 Identity Security | MFA rollout (500 users, 10 admins, contractors), CA baseline, legacy auth block, app consent review, ASTRAL/PULSAR deployment | **Low to medium** (20–30 consultant days) |
|
||||||
|
| Module 6: On-Premise AD Hardening | KRBTGT rotation, service account cleanup, PAW for admins, BloodHound remediation, AD Connect de-privilege | **Low to medium** (15–25 consultant days) |
|
||||||
|
| Module 1: Endpoint Management | Intune compliance baseline, macOS enrollment, CA integration, ASTRAL hardening | **Low** (8–15 consultant days) |
|
||||||
|
| Module 7: Recovery & Resilience | Backup integrity testing, ERP restore drill, DR runbooks | **Low** (8–12 consultant days) |
|
||||||
|
| **Total 180-day programme** | | **~55–80 consultant days** |
|
||||||
|
|
||||||
|
**Infrastructure costs** (one-time, at cost):
|
||||||
|
- PULSAR hosting: €10–20/month (VPS or Azure Container Apps) — or on the client's existing infrastructure
|
||||||
|
- ASTRAL: no additional cost (Azure DevOps pipelines within E3/Microsoft Partner allocation)
|
||||||
|
|
||||||
|
**Retained capability** (post-180 days, quarterly):
|
||||||
|
- Monthly ASTRAL drift review and PULSAR health check
|
||||||
|
- Quarterly BloodHound + Elysium run + housekeeping cycle
|
||||||
|
- Estimated: 3–5 consultant days per quarter
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Consultant Notes
|
||||||
|
|
||||||
|
**The CISO handover opportunity**: The CTO mentioned they want something to hand over when they hire a CISO. Structure the Day 180 deliverables explicitly as a CISO onboarding package: the backlog, the ASTRAL history, the PULSAR event summary, the module completion packages, and the retained scope. A new CISO who inherits a cleaned AD, enforced MFA, running detection, and a maintained backlog is in a position to build — not to firefight.
|
||||||
|
|
||||||
|
**Managing the NIS2 timeline pressure**: The questionnaire is due in 90 days. The Day 90 deliverables are specifically designed to produce the four evidence items (diagnostic, ASTRAL, PULSAR, MFA enforcement) needed to answer the questionnaire. Do not let the regulatory deadline distort the sequence — the diagnostic first, then module work. A questionnaire answered with ASTRAL drift logs and CA sign-in evidence is stronger than one answered with a Word document and good intentions.
|
||||||
|
|
||||||
|
**The two-domain AD**: The acquisition-created second domain adds complexity to Module 6. Scope it explicitly in the kickoff: which domain gets the KRBTGT rotation first? Are there forest-level trusts? BloodHound collection needs to cover both. Add 5–7 days to the Module 6 estimate if the trust relationship is poorly documented.
|
||||||
|
|
||||||
|
**SAP credentials (P1-016)**: This finding is outside the standard M365/AD scope. It requires SAP admin access and coordination with the ERP team (who may not report to Ondřej). Flag it as an explicit dependency at kickoff — it will slip past Day 90 without an owner from the ERP side.
|
||||||
|
|
||||||
|
**Contractors**: 80 contractors at any given time means the offboarding process is a permanent operational concern, not a one-time fix. The contractor provisioning and offboarding procedure (B-105) must name an owner in HR, not just IT. If HR does not send a termination notification, IT cannot offboard. This is a process dependency that the engagement alone cannot fix — it requires a management conversation.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*This sample engagement is based on composite real-world findings from mid-market AD+M365 environments. All company names and individual details are fictional.*
|
||||||
|
|
||||||
|
*Related: [Brownhat Diagnostic](../assessment-templates/nist-csf-baseline.md) · [Module Menu](../core/modular-engagements.md) · [Findings Backlog](../assessment-templates/findings-backlog.md) · [NIS2 Mapping](../reference/nist-csf-mapping.md) · [Risk Register Example](../assessment-templates/risk-register-example.md)*
|
||||||
Reference in New Issue
Block a user