diff --git a/.claude/users.json b/.claude/users.json index cd3e66c..e940968 100644 --- a/.claude/users.json +++ b/.claude/users.json @@ -19,9 +19,7 @@ "git_name": "Howard Enos", "git_email": "howard@azcomputerguru.com", "gitea_username": "howard", - "gitea_initial_password": "ACG-Tech2026!", - "gitea_must_change_password": true, - "notes": "Employee, Mike's brother. Full trust. Same access as Mike for MSP tracking and daily work. Has own Gitea account (howard) with admin access to all repos." + "notes": "Employee, Mike's brother. Full trust. Same access as Mike for MSP tracking and daily work. Has own Gitea account (howard) with admin access to all repos. Password rotated 2026-04-21 — stored in Howard's 1Password, not in this file." } }, "roles": { diff --git a/clients/cascades-tucson/reports/2026-04-21-spoofing-hunt.md b/clients/cascades-tucson/reports/2026-04-21-spoofing-hunt.md new file mode 100644 index 0000000..6bfc801 --- /dev/null +++ b/clients/cascades-tucson/reports/2026-04-21-spoofing-hunt.md @@ -0,0 +1,128 @@ +# Cascades Tucson — Spoofed Email Hunt + +**Date:** 2026-04-21 +**Tenant:** Cascades of Tucson (cascadestucson.com, `207fa277-e9d8-4eb7-ada1-1064d2221498`) +**Subject:** Tenant-wide email spoofing posture (inbound + domain authentication) +**Tool:** Remediation-tool skill (public-DNS only — see Gaps) +**Scope:** READ-ONLY +**Analyst:** Howard Enos (ACG-Tech03L) + +## Summary + +- **Public domain-auth posture is largely solid.** SPF is strict (`-all`), DKIM publishes both M365 selectors, DMARC is at `p=quarantine; pct=100`. +- **One real finding:** DMARC aggregate + forensic reports route to `info@cascadestucson.com` — an internal mailbox. No third-party DMARC aggregator is parsing failures. We have zero visibility into who is trying to spoof this domain. +- **Lookalike domain landscape is clean** for common variants (no A records on `cascadetuscon.com`, `cascadestuscon.com`, `cascadestucson.co/.net/.org`, `cascades-tucson.com`). Worth a deeper scan if concern warrants. +- **Inbound-side hunt is BLOCKED** — Cascades is only consented to the deprecated app (`fabb3421`), and the new tiered-app secrets are missing from Howard's local vault. Cannot run message trace, anti-phishing policy review, transport-rule audit, or quarantine review without one of: (a) syncing the new app secrets from Mike's vault, or (b) consenting Security Investigator in Cascades. +- **SPF includes one non-Microsoft IP** (`72.194.62.5`) — identified as `ix.azcomputerguru.com` (our own iXsystems host). Authorized, not a finding. + +## Target details + +| Field | Value | +|---|---| +| Domain | cascadestucson.com | +| Tenant ID | 207fa277-e9d8-4eb7-ada1-1064d2221498 | +| M365 base domain | NETORGFT4257522.onmicrosoft.com | +| MX | cascadestucson-com.mail.protection.outlook.com (M365 only) | +| App suite status | Old app only (`fabb3421`); tiered suite not consented | + +## Per-check findings + +### 1. SPF + +``` +v=spf1 ip4:72.194.62.5 include:spf.protection.outlook.com -all +``` + +- **Mechanism:** strict `-all` (hard fail) — correct posture. +- **Authorized senders:** M365 (`spf.protection.outlook.com`) + one explicit IP `72.194.62.5`. +- **72.194.62.5 identification:** rDNS `ix.azcomputerguru.com`, ARIN block `NETBLK-PH-CBS-72-194-48-0` (Cox Business). This is ACG's own ix-server — presumably used for on-prem scan-to-email or a mail relay for Cascades. Not a finding. +- **No third-party SPF includes** (no MailChimp, Constant Contact, HubSpot, etc.). Clean. + +### 2. DKIM + +- `selector1._domainkey.cascadestucson.com` -> `selector1-cascadestucson-com._domainkey.NETORGFT4257522.onmicrosoft.com` (M365 standard). +- `selector2._domainkey.cascadestucson.com` -> `selector2-cascadestucson-com._domainkey.NETORGFT4257522.onmicrosoft.com` (M365 standard). +- **Both DKIM selectors are published.** Can't confirm Exchange is actually signing without Exchange access (`Get-DkimSigningConfig` — blocked, see Gaps). Publish state is a prerequisite but not proof of enforcement. + +### 3. DMARC + +``` +v=DMARC1; p=quarantine; pct=100; rua=mailto:info@cascadestucson.com; ruf=mailto:info@cascadestucson.com; ri=86400; fo=1; +``` + +| Tag | Value | Assessment | +|---|---|---| +| `p` | quarantine | Acceptable — quarantines failures. `reject` is stronger but higher-risk to deploy without monitoring. | +| `pct` | 100 | Full enforcement — good. | +| `rua` | info@cascadestucson.com | **FINDING — aggregate reports go to an internal mailbox. No one is parsing them.** | +| `ruf` | info@cascadestucson.com | **FINDING — forensic reports (full failing messages) go to an internal mailbox. Privacy/noise risk + no analysis.** | +| `ri` | 86400 (24h) | Standard reporting interval. | +| `fo` | 1 | Forensic generated on ANY SPF/DKIM fail — aggressive, OK for investigation. | +| `sp` | (unset) | Subdomain policy inherits from `p` — acceptable. | +| `adkim`/`aspf` | (unset, relaxed default) | Acceptable. | + +**Subdomain DMARC:** no subdomain-specific record observed at `_dmarc.sub.cascadestucson.com`, so subdomain behavior falls back to the org policy — fine. + +### 4. Lookalike-domain quick scan + +No A records for any of these obvious variants: + +| Candidate | Status | +|---|---| +| cascadetuscon.com | no A record | +| cascadestuscon.com | no A record | +| cascadestucson.co | no A record | +| cascadestucson.net | no A record | +| cascadestucson.org | no A record | +| cascades-tucson.com | no A record | + +Not exhaustive — a proper lookalike hunt would also check registrations without A records (squatters parking domains), homoglyphs (Cyrillic "а", "ᴄ"), and newly-registered variants. Not done in this pass. + +### 5. Inbound spoofing attempts — BLOCKED (see Gaps) + +Needed but not collected (require Exchange Online access): + +- **Message trace** for last 7–30 days filtering on `SenderAddress` matching internal-spoofing patterns (same domain, but from external IP). +- **Anti-phishing policy review** — spoof intelligence enabled? Impersonation protection configured for executives (Meredith, etc.)? +- **Quarantine review** — currently-quarantined messages tagged as spoofing. +- **Transport rules** — any rule bypassing SCL/anti-phish for specific senders (a known attacker persistence technique). +- **Accepted domains** — verify no unauthorized domains added as internal. +- **Connection filter policy** — any IPs improperly on the Allow list. +- **Defender for O365 alerts** (if licensed) — MDO spoof detections. + +## Suspicious items (from public data) + +- **DMARC reports are a blind spot.** `rua=mailto:info@cascadestucson.com` means aggregate reports from every receiver on the internet are flowing into the same mailbox Cascades uses for external-facing communication — nobody is aggregating them. If someone is actively spoofing cascadestucson.com at scale, we'd have no idea unless a user happened to read those XML attachments. **High-leverage fix** — point `rua` (and optionally `ruf`) at a DMARC aggregator (dmarcian, EasyDMARC, Valimail — all have free tiers for small-volume domains). + +## Gaps — checks not completed + +**All inbound / Exchange-side checks are blocked by tooling state:** + +1. **Cascades is not onboarded to the new app suite.** Per `references/tenants.md` (row `cascadestucson.com`): "Old app only; IdentityRiskyUser not consented". Tiered Security Investigator never got consent in this tenant. +2. **Even if consented, Howard's vault is missing the new-suite client secrets.** Expected at `D:/vault/msp-tools/computerguru-security-investigator.sops.yaml` — file does not exist. These secrets live in Mike's vault (DESKTOP-0O8A1RL) and have not been committed/synced to the shared vault repo. +3. **The old app (`fabb3421`) IS consented in Cascades and its secret IS present** at `D:/vault/msp-tools/claude-msp-access-graph-api.sops.yaml`. However `get-token.sh` has no tier mapping for the old app (intentional — it's deprecated). Using it would require a one-off script. The remediation-tool design explicitly pushes toward migrating off it. + +**Recommended unblock (pick one):** + +- **Option A (preferred):** Mike commits/pushes new-suite SOPS files from his vault to the shared vault repo, then Howard pulls. Enables running this hunt on ANY tenant from Howard's box going forward. +- **Option B:** Consent Security Investigator in Cascades now (send Global Admin the consent URL below), then Option A is still needed to acquire a token on Howard's box. + +Security Investigator consent URL for Cascades: +``` +https://login.microsoftonline.com/207fa277-e9d8-4eb7-ada1-1064d2221498/adminconsent?client_id=bfbc12a4-f0dd-4e12-b06d-997e7271e10c&redirect_uri=https://azcomputerguru.com&prompt=consent +``` + +## Next actions + +1. **Decision on unblock path** — Howard to coordinate with Mike on vault sync (Option A above). Blocks full inbound hunt. +2. **DMARC reporting fix** — update `_dmarc.cascadestucson.com` TXT record to route `rua` (and `ruf`) at a DMARC aggregator. Pending client approval. Requires DNS access at cascadestucson.com registrar. Est. 15 min. +3. **Deeper lookalike-domain scan** — out of scope for this pass; consider running dnstwist or a registrar monitoring service if spoofing pressure is elevated. +4. **Once unblocked, re-run with:** message trace last 30d for `cascadestucson.com` spoofing indicators, anti-phishing policy inventory, transport rules, quarantine review, Defender alerts (if MDO licensed). + +## Remediation actions + +None taken. This pass was read-only / public-DNS only. + +## Data artifacts + +No raw JSON produced (tokens were not acquired). DNS lookups are reproducible from the commands in the Per-check findings section. diff --git a/session-logs/2026-04-21-howard-remediation-vault-gap.md b/session-logs/2026-04-21-howard-remediation-vault-gap.md new file mode 100644 index 0000000..73de031 --- /dev/null +++ b/session-logs/2026-04-21-howard-remediation-vault-gap.md @@ -0,0 +1,69 @@ +# 2026-04-21 — Howard: remediation-tool blocked on Cascades (vault gap) + +## User +- **User:** Howard Enos (howard) +- **Machine:** ACG-Tech03L +- **Role:** tech + +## TL;DR for Mike + +I tried to run the remediation-tool against Cascades (`cascadestucson.com`) to hunt for spoofed emails. **It's blocked on my box — not going to poke at it further, leaving it for you.** + +Two compounding issues: + +1. **Cascades is not consented to the new tiered app suite.** Per `references/tenants.md`, row `cascadestucson.com`: "Old app only; IdentityRiskyUser not consented". Outstanding since 2026-04-16. +2. **Your new-suite SOPS files are not in the shared vault.** `get-token.sh` expects `D:/vault/msp-tools/computerguru-security-investigator.sops.yaml` (and peers). On ACG-Tech03L, `D:/vault/msp-tools/` only has: + - `acg-msp-access-google-workspace.sops.yaml` + - `autotask.sops.yaml` + - `cipp.sops.yaml` + - `claude-msp-access-graph-api.sops.yaml` (the old deprecated app `fabb3421`) + - `screenconnect.sops.yaml` + - `syncro.sops.yaml` + + The five new-tier files (`computerguru-security-investigator|exchange-operator|user-manager|tenant-admin|defender-addon.sops.yaml`) are missing. + +## What the token script actually returned + +``` +$ bash C:/claudetools/.claude/skills/remediation-tool/scripts/get-token.sh cascadestucson.com investigator +ERROR: vault file not found: D:/vault/msp-tools/computerguru-security-investigator.sops.yaml + +$ bash C:/claudetools/.claude/skills/remediation-tool/scripts/get-token.sh cascadestucson.com investigator-exo +ERROR: vault file not found: D:/vault/msp-tools/computerguru-security-investigator.sops.yaml +``` + +(Same error for all tiers since the whole new-suite directory is absent.) + +## What I did manage to check (public DNS only) + +Full report at `clients/cascades-tucson/reports/2026-04-21-spoofing-hunt.md`. One real finding worth flagging even without Graph/EXO access: + +**DMARC reporting is a blind spot.** `_dmarc.cascadestucson.com` has: + +``` +rua=mailto:info@cascadestucson.com +ruf=mailto:info@cascadestucson.com +``` + +Aggregate + forensic DMARC reports flow into an internal mailbox nobody is parsing. If someone is actively spoofing their domain, we have zero visibility. Fix is one DNS change pointing `rua` at a DMARC aggregator (dmarcian / EasyDMARC / Valimair — free tiers cover their volume). + +Other public posture is fine: SPF strict `-all` with only `spf.protection.outlook.com` + our `ix.azcomputerguru.com` authorized, both M365 DKIM selectors published, no obvious lookalike domains registered (checked 6 common variants). + +## What I need from you + +Pick your preferred unblock: + +- **Option A (preferred — unblocks every tenant on my box):** Commit the five new-tier SOPS files from your vault to the shared vault repo and push. Then I pull and any future remediation-tool work from my machine just works. +- **Option B:** Consent Security Investigator in Cascades (URL in the report), but Option A is still needed for me to actually acquire a token. + +## What I did not touch (on purpose) + +- Did NOT modify `get-token.sh` to handle the old app — would've been a workaround that pushes against the stated migration direction. +- Did NOT attempt to use `claude-msp-access-graph-api.sops.yaml` (the old app) even though its secret is in my vault. +- Did NOT send any consent URL to Cascades. +- Did NOT change DNS for DMARC reporting — flagged as a separate action item in the report. + +## Artifacts + +- Report: `clients/cascades-tucson/reports/2026-04-21-spoofing-hunt.md` +- This log: `session-logs/2026-04-21-howard-remediation-vault-gap.md`