- Rewrote get-token.sh: tiered app system (investigator/exchange-op/user-manager/tenant-admin/defender) - Updated SKILL.md, command, gotchas, checklist, graph-endpoints for new app suite - Cascades breach check: mailbox clean, inbound phishing received by John, DMARC gap noted Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5.0 KiB
5.0 KiB
Breach-Check Rubric
How to interpret the outputs from user-breach-check.sh and tenant-sweep.sh.
Single-user check — the 10 points
| # | Check | What "clean" looks like | Red flags |
|---|---|---|---|
| 1 | Inbox rules (Graph) | Empty, or only benign filters | ForwardTo / RedirectTo / ForwardAsAttachmentTo set; DeleteMessage+MarkAsRead combos; rules filtered on "password", "bank", "invoice", "CEO name", "security"; rules with name like "." or " " (attacker hiding) |
| 2 | Mailbox settings / auto-reply | Auto-reply disabled or legitimate | Auto-reply active with external audience + unfamiliar message body |
| 3 | Exchange REST (hidden rules, delegates, SendAs, Get-Mailbox forwarding fields) | Only SELF in permissions; no forwarding | Hidden inbox rule moving to RSS/Notes/Conversation History; non-SELF FullAccess/SendAs; ForwardingAddress or ForwardingSmtpAddress set to external |
| 4 | OAuth consents + app role assignments | Legitimate apps only (Teams, Outlook mobile, BlueMail, etc.); dates match user history | New consent in attack window; unknown app with Mail.ReadWrite, Files.ReadWrite, offline_access; publisher not verified |
| 5 | Auth methods | All methods predate the attack window | New phone/Authenticator registered within hours of first suspicious sign-in; duplicate entries with the same device name but different createdDateTime |
| 6 | Sign-ins 30d | Consistent US IPs, user's known geography | Any successful sign-in from a country the user never visits; IMAP/POP/Authenticated SMTP client apps (legacy auth); sign-ins from TOR exit nodes or known residential-proxy ranges |
| 7 | Directory audits | Only legit admin/system actions | Update user by non-admin principal; password reset the user didn't initiate; auth method change from Microsoft Substrate Management is normal but repeated changes are not |
| 8 | Risky users / risk detections | riskLevel: none |
Any medium or high; riskDetail: userPerformedSecuredPasswordChange just means resolved — check the original detection |
| 9 | Sent items (recent 25) | Normal business correspondence | Blast emails to random external recipients; forwards of internal financial/HR info externally; anything after-hours from an unusual client app |
| 10 | Deleted items (recent 25) | Marketing/spam, routine notifications | Deleted security alerts, password-reset emails, MFA notifications, bounce notices the user wouldn't delete — all signs of attacker cleanup |
Cross-check rule
If inbox rules and forwarding are clean but sign-ins show successful foreign access — attacker may have used OAuth-based access (check OAuth grants) or already extracted data and cleaned up. Pull sent items + deleted items aggressively and check /auditLogs/signIns/beta for non-interactive sign-ins.
Tenant-wide sweep — priorities
| Priority | Signal | Action |
|---|---|---|
| P1 | User with ≥20 failed sign-ins from ≥2 foreign countries | Likely active credential-stuffing target. Reset password, disable SMTP AUTH, monitor. |
| P1 | Successful sign-in from non-US | Verify with user immediately. If not them: force password reset + revoke sessions + full breach check. |
| P2 | New OAuth consent to unfamiliar app in attack window | Review app publisher, scopes, and requesting user. Revoke if unknown. |
| P2 | B2B guest invite to personal email domain (gmail.com, outlook.com, yahoo.com) | Confirm with inviter it's intentional. Guest invites are a known persistence mechanism. |
| P3 | Transport rule created/modified by a non-admin | Transport rules can redirect mail tenant-wide. Review body/actions carefully. |
| P3 | Service principal added by non-admin or by "PowerApps Service" unexpectedly | Usually benign, but worth noting. |
| P4 | Isolated wrong-password attempt from foreign IP | Record and move on. Single attempts are noise unless repeated. |
False positives to filter out
sysadmin@<tenant>failures during onboarding (error 65001 against any ComputerGuru app — Security Investigator, Exchange Operator, User Manager, Tenant Admin, or Defender Add-on).Microsoft Substrate ManagementandAzure MFA StrongAuthenticationServiceroutinely update user records — those are not attacker activity.- Our own consent attempts show up as
Consent to applicationin directory audits. Filtersysadmin+ target matching any "ComputerGuru" app display name during the onboarding window. error 50140"Keep me signed in interrupt" is a browser prompt, not a failed auth.
When to escalate beyond this tool
- Data exfiltration suspected -> pull Unified Audit Log via Purview (this tool does not access UAL).
- Tenant-wide phishing campaign -> enable Purview Content Search, quarantine messages.
- Domain-joined workstation compromise -> GuruRMM + Bitdefender workflow (see
clients/ace-portables/reports/for past example). - Attacker still active and exfiltrating -> consider disabling the user via the
remediatesubcommand and rotating the mailbox password at the same time.