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.

Apple Podcasts podcast player iconSpotify podcast player iconYoutube Music podcast player iconSpreaker podcast player iconPodchaser podcast player iconAmazon Music podcast player icon

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.