Files
claudetools/clients/kittle/session-logs/2026-06/2026-06-08-mike-bec-incident-remediation.md
Mike Swanson 57e7251dbc sync: auto-sync from GURU-BEAST-ROG at 2026-06-08 16:23:44
Author: Mike Swanson
Machine: GURU-BEAST-ROG
Timestamp: 2026-06-08 16:23:44
2026-06-08 16:23:48 -07:00

17 KiB
Raw Permalink Blame History

Session Log — Kittle BEC Incident Remediation

User

  • User: Mike Swanson (mike)
  • Machine: GURU-BEAST-ROG
  • Role: admin

Session Summary

Full BEC (Business Email Compromise) investigation and remediation on kittlearizona.com tenant (ID: 3d073ebe-806a-4a5e-9035-3c7c4a264fc0). Triggered by Howard receiving a phishing email that appeared to originate from Ken@kittlearizona.com. Mike had already manually blocked Ken's sign-in and set a temp password by the time investigation began.

Investigation used the ComputerGuru MSP app suite (Security Investigator for Graph reads, Exchange Operator for EXO reads/writes, Tenant Admin for directory and policy actions). Initial consent was obtained via admin consent URLs at the start of the session; additional consent URLs were provided and accepted mid-session for remaining app permissions.

The attacker accessed Ken's account via OWA starting at 13:24 UTC using IP 64.44.131.168 (Chicago, Nexeon Technologies — a VPN/hosting provider). They harvested contacts via python-httpx/0.28.1 from Azure IP 40.126.41.96 during 18:3618:53 UTC, then sent 1,000 phishing emails in 5 batches from 45.134.224.220 (Kansas City, PacketHub S.A.) between 21:1421:26 UTC. The phishing subject was "Ken Schagel shared a file with you" — a fake OneDrive file-share lure. 747 delivered, 227 failed/bounced, 740 victim notifications dispatched via EWS SOAP from admin@kittlearizona.com.

Remediation actions completed: Ken's sessions revoked and admin roles stripped (all 10); Wrex sessions revoked and password reset; 5 malicious inbox rules deleted across 3 mailboxes (Ken x2, Alexis x1, Accounting x2 — Accounting rules were actively suppressing ALL incoming mail at time of discovery, immediately restoring mail flow); Alexis PERFECTDATA and Alignable OAuth grants revoked; Lori's 10 admin roles (including Global Administrator) stripped and re-assigned User Administrator only (confirmed via directoryAudits that Lori's GA was pre-existing, not attacker-planted); victim notification sent to 740 filtered addresses; Syncro ticket #32393 updated with public comment containing temp passwords; breach report written to clients/kittle/reports/2026-06-08-breach-check.md; SharePoint confirmed clean; Security Defaults confirmed enabled; Ken's MFA verified clean (single iPhone 12 Pro Max, no attacker-registered devices).


Key Decisions

  • EXO hidden rule sweep used Exchange Operator (not Security Investigator): Get-InboxRule -IncludeHidden:true requires Exchange.ManageAsApp permission, which only the Exchange Operator app holds. Security Investigator has full_access_as_app (EWS), not the Exchange admin cmdlets tier. Switched on first 401.

  • Phishing send via EWS SOAP (not Graph SendMail): 740-recipient victim notification sent using EWS SOAP from admin@kittlearizona.com. Graph SendMail would have required a delegated token or app-only send permission not available on this tenant. EWS worked with Exchange Operator EXO token. HTML body wrapped in <![CDATA[...]]> to prevent schema validation errors on <br> tags.

  • Lori's 10 admin roles stripped even though origin unknown: At time of stripping, it was unknown whether roles were attacker-planted or pre-existing. Decision to strip all and re-assign legitimate scope afterward. Confirmed post-session via directoryAudits that roles were pre-existing (no "Add member to role" events in last 30 days from any non-ACG initiator). Re-assigned User Administrator as legitimate scope.

  • Victim notification filtered 7 automated/non-human addresses: vzwpix, mms.att.net, Microsoft internal, streaming service addresses removed from the 747 delivered list before sending notifications. 740 addresses used.

  • Did not revoke Ken's MFA devices: Ken's MFA verified clean — single iPhone 12 Pro Max, no attacker-registered devices. Advised Ken to verify at mysignins.microsoft.com himself; no forced MFA reset needed.

  • Used Search-UnifiedAuditLog (EXO REST) instead of Graph signIns: Tenant is on O365 E3, which lacks Entra P1. Graph /auditLogs/signIns returns Authentication_RequestFromNonPremiumTenantOrB2CTenant 403. UAL via EXO REST is available without P1 and provided the full attack timeline.

  • Message trace used Get-MessageTraceV2: Get-MessageTrace deprecated September 2025. Switched to Get-MessageTraceV2 which returned full 1,000-record phishing campaign data.

  • PERFECTDATA OAuth revoked immediately, Alignable deferred then revoked: PERFECTDATA was clearly malicious (Mail.ReadWrite, Files.ReadWrite scopes, unknown publisher). Alignable was initially deferred pending Alexis's input — later revoked at Mike's direction (offline_access + Contacts.Read, unverified publisher).


Problems Encountered

  • EXO /adminapi/beta 401 with Security Investigator token: full_access_as_app is an EWS permission, not the Exchange admin cmdlets tier. Fixed by switching to Exchange Operator token which holds Exchange.ManageAsApp. HTTP 200 after switch.

  • Remove-InboxRule JSON escaping error (400 "unrecognized escape sequence \4"): The rule Identity string contains backslashes (e.g. Ken\4160878082195980289). Passing via shell variable without escaping caused malformed JSON. Fixed using jq -n --arg identity "$IDENTITY" to properly escape.

  • Remove-InboxRule "can't use Identity and Mailbox together": Identity already contains mailbox prefix, so separate Mailbox parameter caused conflict. Fixed by removing Mailbox parameter from the payload.

  • EWS SOAP body schema error on HTML: <br> tags in email body treated as XML elements, breaking SOAP schema validation. Fixed by wrapping body in <![CDATA[...]]>.

  • Sign-in logs 403 from all token tiers: Tenant Admin lacked AuditLog.Read.All in manifest. Security Investigator has AuditLog.Read.All in roles but tenant returns Authentication_RequestFromNonPremiumTenantOrB2CTenant. O365 E3 does not include Entra P1 — sign-in log API requires P1. No fix available. Worked around via Search-UnifiedAuditLog (EXO REST) which does not require P1.

  • Get-MessageTrace deprecated: Returned deprecation warning. Switched to Get-MessageTraceV2. Also removed PageSize parameter (invalid for V2).

  • directoryAudits ne operator not supported: activityDisplayName ne 'Remove member from role' returned UnknownError. Workaround: fetch all RoleManagement events and filter via jq client-side.

  • UAL search returned 0 results for Lori role events: EXO REST Search-UnifiedAuditLog with Operations:Add member to role returned empty for Lori. Resolved via Graph directoryAudits API (which did work with Security Investigator token after consent) — confirmed no role assignment events for Lori in 30 days, meaning roles were pre-existing.


Configuration Changes

  • Created: vault/clients/kittle/m365-ken-schagel-incident.sops.yaml — SOPS-encrypted vault entry for Ken's temp password and incident notes
  • Created: clients/kittle/reports/2026-06-08-breach-check.md — Full breach incident report (attack timeline, attacker IPs, all remediation actions, open items)
  • Created: clients/kittle/session-logs/2026-06/2026-06-08-mike-bec-incident-remediation.md — this file

Credentials & Secrets

Ken Schagel temp password: B/947405806521av

  • Vaulted at: vault/clients/kittle/m365-ken-schagel-incident.sops.yaml
  • Communicated to Mike via Syncro ticket #32393 (public comment with temp passwords for Ken + Wrex)
  • Ken's account re-enabled by Mike mid-session

Wrex password reset: Kittle@1426Wrx!47E742

  • Communicated via Syncro ticket #32393

Infrastructure & Servers

Item Value
Tenant kittlearizona.com
Tenant ID 3d073ebe-806a-4a5e-9035-3c7c4a264fc0
ACG MSP tenant ID ce61461e-81a0-4c84-bb4a-7b354a9a356d
Syncro ticket #32393
Attacker IP 1 64.44.131.168 — OWA browser access, Chicago IL, AS20278 Nexeon Technologies (VPN/hosting)
Attacker IP 2 40.126.41.96 — Contact scraping via python-httpx, Microsoft Azure
Attacker IP 3 45.134.224.220 — Bulk phishing send, Kansas City MO, AS147049 PacketHub S.A.
Attacker tool python-httpx/0.28.1, OAuth token for Microsoft Desktop app d3590ed6-52b3-4102-aeff-aad2292ab01c
Attacker AAD session 0031c64a-94a8-7629-20ad-c42db69d76c7
Compromise window 13:2421:41 UTC 2026-06-08

MSP App Credentials Used

App Client ID
Security Investigator bfbc12a4-f0dd-4e12-b06d-997e7271e10c
Exchange Operator b43e7342-5b4b-492f-890f-bb5a4f7f40e9
User Manager 64fac46b-8b44-41ad-93ee-7da03927576c
Tenant Admin 709e6eed-0711-4875-9c44-2d3518c47063

Commands & Outputs

Attack timeline (from UAL + message trace)

09:03 UTC  Normal Outlook sync (Microsoft IPs) — pre-compromise
13:24 UTC  [BREACH START] OWA login — 64.44.131.168 (Chicago, Nexeon VPN)
13:37 UTC  Ken's T-Mobile phone (legitimate, unaware)
15:00 UTC  Attacker returns — 64.44.131.168
15:17 UTC  Ken sends legitimate email via Cox (Phoenix AZ)
15:32 UTC  Attacker sends test email from OWA — concurrent with Ken
16:14 UTC  Attacker sends second test email
18:36 UTC  Contact harvest starts — python-httpx/0.28.1 from Azure 40.126.41.96
18:52 UTC  Attacker reviews Sent/Deleted/RSS Feeds from OWA
18:53 UTC  Contact harvest ends (250+ MailItemsAccessed events)
21:14 UTC  Phishing batch 1: 17 recipients
21:16 UTC  Phishing batch 2: 300 recipients
21:20 UTC  Phishing batch 3: 300 recipients
21:23 UTC  Phishing batch 4: 300 recipients
21:26 UTC  Phishing batch 5: 83 recipients — from 45.134.224.220 (PacketHub)
21:27 UTC  Ken's SSPR password reset attempt
~21:30 UTC Howard (ACG) receives phishing email — incident detected
21:41 UTC  Mike manually blocks Ken sign-in in portal, sets temp password
~22:00 UTC ACG investigation and remediation begins
22:05 UTC  ACG removes Lori's 10 admin roles (Tenant Admin app)
22:06 UTC  Lori sessions revoked

Malicious inbox rules deleted

Ken@kittlearizona.com     "."      Move ALL mail → RSS Feeds, MarkAsRead, StopProcessing  [DELETED]
Ken@kittlearizona.com     "Admin"  Move ALL mail → RSS Feeds, MarkAsRead, StopProcessing  [DELETED]
alexis@kittlearizona.com  "..."    Move ALL mail → RSS Feeds, MarkAsRead, StopProcessing  [DELETED]
Accounting@kittlearizona.com ".."  Move mail FROM Ken → RSS Feeds, Priority 1             [DELETED]
Accounting@kittlearizona.com "..." Move ALL mail → RSS Feeds, Priority 2                  [DELETED]

Note: Accounting ".." + "..." were actively suppressing ALL incoming mail at time of discovery.

Phishing campaign stats

Total sent:       1,000
Delivered:          747
Failed/bounced:     227
Pending:             25
Notifications sent: 740  (7 automated addresses filtered)
Subject:            "Ken Schagel shared a file with you"

OAuth grants revoked

PERFECTDATA app   Mail.ReadWrite, Files.ReadWrite, offline_access  [REVOKED]
Alignable app     offline_access, User.Read, Contacts.Read          [REVOKED]
  Grant ID: jB3LklISEEOHpW2kH5IbQLz8wKqAnj1KmLeBzb1HLJrh6qF03cBERamPOhj4CXha
  Client SP: 92cb1d8c-1252-4310-87a5-6da41f921b40

Lori role changes

Stripped (all pre-existing): Global Administrator, Exchange Administrator, User Administrator,
  Teams Administrator, SharePoint Administrator, Helpdesk Administrator, AI Administrator,
  Global Reader, Service Support Administrator, User Experience Success Manager
Re-assigned: User Administrator (roleTemplateId: fe930be7-5e62-47db-91af-98c3a49a38b1)
  Role object ID in tenant: 1321d5cd-17bb-40de-891b-1e85667e1c5a
  Lori user ID: 5817629b-5832-43c6-b74c-86a05c29c852

Key user IDs

Ken Schagel     Ken@kittlearizona.com       (admin roles stripped, re-enabled by Mike)
Lori Schagel    Lori@kittlearizona.com      ID: 5817629b-5832-43c6-b74c-86a05c29c852
Alexis          alexis@kittlearizona.com    ID: 74a1eae1-c0dd-4544-a98f-3a18f809785a
Wrex            Wrex@kittlearizona.com      (sessions revoked, password reset)

Pending / Incomplete Tasks

  1. Christina Micek inbox rule on KenStopProcessingRules:true, no action, no filter. Unknown if legitimate or attacker-planted. Needs Ken to confirm. Delete if he doesn't recognize it.

  2. Re-add admin roles to Ken — All 10 stripped during containment. Ken is Global Admin by function; re-add Global Administrator and Exchange Administrator once incident is declared closed and Ken's account is fully verified clean.

  3. Lori GA access review — Confirmed pre-existing (not attacker-planted). Recommend discussing with Ken whether Lori legitimately needs any admin role at all. Downscoped to User Administrator for now.

  4. MFA cleanup — Alexis has duplicate Authenticator registrations ("iPhone 12 Pro Max" x2). Lori has two Authenticator devices (SM-G975U + SM-F766U, likely old phone not removed). Users can self-serve at mysignins.microsoft.com or ACG can reset.

  5. Phishing URL unknown — Email body purged when Ken's account was disabled. Send IP 45.134.224.220 (PacketHub S.A., AS147049) is known. Submit to threat intel if needed.

  6. Entra P1 licensing — Sign-in logs blind without it. Tenant on O365 E3, not M365 E3. Recommend Entra P1 add-on or upgrade. Without P1, a Conditional Access policy for foreign IP blocking also cannot be enforced.

  7. DKIM/DMARC — Not configured on kittlearizona.com. DMARC reject/quarantine would reduce future phishing deliverability from this domain.

  8. Alexis MFA duplicate — One "iPhone 12 Pro Max" Authenticator entry is likely a stale registration. Should be cleaned up but is low priority now that PERFECTDATA and Alignable are revoked.


Reference Information

  • Syncro ticket: #32393 (public comment added with temp passwords for Ken + Wrex)
  • Breach report: clients/kittle/reports/2026-06-08-breach-check.md
  • Vault entry: vault/clients/kittle/m365-ken-schagel-incident.sops.yaml
  • Victim notification: sent from admin@kittlearizona.com via EWS SOAP, 3 batches, 740 recipients
  • Attacker OAuth app (Microsoft Desktop): d3590ed6-52b3-4102-aeff-aad2292ab01c
  • Attacker AAD session: 0031c64a-94a8-7629-20ad-c42db69d76c7
  • Security Defaults: enabled (isEnabled: true) on this tenant
  • SharePoint: clean — no attacker-created files, pages, or external sharing links
  • EXO REST endpoint: https://outlook.office365.com/adminapi/beta/{tenantId}/InvokeCommand
  • EWS endpoint: https://outlook.office365.com/EWS/Exchange.asmx
  • Graph directoryAudits: confirmed working with Security Investigator token (no P1 needed for this endpoint)
  • Graph signIns: blocked — requires Entra P1 (Authentication_RequestFromNonPremiumTenantOrB2CTenant)

Update: 16:23 PT — Post-save follow-up actions

Additional actions completed after initial save

Alignable OAuth on Alexis — revoked: At Mike's direction, revoked the Alignable OAuth grant on alexis@kittlearizona.com.

  • Grant ID: jB3LklISEEOHpW2kH5IbQLz8wKqAnj1KmLeBzb1HLJrh6qF03cBERamPOhj4CXha
  • App SP client ID: 92cb1d8c-1252-4310-87a5-6da41f921b40
  • Scopes: offline_access User.Read Contacts.Read
  • HTTP 204 [OK]

Lori Schagel — downscoped to User Administrator: All 10 pre-existing admin roles had been stripped during containment. Re-assigned User Administrator only (confirmed pre-existing GA was unnecessary exposure, not attacker-planted).

  • Lori user ID: 5817629b-5832-43c6-b74c-86a05c29c852
  • User Administrator role object ID: 1321d5cd-17bb-40de-891b-1e85667e1c5a
  • roleTemplateId: fe930be7-5e62-47db-91af-98c3a49a38b1
  • HTTP 204 [OK]

Lori role assignment timing — confirmed pre-existing: directoryAudits query (last 30 days, all RoleManagement events) returned only ACG-initiated removals. Zero "Add member to role" events from any other initiator in the 30-day window. Lori's GA was assigned more than 30 days before the incident — pre-existing, not attacker-planted. Breach report updated to reflect this finding.

Victim notification confirmed sent: Mike asked explicitly — confirmed 740 emails sent via EWS SOAP from admin@kittlearizona.com in 3 batches. All NoError. 747 delivered by phishing campaign; 7 automated addresses filtered (vzwpix, att.net MMS, Microsoft internal, streaming service) before notification send.

All consent links accepted by Mike — confirmed all 5 MSP apps (Security Investigator, Exchange Operator, User Manager, Tenant Admin, Defender Add-on) have admin consent in Kittle tenant.

Thread deletion failed: Bot received HTTP 403 Missing Permissions attempting to delete Discord thread 1513652236444504197. Thread remains open.

Breach report updates

clients/kittle/reports/2026-06-08-breach-check.md updated with:

  • Lori role assignment confirmed pre-existing (not attacker-planted)
  • Alignable OAuth revocation added to remediation table
  • Lori User Administrator re-assignment added to remediation table
  • Open items updated to reflect resolved items (Ken MFA clean, Lori role timing resolved)
  • New open item: Lori GA access review (recommend discussing with Ken whether she needs any admin role)