Your MFA Is Useless: The Entra ID Attack Nobody Audits
The podcast explains how attackers bypass MFA by abusing OAuth consent instead of stealing passwords. When a user or admin approves a malicious “productivity” app, it gets tokens with scopes like mail or files read and offline_access. That lets the attacker quietly read email, files and chats for months, even after password resets and new MFA devices. Normal identity events don’t revoke these grants; you must remove the OAuth grant or service principal itself. The host stresses three Entra controls: lock down user consent to low-risk scopes, only allow verified publishers, and route risky permissions through an admin consent workflow. Combined with rigorous logging, reviews and revocation, these steps eliminate most consent-based attacks in modern cloud identity environments today.
This episode is a drill for security leaders, identity admins, and anyone running Microsoft 365 / Entra (Azure AD). We walk through how attackers weaponize OAuth consent—not password theft—to gain persistent access to email, files, and directory data without triggering traditional MFA defenses. You’ll hear a full breakdown of:
- What illicit consent grants really are
- How refresh tokens and offline_access keep attackers in even after you reset passwords
- The three Entra controls that collapse most of this attack surface
- How to detect, prove, and remediate malicious OAuth grants in your tenant
If you think “we forced sign-out and reset passwords, so we’re safe,” this episode is your wake-up call. What You’ll Learn in This Episode
- What Illicit OAuth Consent Grants Actually Are
- Why this is authorization abuse, not credential theft
- How a “harmless” Microsoft consent screen turns into:
- Mail.Read / Mail.ReadWrite → inbox and attachment visibility
- Files.Read.All / Files.ReadWrite.All → SharePoint & OneDrive sweep
- Directory.ReadWrite.All → identity pivot and tenant tampering
- Why MFA doesn’t fire: the app acts with your delegated permissions, using tokens, not logins
- The critical role of offline_access as a persistence flag
2. Why MFA and Password Resets Don’t Save You
- How refresh tokens keep minting new access tokens long after you:
- Reset passwords
- Enforce MFA
- “Force sign-out” for a user
- Why OAuth consent lives in a different lane:
- User authentication events vs. app permission events
- Why revoking the grant beats resetting the password every time
- Delegated vs. application permissions:
- Delegated: act as the user
- Application: act as a service, often tenant-wide
3. The Three Non-Negotiable Entra Controls You Must Set You’ll get a clear checklist of Entra ID / Azure AD controls:
- Lock Down User Consent
- Disable user consent entirely or
- Allow only verified publishers and low-risk scopes
- Exclude: offline_access, Files..All, Mail.ReadWrite, Directory.
- Require Verified Publishers
- Only apps with Verified Publisher status can receive user consent
- Force attackers into admin consent lanes where visibility and scrutiny are higher
- Enable & Enforce Admin Consent Workflow
- Route risky scope requests (Mail.Read, Files.ReadWrite.All, Directory.ReadWrite.All, etc.)
into a structured approval process - Require justification, business owner, and expiry for approvals
- Use permission grant policies and least privilege as the default
- Route risky scope requests (Mail.Read, Files.ReadWrite.All, Directory.ReadWrite.All, etc.)
4. Case Study: Proving MFA & Resets Don’t Revoke Grants We walk through a clean, reproducible scenario:
- User approves a “Productivity Sync” app with Mail.Read + offline_access
- Attacker uses Microsoft Graph to read mail and pull attachments—quietly
- Blue team resets password, enforces MFA, forces sign-out
- App keeps working because the OAuth grant and refresh token still exist
- The only real fix: revoke the OAuth grant / service principal permissions
You’ll come away with a mental model of why your normal incident playbook fails against app-based attacks. 5. Detection: Logs, Queries, and What to Flag Immediately We cover the high-signal events and patterns you should be hunting:
- Key audit events:
- Add servicePrincipalOAuth2PermissionGrant
- Update application
- Add passwordCredential / Add keyCredential
- How to triage suspicious apps:
- Unknown service principals
- Unverified publishers
- High-risk scopes: offline_access, Mail., Files..All, Directory.*
- Inventory & queries (Graph / PowerShell) to map:
- Who granted what
- Which apps hold risky scopes
- Tenant-wide consents (consentType = AllPrincipals)
6. Remediation & Hardening: Purge, Review, Enforce, Repeat You’ll get a remediation playbook you can adapt:
- Immediate:
- Remove OAuth2PermissionGrants for malicious apps
- Remove or rotate app secrets and certificates
- Delete rogue service principals
- Assessment:
- Review mailbox, SharePoint, and directory impact based on granted scopes
- Hardening:
- Implement deny-by-default permission grant policies
- Build a scope catalog of: allowed, conditional, and blocked scopes
- Schedule recurring access reviews for apps and consents
- Dashboard: long-lived grants, risky scopes, and grants to privileged users
Who This Episode Is For
- CISOs & security leaders running Microsoft 365 / Entra ID
- Identity & access management teams
- SOC & detection engineers
- Cloud security / platform engineering teams
- Red teams & blue teams modeling OAuth abuse and MFA bypass
Key Terms Covered
- OAuth Consent / Illicit Consent Grants
- Refresh Tokens & offline_access
- Delegated vs. Application Permissions
- Admin Consent Workflow
- Verified Publisher
- Service Principal & OAuth2PermissionGrant
- Microsoft Graph–based exfiltration
Call to Action Next steps after listening:
- Lock user consent: restrict or disable it, and remove offline_access from low-risk scopes.
- Enable Verified Publisher enforcement for all user-consent scenarios.
- Turn on and use Admin Consent Workflow—no more “one-click tenant skeleton keys.”
- Audit existing grants for offline_access + *.All scopes and revoke anything suspicious.
- Subscribe for the follow-up episode on real Microsoft Graph queries and KQL detections to automate this hunt.
Become a supporter of this podcast: https://www.spreaker.com/podcast/m365-show-podcast--6704921/support.
Follow us on:
LInkedIn
Substack
1
00:00:00,000 --> 00:00:02,500
Recruit, you think MFA makes you bulletproof?
2
00:00:02,500 --> 00:00:03,340
Wrong.
3
00:00:03,340 --> 00:00:06,180
An attacker can read your mail, raid your files,
4
00:00:06,180 --> 00:00:09,260
and live in your tenant without ever touching your password.
5
00:00:09,260 --> 00:00:14,420
No prompts, no push fatigue, just quiet theft.
6
00:00:14,420 --> 00:00:17,220
The trick is OUTH consent.
7
00:00:17,220 --> 00:00:19,460
Apps you approve acting as you.
8
00:00:19,460 --> 00:00:20,460
Here's the deal.
9
00:00:20,460 --> 00:00:23,980
I'm going to show you how consent bypasses MFA,
10
00:00:23,980 --> 00:00:26,780
whitetocons outlive password resets,
11
00:00:26,780 --> 00:00:29,860
and the single control that kills 80% of this.
12
00:00:29,860 --> 00:00:34,660
Your lock user consent, require verified publishers,
13
00:00:34,660 --> 00:00:39,380
and push every risky request into an admin workflow.
14
00:00:39,380 --> 00:00:40,700
Move.
15
00:00:40,700 --> 00:00:44,340
We define the enemy, then erase it.
16
00:00:44,340 --> 00:00:47,420
What illicit consent grants actually are,
17
00:00:47,420 --> 00:00:49,220
and why MFA fails.
18
00:00:49,220 --> 00:00:50,700
All right, listen up.
19
00:00:50,700 --> 00:00:54,460
This is not credential theft, it's authorization abuse.
20
00:00:54,460 --> 00:00:58,300
Okay, so basically OUTH consent lets an application act
21
00:00:58,300 --> 00:01:00,100
on your behalf with scopes.
22
00:01:00,100 --> 00:01:04,380
You click "except" on a tidy Microsoft page and boom.
23
00:01:04,380 --> 00:01:07,060
The app gets tokens to your data.
24
00:01:07,060 --> 00:01:08,620
The attacker doesn't log in as you.
25
00:01:08,620 --> 00:01:11,060
They operate as an app you blessed.
26
00:01:11,060 --> 00:01:13,060
That's the ambush.
27
00:01:13,060 --> 00:01:15,100
Why MFA fails?
28
00:01:15,100 --> 00:01:16,260
Simple.
29
00:01:16,260 --> 00:01:18,700
MFA protects authentication.
30
00:01:18,700 --> 00:01:22,340
Consent grants create tokens after a one-time dance.
31
00:01:22,340 --> 00:01:25,100
Those tokens keep refreshing with refreshed tokens.
32
00:01:25,100 --> 00:01:26,700
You can reset the password,
33
00:01:26,700 --> 00:01:30,100
and force MFA doesn't matter the app never reprompts like a user.
34
00:01:30,100 --> 00:01:32,900
It just trades refreshed tokens for new access tokens
35
00:01:32,900 --> 00:01:34,500
until you revoke the grant.
36
00:01:34,500 --> 00:01:36,380
In other words, you lock the front door.
37
00:01:36,380 --> 00:01:39,780
You left assigned power of attorney in the mailbox.
38
00:01:39,780 --> 00:01:41,020
Here's the weird part.
39
00:01:41,020 --> 00:01:43,260
Device code flow makes it look legit.
40
00:01:43,260 --> 00:01:46,700
You see a Microsoft screen, enter a code,
41
00:01:46,700 --> 00:01:50,620
approve a helpful tool, and the consent lands.
42
00:01:50,620 --> 00:01:53,820
No shady form, no give me your password.
43
00:01:53,820 --> 00:01:55,900
Just a friendly scop list.
44
00:01:55,900 --> 00:01:59,500
If it includes offline access, that app gets persistence.
45
00:01:59,500 --> 00:02:04,620
If it includes mail, read or files, read.
46
00:02:04,620 --> 00:02:06,860
All you just gave the intruder a reading room
47
00:02:06,860 --> 00:02:10,540
in a library card, let's talk persistence.
48
00:02:10,540 --> 00:02:12,780
Refresh tokens extend sessions.
49
00:02:12,780 --> 00:02:15,620
Some apps ask for offline access specifically
50
00:02:15,620 --> 00:02:17,740
to survive long periods.
51
00:02:17,740 --> 00:02:22,100
If the app is granted delegated permissions, it acts as you.
52
00:02:22,100 --> 00:02:24,220
If an admin blesses application permissions,
53
00:02:24,220 --> 00:02:26,260
it acts as itself, no user context.
54
00:02:26,260 --> 00:02:27,740
That's a bigger blast radius.
55
00:02:27,740 --> 00:02:30,620
Admin consent to directory, read right all.
56
00:02:30,620 --> 00:02:32,420
You call that secure.
57
00:02:32,420 --> 00:02:34,300
That's tenant wide exposure.
58
00:02:34,300 --> 00:02:37,140
Mailbox rules, file x fill, graph queries,
59
00:02:37,140 --> 00:02:39,300
directory changes, the works.
60
00:02:39,300 --> 00:02:40,740
MicroStory.
61
00:02:40,740 --> 00:02:44,340
A user approves calendar helper asking for mail,
62
00:02:44,340 --> 00:02:46,860
read and offline access.
63
00:02:46,860 --> 00:02:49,020
Attacker never touches the user's password.
64
00:02:49,020 --> 00:02:51,860
They use Microsoft Graph with the apps token,
65
00:02:51,860 --> 00:02:56,780
read the inbox, pull attachments, and set a covert forwarding rule
66
00:02:56,780 --> 00:02:58,940
from their own infrastructure.
67
00:02:58,940 --> 00:03:03,140
Security forces a password reset and MFA registration.
68
00:03:03,140 --> 00:03:04,460
Nothing breaks.
69
00:03:04,460 --> 00:03:06,340
The app keeps pulling mail.
70
00:03:06,340 --> 00:03:06,820
Why?
71
00:03:06,820 --> 00:03:10,420
Because identity events aren't app permission events.
72
00:03:10,420 --> 00:03:13,020
Different lanes, different guards.
73
00:03:13,020 --> 00:03:15,140
Here's what most people miss.
74
00:03:15,140 --> 00:03:19,340
Delegated versus application permissions changes the stakes.
75
00:03:19,340 --> 00:03:22,140
Delegated is act as user.
76
00:03:22,140 --> 00:03:24,500
Application is act as service.
77
00:03:24,500 --> 00:03:27,020
Delegated can be limited to the user's data.
78
00:03:27,020 --> 00:03:30,020
Application, when granted to certain scopes,
79
00:03:30,020 --> 00:03:32,060
becomes tenant wide.
80
00:03:32,060 --> 00:03:35,780
If an admin hits a prove on an unverified app,
81
00:03:35,780 --> 00:03:38,180
asking for high-privileged scopes,
82
00:03:38,180 --> 00:03:40,220
you've issued a skeleton key.
83
00:03:40,220 --> 00:03:43,620
And yes, some attackers target admins or help desk staff
84
00:03:43,620 --> 00:03:46,300
with polished consent pages just for that one click.
85
00:03:46,300 --> 00:03:47,900
Think of it like badge access.
86
00:03:47,900 --> 00:03:50,300
MFA checks the person at the door.
87
00:03:50,300 --> 00:03:52,660
Consent grants create a vendor badge
88
00:03:52,660 --> 00:03:55,140
that opens rooms without escort.
89
00:03:55,140 --> 00:03:59,060
If the badge says all rooms, congratulations,
90
00:03:59,060 --> 00:04:02,140
your data center now has a self-guided tour.
91
00:04:02,140 --> 00:04:06,380
The simple version is authentication answers, who are you?
92
00:04:06,380 --> 00:04:09,300
Authorization answers, what can you do?
93
00:04:09,300 --> 00:04:11,380
This attack hijacks authorization.
94
00:04:11,380 --> 00:04:13,380
You keep arguing with the receptionist
95
00:04:13,380 --> 00:04:16,420
while the vendor loads the truck, specific damage,
96
00:04:16,420 --> 00:04:18,540
email red, send, files.
97
00:04:18,540 --> 00:04:24,060
Read, all to one drive and share point.
98
00:04:24,060 --> 00:04:27,980
Calendar scraping contacts harvest for next wave fishing,
99
00:04:27,980 --> 00:04:31,460
teams, message, impersonation with chat.
100
00:04:31,460 --> 00:04:33,140
Read right, directory.
101
00:04:33,140 --> 00:04:35,820
Read right, all for identity pivoting.
102
00:04:35,820 --> 00:04:38,260
With privileged scopes, they can write app roles
103
00:04:38,260 --> 00:04:40,660
at secrets and build back doors.
104
00:04:40,660 --> 00:04:42,940
MFA never fires because nobody's pretending
105
00:04:42,940 --> 00:04:44,700
to be a user logging in.
106
00:04:44,700 --> 00:04:47,260
And everything clicked when I realized resets don't revoke
107
00:04:47,260 --> 00:04:48,180
grants.
108
00:04:48,180 --> 00:04:51,540
You must revoke the OAuth consent at the service principal
109
00:04:51,540 --> 00:04:53,260
or grant object level.
110
00:04:53,260 --> 00:04:56,500
Until you remove the grant, the refresh token flow
111
00:04:56,500 --> 00:04:57,940
keeps working.
112
00:04:57,940 --> 00:05:01,500
That's why we forced sign out is theater.
113
00:05:01,500 --> 00:05:04,420
You didn't cut the cord, you just changed the Wi-Fi name.
114
00:05:04,420 --> 00:05:09,180
Now drop and give me three rules burned into your cortex.
115
00:05:09,180 --> 00:05:12,500
Consent is an access decision, not a login.
116
00:05:12,500 --> 00:05:16,780
Tocons outlive passwords unless you revoke the grant.
117
00:05:16,780 --> 00:05:19,700
Admin consent can detonate your whole tenant.
118
00:05:19,700 --> 00:05:21,940
Remember this detail, it's going to matter.
119
00:05:21,940 --> 00:05:24,860
Offline access is a persistence flag.
120
00:05:24,860 --> 00:05:28,260
When you see it next to mail, read, files,
121
00:05:28,260 --> 00:05:32,780
to read, write, all, or directory, scopes, treat it
122
00:05:32,780 --> 00:05:34,620
like a live grenade.
123
00:05:34,620 --> 00:05:36,820
In a minute, we clamp consent at the source,
124
00:05:36,820 --> 00:05:39,500
so the grenade never enters the building.
125
00:05:39,500 --> 00:05:41,460
Then we'll prove it with a case study
126
00:05:41,460 --> 00:05:45,180
and show you exactly where to hunt grants in logs.
127
00:05:45,180 --> 00:05:46,180
Move.
128
00:05:46,180 --> 00:05:50,380
The non-negotiables set these three-entra controls now.
129
00:05:50,380 --> 00:05:52,900
User consent, verified publishers.
130
00:05:52,900 --> 00:05:54,900
Admin consent workflow.
131
00:05:54,900 --> 00:05:56,620
All right, listen up.
132
00:05:56,620 --> 00:05:57,820
Controls win wars.
133
00:05:57,820 --> 00:06:01,340
You're going to set three-entra policies today, not tomorrow.
134
00:06:01,340 --> 00:06:03,740
Today, because every minute you wait,
135
00:06:03,740 --> 00:06:06,780
some productivity booster app is siphoning mail
136
00:06:06,780 --> 00:06:08,220
like a hungry raccoon.
137
00:06:08,220 --> 00:06:11,060
Rule number one, lock down user
138
00:06:11,060 --> 00:06:12,420
consent.
139
00:06:12,420 --> 00:06:15,380
You open this valve only for low-risk scopes
140
00:06:15,380 --> 00:06:17,980
or you shut it off entirely.
141
00:06:17,980 --> 00:06:21,460
In Entra Admin Center, go to enterprise applications,
142
00:06:21,460 --> 00:06:23,940
consent and permissions.
143
00:06:23,940 --> 00:06:26,620
User consent settings.
144
00:06:26,620 --> 00:06:30,980
Pick allow user consent for apps from verified publishers
145
00:06:30,980 --> 00:06:34,940
for selected permissions, or if your environment can handle it
146
00:06:34,940 --> 00:06:37,220
do not allow user consent.
147
00:06:37,220 --> 00:06:38,980
That's the gold standard.
148
00:06:38,980 --> 00:06:42,300
Why? Because consent is an access decision.
149
00:06:42,300 --> 00:06:45,060
You don't let random apps decide their own privileges.
150
00:06:45,060 --> 00:06:49,500
You define a safe list of low-impact scopes, user.
151
00:06:49,500 --> 00:06:53,100
Read open ID profile may be basic read of presence,
152
00:06:53,100 --> 00:06:54,020
and that's it.
153
00:06:54,020 --> 00:06:56,220
Everything else goes to the adults table.
154
00:06:56,220 --> 00:06:58,380
Here's what most people miss.
155
00:06:58,380 --> 00:07:02,380
Selected permissions is where you make or break this.
156
00:07:02,380 --> 00:07:05,820
Build a permission grant policy that includes low-risk scopes
157
00:07:05,820 --> 00:07:08,500
only exclude offline access.
158
00:07:08,500 --> 00:07:10,620
Exclude files.
159
00:07:10,620 --> 00:07:17,140
Read all mail read write directory.
160
00:07:17,140 --> 00:07:20,660
If an app needs persistent access or broad data read,
161
00:07:20,660 --> 00:07:22,220
it is not low-risk.
162
00:07:22,220 --> 00:07:24,740
Treat offline access like a smoke grenade
163
00:07:24,740 --> 00:07:26,780
banned for user consent.
164
00:07:26,780 --> 00:07:28,540
You want productivity?
165
00:07:28,540 --> 00:07:29,420
Fine.
166
00:07:29,420 --> 00:07:32,780
You still obey least privilege.
167
00:07:32,780 --> 00:07:36,500
Rule number two, require verified publishers.
168
00:07:36,500 --> 00:07:38,180
You call that app trustworthy?
169
00:07:38,180 --> 00:07:40,700
Where's the publisher verification badge?
170
00:07:40,700 --> 00:07:43,540
If it's unverified it doesn't get user consent.
171
00:07:43,540 --> 00:07:44,980
Period.
172
00:07:44,980 --> 00:07:47,820
Verified publishers have gone through Microsoft's process
173
00:07:47,820 --> 00:07:49,380
to prove ownership.
174
00:07:49,380 --> 00:07:50,380
Is it perfect?
175
00:07:50,380 --> 00:07:51,260
No.
176
00:07:51,260 --> 00:07:54,180
But it raises the bar and filters out a ton of junkware
177
00:07:54,180 --> 00:07:56,260
and throw away phishing apps.
178
00:07:56,260 --> 00:07:58,540
In Entra, enable the policy.
179
00:07:58,540 --> 00:08:01,540
Only apps with verified publisher status
180
00:08:01,540 --> 00:08:05,780
can receive user consent, and only for the low-risk scopes
181
00:08:05,780 --> 00:08:07,460
you approved.
182
00:08:07,460 --> 00:08:09,340
This forces attackers to either escalate
183
00:08:09,340 --> 00:08:11,380
to admin consent or fail at the door.
184
00:08:11,380 --> 00:08:13,220
Either way, you get visibility.
185
00:08:13,220 --> 00:08:15,420
Now drop and give me the big one.
186
00:08:15,420 --> 00:08:19,460
Rule number three, enable the admin consent workflow.
187
00:08:19,460 --> 00:08:22,180
This is your elevation lane with headlights, brakes,
188
00:08:22,180 --> 00:08:23,420
and a steering wheel.
189
00:08:23,420 --> 00:08:24,580
Turn it on.
190
00:08:24,580 --> 00:08:26,220
Set approvers.
191
00:08:26,220 --> 00:08:28,420
Require justification.
192
00:08:28,420 --> 00:08:30,300
Require business owner.
193
00:08:30,300 --> 00:08:32,980
Require expiration for approvals.
194
00:08:32,980 --> 00:08:37,300
When a user hits an app that needs risky scopes, mail.
195
00:08:37,300 --> 00:08:39,420
Read files.
196
00:08:39,420 --> 00:08:42,780
Read write all directory.
197
00:08:42,780 --> 00:08:48,180
Read write.
198
00:08:48,180 --> 00:08:51,460
All the workflow collects context and routes
199
00:08:51,460 --> 00:08:55,340
to the approvers with the app name, publisher status,
200
00:08:55,340 --> 00:08:58,540
requested scopes, and impact.
201
00:08:58,540 --> 00:09:01,940
This stops the one-click oops that hands over your tenant.
202
00:09:01,940 --> 00:09:03,460
You don't rubber stamp.
203
00:09:03,460 --> 00:09:07,060
You interrogate what scopes for whom?
204
00:09:07,060 --> 00:09:09,300
For how long and why?
205
00:09:09,300 --> 00:09:11,500
Secure by default update.
206
00:09:11,500 --> 00:09:13,340
Tighten your baselines.
207
00:09:13,340 --> 00:09:17,300
New tenants often lean towards stricter consent by default.
208
00:09:17,300 --> 00:09:18,740
But legacy tenants?
209
00:09:18,740 --> 00:09:20,340
Their loose, fix it.
210
00:09:20,340 --> 00:09:22,300
Create tiered policies.
211
00:09:22,300 --> 00:09:24,580
Tier, no user consent.
212
00:09:24,580 --> 00:09:28,660
Tier one, verified publishers, low-risk scopes only.
213
00:09:28,660 --> 00:09:31,100
Tier two, pre-approved enterprise apps
214
00:09:31,100 --> 00:09:34,500
with narrowly scoped permissions mapped to business units.
215
00:09:34,500 --> 00:09:36,220
Anything outside those lanes.
216
00:09:36,220 --> 00:09:39,340
Admin workflow, full review, maybe a POC
217
00:09:39,340 --> 00:09:41,860
in a sandbox before production.
218
00:09:41,860 --> 00:09:45,180
Custom permission grant policies let you encode this.
219
00:09:45,180 --> 00:09:47,180
Use them.
220
00:09:47,180 --> 00:09:49,260
Leased privilege patterns.
221
00:09:49,260 --> 00:09:51,300
Enforced.
222
00:09:51,300 --> 00:09:55,540
For every app you approve, slice scopes to the bone.
223
00:09:55,540 --> 00:09:58,780
If it only needs read of one mailbox, don't grant mail.
224
00:09:58,780 --> 00:10:00,060
Read for the org.
225
00:10:00,060 --> 00:10:04,140
If it needs SharePoint access, prefer site-specific permissions
226
00:10:04,140 --> 00:10:07,980
or delegated user-scoped reads over files.
227
00:10:07,980 --> 00:10:09,020
Read all.
228
00:10:09,020 --> 00:10:11,740
Deny risky scopes by policy.
229
00:10:11,740 --> 00:10:13,340
Maintain a block list.
230
00:10:13,340 --> 00:10:14,700
Offline access.
231
00:10:14,700 --> 00:10:16,020
Directory.
232
00:10:16,020 --> 00:10:17,020
Read right.
233
00:10:17,020 --> 00:10:17,620
All.
234
00:10:17,620 --> 00:10:18,140
Files.
235
00:10:18,140 --> 00:10:18,940
Read right.
236
00:10:18,940 --> 00:10:20,300
All mail.
237
00:10:20,300 --> 00:10:23,300
Send on behalf without governance and anything all
238
00:10:23,300 --> 00:10:27,340
unless there's a hard requirement and a compensating control.
239
00:10:27,340 --> 00:10:29,100
Saggregation of duties, not everyone
240
00:10:29,100 --> 00:10:31,460
gets to request or receive consent.
241
00:10:31,460 --> 00:10:34,940
Build security groups for requesters in sensitive areas.
242
00:10:34,940 --> 00:10:39,460
High-risk apps should be accessible only via access packages
243
00:10:39,460 --> 00:10:41,380
in title management.
244
00:10:41,380 --> 00:10:44,620
So people must request access, get approvals,
245
00:10:44,620 --> 00:10:47,940
and undergo periodic access reviews.
246
00:10:47,940 --> 00:10:50,660
Tie the app to the package, tie the package to the group,
247
00:10:50,660 --> 00:10:51,940
and review quarterly.
248
00:10:51,940 --> 00:10:55,620
When someone leaves the group, their delegated access evaporates.
249
00:10:55,620 --> 00:10:57,940
That's containment.
250
00:10:57,940 --> 00:10:59,980
Here's the counter-intuitive part.
251
00:10:59,980 --> 00:11:02,260
Controls without proof or theater.
252
00:11:02,260 --> 00:11:04,500
So wire evidence into the workflow.
253
00:11:04,500 --> 00:11:07,660
Require screenshots of the vendor's security page.
254
00:11:07,660 --> 00:11:10,220
Demand the list of exact graph scopes.
255
00:11:10,220 --> 00:11:12,860
Ask for data residency and retention.
256
00:11:12,860 --> 00:11:15,900
If they can't answer, the app doesn't enter.
257
00:11:15,900 --> 00:11:18,780
And keep a registry of approved apps
258
00:11:18,780 --> 00:11:24,380
with owner, scoplist, expiration, and review date.
259
00:11:24,380 --> 00:11:29,500
No owner, no approval, no end date, denied.
260
00:11:29,500 --> 00:11:32,060
Everything clicked when teams started rejecting
261
00:11:32,060 --> 00:11:34,700
helpful tools missing verified starters
262
00:11:34,700 --> 00:11:38,300
and offline access demands, requests dropped.
263
00:11:38,300 --> 00:11:40,220
Shadow, it bled out.
264
00:11:40,220 --> 00:11:44,500
Admin saw fewer fires because the kindling never crossed the gate.
265
00:11:44,500 --> 00:11:46,340
Set these three controls, and you
266
00:11:46,340 --> 00:11:49,660
collapse 80% of the attack surface.
267
00:11:49,660 --> 00:11:52,900
User consent locked, only verified publishers.
268
00:11:52,900 --> 00:11:56,060
Admin consent workflow on and enforced.
269
00:11:56,060 --> 00:11:57,460
You want zero trust?
270
00:11:57,460 --> 00:11:59,620
This is zero trust at the app layer.
271
00:11:59,620 --> 00:12:01,140
Not optional.
272
00:12:01,140 --> 00:12:02,380
Not someday.
273
00:12:02,380 --> 00:12:03,940
Now.
274
00:12:03,940 --> 00:12:08,780
Move, case study, proving MFA and password resets
275
00:12:08,780 --> 00:12:11,220
don't revoke OAuth grants.
276
00:12:11,220 --> 00:12:12,180
All right, listen up.
277
00:12:12,180 --> 00:12:13,700
We're going to prove it.
278
00:12:13,700 --> 00:12:16,340
Not theory, a clean controlled run
279
00:12:16,340 --> 00:12:19,900
that shows why your precious MFA and password resets
280
00:12:19,900 --> 00:12:22,540
don't touch OAuth grants.
281
00:12:22,540 --> 00:12:27,180
Set up one normal user, one shiny productivity sink
282
00:12:27,180 --> 00:12:32,740
app, requested scopes, mail, read and offline access.
283
00:12:32,740 --> 00:12:35,940
That's read mailbox plus persistence.
284
00:12:35,940 --> 00:12:38,940
User hits a legit Microsoft consent screen,
285
00:12:38,940 --> 00:12:43,780
sees the tidy scope list, clicks accept, mission starts, action.
286
00:12:43,780 --> 00:12:45,340
The attacker doesn't guess passwords.
287
00:12:45,340 --> 00:12:46,500
They don't spray logins.
288
00:12:46,500 --> 00:12:50,060
They use Microsoft graph with the apps tokens.
289
00:12:50,060 --> 00:12:56,260
First call, get me messages to read the inbox, quiet.
290
00:12:56,260 --> 00:12:58,220
No sign in prompt.
291
00:12:58,220 --> 00:13:00,380
No push notification.
292
00:13:00,380 --> 00:13:02,940
The app operates as the user.
293
00:13:02,940 --> 00:13:05,380
Because the user invited it, the attacker
294
00:13:05,380 --> 00:13:08,060
scripts it to pull attachments every 15 minutes
295
00:13:08,060 --> 00:13:09,860
and stash them off tenant.
296
00:13:09,860 --> 00:13:12,180
They add a mailbox rule via graph
297
00:13:12,180 --> 00:13:14,620
to flag certain vendors for quick X-Fill.
298
00:13:14,620 --> 00:13:15,900
Now the blue team wakes up.
299
00:13:15,900 --> 00:13:18,620
They force the user to reset their password.
300
00:13:18,620 --> 00:13:20,940
They enforce MFA with a new device.
301
00:13:20,940 --> 00:13:23,580
They brag, we cut off access.
302
00:13:23,580 --> 00:13:26,500
You call that a shutdown, watch this.
303
00:13:26,500 --> 00:13:30,540
Persistence, the malicious app already has a refresh token.
304
00:13:30,540 --> 00:13:33,900
The app trades refresh for new access tokens on schedule.
305
00:13:33,900 --> 00:13:37,220
No password required, no MFA required.
306
00:13:37,220 --> 00:13:38,860
Authentication is done.
307
00:13:38,860 --> 00:13:40,900
Authorization is in effect.
308
00:13:40,900 --> 00:13:43,140
The graph calls, keeps succeeding.
309
00:13:43,140 --> 00:13:44,860
The mailbox keeps streaming.
310
00:13:44,860 --> 00:13:47,340
The forwarding rule keeps working.
311
00:13:47,340 --> 00:13:49,780
The attacker's script never breaks stride.
312
00:13:49,780 --> 00:13:52,620
Hours later, days later, still pulling.
313
00:13:52,620 --> 00:13:55,060
Because nothing in a password reset
314
00:13:55,060 --> 00:13:57,380
revokes the grant object.
315
00:13:57,380 --> 00:13:58,700
Escalation path.
316
00:13:58,700 --> 00:14:01,260
If that consent had been approved by an admin
317
00:14:01,260 --> 00:14:04,380
with application permissions, say, mail.
318
00:14:04,380 --> 00:14:06,740
Read for the organization or directory.
319
00:14:06,740 --> 00:14:09,060
Read right dot all.
320
00:14:09,060 --> 00:14:13,460
The blast radius jumps from one mailbox to tenant-wide exposure.
321
00:14:13,460 --> 00:14:17,340
That means reading any mailbox in scope, harvesting
322
00:14:17,340 --> 00:14:19,460
share point via files.
323
00:14:19,460 --> 00:14:22,220
Read all, enumerating users, modifying
324
00:14:22,220 --> 00:14:25,020
directory attributes, even planting new secrets
325
00:14:25,020 --> 00:14:26,420
in existing apps.
326
00:14:26,420 --> 00:14:28,700
Admin consent acts like a master key.
327
00:14:28,700 --> 00:14:30,940
One click, massive surface.
328
00:14:30,940 --> 00:14:33,660
That's why we block unverified publishers
329
00:14:33,660 --> 00:14:36,820
and shove risky requests into the admin workflow.
330
00:14:36,820 --> 00:14:40,140
You stop this escalation before it starts.
331
00:14:40,140 --> 00:14:41,860
Remediation pivot.
332
00:14:41,860 --> 00:14:43,940
Here's the only lever that works.
333
00:14:43,940 --> 00:14:46,860
Revoke the app's permissions.
334
00:14:46,860 --> 00:14:49,580
Enterprise applications find the malicious service
335
00:14:49,580 --> 00:14:54,580
principle permissions remove grant, alternatively graph,
336
00:14:54,580 --> 00:14:57,100
delete the OAuth to permission.
337
00:14:57,100 --> 00:15:00,300
Grant tied to that service principle and user.
338
00:15:00,300 --> 00:15:04,340
Instantly, the refreshed token flow fails.
339
00:15:04,340 --> 00:15:06,740
Next token exchange denied.
340
00:15:06,740 --> 00:15:08,100
The stream stops.
341
00:15:08,100 --> 00:15:11,620
The mailbox rule is still there, but the app can't call graph.
342
00:15:11,620 --> 00:15:13,260
That's the control that matters.
343
00:15:13,260 --> 00:15:15,660
Not the password, not the MFA device.
344
00:15:15,660 --> 00:15:21,020
The grant, term, lesson, identity events
345
00:15:21,020 --> 00:15:23,380
aren't app permission events.
346
00:15:23,380 --> 00:15:27,740
Password resets, MFA re-registrations, and forced signouts
347
00:15:27,740 --> 00:15:30,220
are user authentication controls.
348
00:15:30,220 --> 00:15:33,340
OAuth consents its under application authorization,
349
00:15:33,340 --> 00:15:35,500
different objects, different life cycles,
350
00:15:35,500 --> 00:15:38,700
different kill switches govern OAuth grants separately,
351
00:15:38,700 --> 00:15:41,820
or you'll celebrate while the attacker quietly continues
352
00:15:41,820 --> 00:15:43,340
extraction.
353
00:15:43,340 --> 00:15:46,620
Micro-proof, before revocation, run a test.
354
00:15:46,620 --> 00:15:49,460
Call get me messages with the app's access token.
355
00:15:49,460 --> 00:15:51,580
200, OK.
356
00:15:51,580 --> 00:15:55,140
After revocation, try the same call.
357
00:15:55,140 --> 00:15:59,780
4-010403, token invalid or insufficient privileges.
358
00:15:59,780 --> 00:16:01,660
That's your red versus blue scoreboard.
359
00:16:01,660 --> 00:16:03,860
No debate, no, maybe.
360
00:16:03,860 --> 00:16:06,620
Either the grant exists or it doesn't.
361
00:16:06,620 --> 00:16:08,420
Here's what most people miss.
362
00:16:08,420 --> 00:16:11,340
Offline access is not nice to have.
363
00:16:11,340 --> 00:16:12,420
It's a time machine.
364
00:16:12,420 --> 00:16:15,020
It lets the app come back tomorrow without you.
365
00:16:15,020 --> 00:16:19,700
Parade with mail, read files, read write all, or directory.
366
00:16:19,700 --> 00:16:21,980
And you've built a bunker for the enemy.
367
00:16:21,980 --> 00:16:25,100
Your audit will show the login storm you expected never
368
00:16:25,100 --> 00:16:27,460
happened because there was no storm.
369
00:16:27,460 --> 00:16:31,020
Just steady API calls that looked like business as usual.
370
00:16:31,020 --> 00:16:33,180
Final take away from this drill.
371
00:16:33,180 --> 00:16:37,300
Revoke grants, or you are rehearsing failure.
372
00:16:37,300 --> 00:16:40,060
You don't negotiate with malicious service principles.
373
00:16:40,060 --> 00:16:41,060
You delete them.
374
00:16:41,060 --> 00:16:42,940
You invalidate their secrets.
375
00:16:42,940 --> 00:16:45,180
You cut the OAuth to permission grant
376
00:16:45,180 --> 00:16:48,140
and you verify with a failed graph call.
377
00:16:48,140 --> 00:16:52,060
Then and only then does the attacker lose access.
378
00:16:52,060 --> 00:16:55,780
Move, detection, logs, queries, and what to flag immediately.
379
00:16:55,780 --> 00:16:58,340
All right, listen up, find it fast.
380
00:16:58,340 --> 00:17:00,500
Then crush it faster.
381
00:17:00,500 --> 00:17:05,460
We hunt three trails, audit logs, sign-in context,
382
00:17:05,460 --> 00:17:10,140
and live inventory via graph/power shell.
383
00:17:10,140 --> 00:17:13,820
You flag risky scopes, unknown apps, and tenant-wide
384
00:17:13,820 --> 00:17:16,660
consents like their explosives.
385
00:17:16,660 --> 00:17:18,300
Audit targets first.
386
00:17:18,300 --> 00:17:20,180
You're looking for the birth of badness.
387
00:17:20,180 --> 00:17:23,500
Add service principle OAuth to permission grant.
388
00:17:23,500 --> 00:17:25,300
That's a new delegated grant.
389
00:17:25,300 --> 00:17:27,220
Treat it as a tripwire.
390
00:17:27,220 --> 00:17:29,500
Update application.
391
00:17:29,500 --> 00:17:32,980
Someone changed an app manifest or permissions.
392
00:17:32,980 --> 00:17:34,380
Could be back-doring.
393
00:17:34,380 --> 00:17:35,980
Add password credential.
394
00:17:35,980 --> 00:17:37,420
Add key credential.
395
00:17:37,420 --> 00:17:40,300
New client secret or cert added to a service principle
396
00:17:40,300 --> 00:17:42,540
persistence attempt.
397
00:17:42,540 --> 00:17:45,380
In Microsoft Defender or Entra Audit,
398
00:17:45,380 --> 00:17:48,580
filter on activity display name for those three.
399
00:17:48,580 --> 00:17:50,900
Then pivot on target resources to pull
400
00:17:50,900 --> 00:17:53,140
App-Bid Service Principle and the Actor.
401
00:17:53,140 --> 00:17:55,860
You see unfamiliar app names or random guide labels,
402
00:17:55,860 --> 00:17:56,940
Red Flag.
403
00:17:56,940 --> 00:17:59,100
You see grants created outside business hours
404
00:17:59,100 --> 00:18:01,740
or from odd IPs, Double Red.
405
00:18:01,740 --> 00:18:04,060
Now sign-in and consent anomalies.
406
00:18:04,060 --> 00:18:07,580
Even though the app uses tokens without your login,
407
00:18:07,580 --> 00:18:11,300
the initial consent often leaves a trail.
408
00:18:11,300 --> 00:18:14,740
Check new app IDs appearing in the tenant.
409
00:18:14,740 --> 00:18:17,900
Consent events tied to geographic outliers.
410
00:18:17,900 --> 00:18:21,620
User agents that scream automation not browsers.
411
00:18:21,620 --> 00:18:23,260
Here's what most people miss.
412
00:18:23,260 --> 00:18:26,540
The scope list tells you intent, suspicious scopes
413
00:18:26,540 --> 00:18:31,180
to flag immediately, offline access, persistence badge.
414
00:18:31,180 --> 00:18:33,860
If present with anything juicy, escalate.
415
00:18:33,860 --> 00:18:35,140
Mail.
416
00:18:35,140 --> 00:18:36,900
Read or mail.
417
00:18:36,900 --> 00:18:38,100
Read right.
418
00:18:38,100 --> 00:18:39,660
Inbox data.
419
00:18:39,660 --> 00:18:41,500
Attachment theft.
420
00:18:41,500 --> 00:18:42,420
Files.
421
00:18:42,420 --> 00:18:44,380
Read dot all or files.
422
00:18:44,380 --> 00:18:46,380
Read right dot all.
423
00:18:46,380 --> 00:18:48,940
SharePoint OneDrive sweep directory.
424
00:18:48,940 --> 00:18:50,140
Read right all.
425
00:18:50,140 --> 00:18:52,820
Identity pivot and tenant tampering.
426
00:18:52,820 --> 00:18:53,460
Chat.
427
00:18:53,460 --> 00:18:54,220
Read right.
428
00:18:54,220 --> 00:18:55,020
Channel message.
429
00:18:55,020 --> 00:18:56,220
Read all.
430
00:18:56,220 --> 00:18:58,540
Teams impersonation and data mining.
431
00:18:58,540 --> 00:19:00,420
You call that a low-risk scope?
432
00:19:00,420 --> 00:19:03,020
No, these are call the sergeants scopes.
433
00:19:03,020 --> 00:19:05,620
Create alert rules that trigger on new grants
434
00:19:05,620 --> 00:19:07,460
containing any of these, especially
435
00:19:07,460 --> 00:19:10,780
of granted tenant-wide or by admin portal time.
436
00:19:10,780 --> 00:19:12,260
Enterprise applications.
437
00:19:12,260 --> 00:19:13,100
Permissions.
438
00:19:13,100 --> 00:19:15,020
Sort by granted by.
439
00:19:15,020 --> 00:19:16,540
Unknown owner.
440
00:19:16,540 --> 00:19:18,660
That app gets a full frisk.
441
00:19:18,660 --> 00:19:20,980
Check admin consent requests.
442
00:19:20,980 --> 00:19:23,340
Any pending or recently approved items
443
00:19:23,340 --> 00:19:26,340
with risky scopes or unverified publishers.
444
00:19:26,340 --> 00:19:27,860
Review immediately.
445
00:19:27,860 --> 00:19:29,700
Build a risky app inventory.
446
00:19:29,700 --> 00:19:31,260
Unverified publisher.
447
00:19:31,260 --> 00:19:35,500
Last used over 30 days, but still holding high privilege scopes
448
00:19:35,500 --> 00:19:37,820
or apps granted to privileged users.
449
00:19:37,820 --> 00:19:40,940
Now drop and give me inventory discipline.
450
00:19:40,940 --> 00:19:44,460
Use graph or power shell to enumerate everything.
451
00:19:44,460 --> 00:19:48,180
With Microsoft Graph, list service principles.
452
00:19:48,180 --> 00:19:50,180
Get service principles.
453
00:19:50,180 --> 00:19:55,220
Select ID, app ID, display name, publisher name, verified,
454
00:19:55,220 --> 00:19:58,100
publisher, pull OAuth grants.
455
00:19:58,100 --> 00:20:00,340
Get OAuth 2 permission.
456
00:20:00,340 --> 00:20:05,100
Grants filter client ID EQ service principle id.
457
00:20:05,100 --> 00:20:08,380
For user level view, get users plasher eds.
458
00:20:08,380 --> 00:20:10,580
Joe OAuth permission grants.
459
00:20:10,580 --> 00:20:12,180
You want the scope field.
460
00:20:12,180 --> 00:20:13,420
Parsit.
461
00:20:13,420 --> 00:20:20,260
If it contains offline access, mail, files, all directory.
462
00:20:20,260 --> 00:20:21,380
Tag it.
463
00:20:21,380 --> 00:20:23,540
Also check consent type.
464
00:20:23,540 --> 00:20:27,660
All principles means admin tenant-wide consent.
465
00:20:27,660 --> 00:20:31,140
That's a siren with power shell, grab OAuth 2 permission
466
00:20:31,140 --> 00:20:33,980
grants and cross join with service principle data
467
00:20:33,980 --> 00:20:36,660
to map who granted what to whom.
468
00:20:36,660 --> 00:20:40,940
Then slice by high value accounts, admins, executives.
469
00:20:40,940 --> 00:20:42,820
Apps with no verified publisher.
470
00:20:42,820 --> 00:20:44,860
Grants created in the last seven days.
471
00:20:44,860 --> 00:20:47,380
Here's the counterintuitive part.
472
00:20:47,380 --> 00:20:50,580
Sometimes the only visible motion is an update application
473
00:20:50,580 --> 00:20:54,460
followed by an ad password credential on a legit enterprise app.
474
00:20:54,460 --> 00:20:56,980
That's app backdoring.
475
00:20:56,980 --> 00:21:00,220
Pull the apps required resource access
476
00:21:00,220 --> 00:21:03,460
and compare deltas over time.
477
00:21:03,460 --> 00:21:07,380
If risky scopes appeared recently treated like an intrusion,
478
00:21:07,380 --> 00:21:09,260
alerting rules.
479
00:21:09,260 --> 00:21:14,060
Build automation to fire on any new tenant-wide consent.
480
00:21:14,060 --> 00:21:15,740
Consent type.
481
00:21:15,740 --> 00:21:18,020
It's all principles.
482
00:21:18,020 --> 00:21:21,860
Fire on any new grant with offline access plus mail.
483
00:21:21,860 --> 00:21:24,180
Or files.
484
00:21:24,180 --> 00:21:25,780
All.
485
00:21:25,780 --> 00:21:29,100
Fire when a non-verified publisher receives any consent.
486
00:21:29,100 --> 00:21:29,940
Fire.
487
00:21:29,940 --> 00:21:31,060
When directory.
488
00:21:31,060 --> 00:21:32,580
Read right.
489
00:21:32,580 --> 00:21:34,980
All or app role assignment.
490
00:21:34,980 --> 00:21:36,740
Read right.
491
00:21:36,740 --> 00:21:38,940
All shows up anywhere.
492
00:21:38,940 --> 00:21:41,340
Fire when ad password.
493
00:21:41,340 --> 00:21:45,900
Credential occurs on an app you consider crown jewels.
494
00:21:45,900 --> 00:21:48,140
Tie alerts to enrichment.
495
00:21:48,140 --> 00:21:53,260
Include appy ID, display name, publisher, verified status,
496
00:21:53,260 --> 00:21:59,100
scopes, granted, buy, consent type, created daytime,
497
00:21:59,100 --> 00:22:01,540
and the granting IP location.
498
00:22:01,540 --> 00:22:04,220
If your alert doesn't tell responders exactly what
499
00:22:04,220 --> 00:22:08,540
was granted and buy whom, it slows the kill chain.
500
00:22:08,540 --> 00:22:09,820
Microcheck.
501
00:22:09,820 --> 00:22:13,420
Grab one suspicious app, test access.
502
00:22:13,420 --> 00:22:16,300
Use its token to call a harmless endpoint
503
00:22:16,300 --> 00:22:18,300
like Get Me.
504
00:22:18,300 --> 00:22:22,060
If it returns 200 for a user who never installed it,
505
00:22:22,060 --> 00:22:24,980
you've got delegated access mis-scoped.
506
00:22:24,980 --> 00:22:27,420
If an app claims application permissions,
507
00:22:27,420 --> 00:22:31,380
test an org-wide endpoint like Get Users, top one one
508
00:22:31,380 --> 00:22:32,900
with the app token.
509
00:22:32,900 --> 00:22:35,140
If that returns data, your tenant just
510
00:22:35,140 --> 00:22:36,340
handed it the keys.
511
00:22:36,340 --> 00:22:38,100
Portal views again.
512
00:22:38,100 --> 00:22:41,820
Enterprise applications, activity, sign-ins,
513
00:22:41,820 --> 00:22:44,860
you might see service-principled sign-in patterns.
514
00:22:44,860 --> 00:22:46,740
Volume spikes.
515
00:22:46,740 --> 00:22:50,940
Regular 15-minute calls aligned with X-Fill scripts.
516
00:22:50,940 --> 00:22:52,860
That's persistence rhythm.
517
00:22:52,860 --> 00:22:56,620
Combined with Azure AD audit to confirm when the grant started,
518
00:22:56,620 --> 00:22:58,140
the simple version is this.
519
00:22:58,140 --> 00:23:01,860
If you're not watching grants, you're not watching access.
520
00:23:01,860 --> 00:23:05,740
Build dashboards for new grants per day by scope risk,
521
00:23:05,740 --> 00:23:09,060
apps by verified status versus privilege.
522
00:23:09,060 --> 00:23:11,100
Grants to privileged users.
523
00:23:11,100 --> 00:23:15,060
Long-lived grants older than 90 days, remember this detail.
524
00:23:15,060 --> 00:23:18,780
Offline access next to all all is a grenade with the pin out.
525
00:23:18,780 --> 00:23:21,740
When your rules catch it, you don't negotiate.
526
00:23:21,740 --> 00:23:25,500
You escalate, investigate, and prepare to revoke.
527
00:23:25,500 --> 00:23:26,380
Move.
528
00:23:26,380 --> 00:23:28,140
Remediation and hardening.
529
00:23:28,140 --> 00:23:28,940
Perge.
530
00:23:28,940 --> 00:23:29,540
Review.
531
00:23:29,540 --> 00:23:30,420
Enforce.
532
00:23:30,420 --> 00:23:31,340
Repeat.
533
00:23:31,340 --> 00:23:32,060
All right.
534
00:23:32,060 --> 00:23:33,300
Listen up.
535
00:23:33,300 --> 00:23:34,020
We found it.
536
00:23:34,020 --> 00:23:35,020
Now we kill it.
537
00:23:35,020 --> 00:23:36,700
Then we weld the door shut.
538
00:23:36,700 --> 00:23:38,340
Immediate kill chain.
539
00:23:38,340 --> 00:23:39,420
Step one.
540
00:23:39,420 --> 00:23:41,140
Revoke the grants.
541
00:23:41,140 --> 00:23:42,700
Enterprise applications.
542
00:23:42,700 --> 00:23:45,100
Select the malicious service principle.
543
00:23:45,100 --> 00:23:46,020
Permissions.
544
00:23:46,020 --> 00:23:48,140
Remove every grant.
545
00:23:48,140 --> 00:23:49,580
Or Viagraph.
546
00:23:49,580 --> 00:23:54,100
Delete the OAuth2 permission grant objects tied to that app.
547
00:23:54,100 --> 00:23:55,620
Step two.
548
00:23:55,620 --> 00:23:59,100
Invalidate the absibility to authenticate.
549
00:23:59,100 --> 00:24:01,340
Remove secrets and certificates.
550
00:24:01,340 --> 00:24:04,260
Add password credential was the problem.
551
00:24:04,260 --> 00:24:06,460
Now you remove password credential.
552
00:24:06,460 --> 00:24:10,540
If the app is yours but backdoored, rotate secrets and certs.
553
00:24:10,540 --> 00:24:14,260
If it's rogue, delete the service principle outright.
554
00:24:14,260 --> 00:24:15,420
Step three.
555
00:24:15,420 --> 00:24:17,660
Block future calls.
556
00:24:17,660 --> 00:24:21,180
Conditional access policy that denies the app's client ID
557
00:24:21,180 --> 00:24:22,900
while you clean.
558
00:24:22,900 --> 00:24:24,300
Verify the takedown.
559
00:24:24,300 --> 00:24:26,140
Retest with the same token.
560
00:24:26,140 --> 00:24:28,620
Expect 401403.
561
00:24:28,620 --> 00:24:31,220
If you still get 200, you missed a grant
562
00:24:31,220 --> 00:24:33,180
or left an app role assignment.
563
00:24:33,180 --> 00:24:34,900
Keep cutting.
564
00:24:34,900 --> 00:24:36,500
Scope assessment.
565
00:24:36,500 --> 00:24:38,060
You report it.
566
00:24:38,060 --> 00:24:41,100
Pull mailbox audit and SharePoint file access
567
00:24:41,100 --> 00:24:43,740
around the grants created date time.
568
00:24:43,740 --> 00:24:47,340
Identify which users, sites, and teams were touched.
569
00:24:47,340 --> 00:24:50,060
Export the scop list from the grant and map
570
00:24:50,060 --> 00:24:51,580
to data domains.
571
00:24:51,580 --> 00:24:55,580
Mail, files, directory, teams.
572
00:24:55,580 --> 00:24:59,580
If directory was present, check for added app roles,
573
00:24:59,580 --> 00:25:02,220
new credentials on legit apps, and sudden group
574
00:25:02,220 --> 00:25:03,620
membership changes.
575
00:25:03,620 --> 00:25:06,500
Anything privileged gets a forensic sweep.
576
00:25:06,500 --> 00:25:10,140
Rotate secrets where applicable and purge inbox rules
577
00:25:10,140 --> 00:25:11,580
the app created.
578
00:25:11,580 --> 00:25:12,660
Policy hardening.
579
00:25:12,660 --> 00:25:13,980
You already know the drill.
580
00:25:13,980 --> 00:25:17,340
Lock user consent require verified publishers enforce
581
00:25:17,340 --> 00:25:19,700
admin consent workflow, but you're not done.
582
00:25:19,700 --> 00:25:23,140
Encoder denied by default, permission grant policy
583
00:25:23,140 --> 00:25:28,300
that blocks offline access, and all scopes from user consent.
584
00:25:28,300 --> 00:25:31,660
Tie the admin consent workflow to approver groups
585
00:25:31,660 --> 00:25:34,300
with no overlap to app owners.
586
00:25:34,300 --> 00:25:36,180
Require expiration on every approval
587
00:25:36,180 --> 00:25:39,260
if an app truly needs application permissions.
588
00:25:39,260 --> 00:25:42,180
Forces service account separate secret storage
589
00:25:42,180 --> 00:25:44,700
and compensating monitoring.
590
00:25:44,700 --> 00:25:48,860
Access reviews, quarterly, non-negotiable, enterprise
591
00:25:48,860 --> 00:25:52,820
applications, access reviews for app permissions,
592
00:25:52,820 --> 00:25:56,580
review apps by business unit owner and privileged tier.
593
00:25:56,580 --> 00:25:59,340
Any app with no listed owner is out.
594
00:25:59,340 --> 00:26:05,140
Any app unused for 60, 90 days gets cut or justified.
595
00:26:05,140 --> 00:26:10,100
Use entitlement management access packages for high-risk apps
596
00:26:10,100 --> 00:26:14,500
users request approvers approve and reviews prune
597
00:26:14,500 --> 00:26:17,380
when the package expires delegated access ends
598
00:26:17,380 --> 00:26:21,620
that's life cycle not hope, least privilege scope list,
599
00:26:21,620 --> 00:26:25,580
build and publish a pre-approved scope catalog.
600
00:26:25,580 --> 00:26:28,700
Allow for user consent with verified publishers,
601
00:26:28,700 --> 00:26:34,100
open ID, profile, email, user, read, offline access,
602
00:26:34,100 --> 00:26:38,300
excluded, conditionally allowed via admin workflow,
603
00:26:38,300 --> 00:26:43,540
mail, read, single user, files, read delegated per user,
604
00:26:43,540 --> 00:26:49,340
calendars, read, block listed, offline, slash access,
605
00:26:49,340 --> 00:26:56,060
paired with high-value scopes, files, readwrite.all, mail,
606
00:26:56,060 --> 00:27:01,620
readwrite across org directory, readwrite.all,
607
00:27:01,620 --> 00:27:05,100
app role assignment, readwrite,
608
00:27:05,100 --> 00:27:11,100
all, channel message, dot read, all chat, readwrite,
609
00:27:11,100 --> 00:27:14,300
tie this catalog to your grant policies and your review
610
00:27:14,300 --> 00:27:15,700
checklists.
611
00:27:15,700 --> 00:27:18,820
If a vendor requests outside catalog scopes,
612
00:27:18,820 --> 00:27:22,060
they bring a written justification and a reduced scope
613
00:27:22,060 --> 00:27:26,660
alternative, ongoing monitoring, automate detection rules,
614
00:27:26,660 --> 00:27:31,220
new tenant wide consent, new grants with risky scopes,
615
00:27:31,220 --> 00:27:35,140
non-verified publisher consent, add password credential
616
00:27:35,140 --> 00:27:39,420
on crown jewel apps, update application adding risky required
617
00:27:39,420 --> 00:27:43,940
resource access, send alerts with full enrichment,
618
00:27:43,940 --> 00:27:47,540
app ID, display name, publisher verification,
619
00:27:47,540 --> 00:27:52,780
scopes consent, type, granted, buy, IP location,
620
00:27:52,780 --> 00:27:55,860
dashboards track long-lived grants,
621
00:27:55,860 --> 00:28:00,740
grants to privileged users and risky scope velocity,
622
00:28:00,740 --> 00:28:05,300
drill weekly, yes weekly, you want boredom, not breaches.
623
00:28:05,300 --> 00:28:09,620
War game it, quarterly tabletop, plan to fake malicious app,
624
00:28:09,620 --> 00:28:12,780
see how fast the team detects, revokes, and verifies failure
625
00:28:12,780 --> 00:28:18,060
of graph calls, clock it, improve it, document owners,
626
00:28:18,060 --> 00:28:21,100
playbooks, and roll back paths.
627
00:28:21,100 --> 00:28:24,980
Zero trust means you practice until this is muscle memory,
628
00:28:24,980 --> 00:28:29,660
final orders, purge the grants, review the blast radius,
629
00:28:29,660 --> 00:28:34,660
enforce the policies, then repeat, you don't fix and forget,
630
00:28:34,660 --> 00:28:39,740
you fix, prove, and patrol, move, the one thing that stops this
631
00:28:39,740 --> 00:28:44,580
consent control, key takeaway, O-arth consent is a back door
632
00:28:44,580 --> 00:28:48,900
that ignores passwords in MFA, the only real defense is strict
633
00:28:48,900 --> 00:28:53,220
enforced consent control at the app layer, now lock user consent
634
00:28:53,220 --> 00:28:56,900
to low risk with verified publishers, enable the admin
635
00:28:56,900 --> 00:29:01,100
consent workflow, audit existing grants, and set alerts for risky
636
00:29:01,100 --> 00:29:02,620
scopes today.
637
00:29:02,620 --> 00:29:06,500
Subscribe and hit the next video on real graph queries to automate
638
00:29:06,500 --> 00:29:08,660
this hunt, move, recruit.