Dec. 1, 2025

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

  1. 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:

  1. 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.
  2. 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
  3. 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

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:

  1. Lock user consent: restrict or disable it, and remove offline_access from low-risk scopes.
  2. Enable Verified Publisher enforcement for all user-consent scenarios.
  3. Turn on and use Admin Consent Workflow—no more “one-click tenant skeleton keys.”
  4. Audit existing grants for offline_access + *.All scopes and revoke anything suspicious.
  5. 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

Transcript

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.