-
-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathFind-SmtpAuthExposure.ps1
More file actions
239 lines (182 loc) · 8.24 KB
/
Copy pathFind-SmtpAuthExposure.ps1
File metadata and controls
239 lines (182 loc) · 8.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
<#PSScriptInfo
.VERSION 1.0.1
.GUID 699c5654-5dd9-4914-b032-fb8744cdb6ec
.AUTHOR msgwing.com
.COMPANYNAME msgwing.com
.COPYRIGHT MIT
.TAGS SMTP SMTPAUTH SmtpClientAuthentication BasicAuthentication ExchangeOnline Microsoft365 Office365 Audit ReadOnly Deprecation Relay Printer MFP Scanner 5.7.139
.LICENSEURI https://github.com/msgwing/ZeroSMTP/blob/main/LICENSE
.PROJECTURI https://github.com/msgwing/ZeroSMTP
.RELEASENOTES
Initial release. Reports which Exchange Online mailboxes can still authenticate
with SMTP AUTH before Microsoft disables Basic authentication for it by default
at the end of December 2026. Read-only.
Handles all three states of SmtpClientAuthenticationDisabled, including $null
which inherits the tenant setting - the state that the commonly repeated
`-eq $false` filter misses entirely.
#>
#Requires -Version 5.1
<#
.SYNOPSIS
Reports which Exchange Online mailboxes can still authenticate with SMTP
AUTH, and will therefore stop sending when Microsoft disables Basic auth
for SMTP AUTH at the end of December 2026.
.DESCRIPTION
Answers one question before December 2026: which mailboxes in this tenant
can still send with a username and password, and will therefore stop when
Microsoft disables SMTP AUTH Basic authentication by default at the end of
that month. Printers, scanners, MFPs, NAS units and scripts are what break,
and the error they will report is 535 5.7.139.
Read-only. The script queries configuration and prints a report; it never
changes a setting, so it is safe to run against production before you have
decided anything.
The reason a script is needed rather than one Get-CASMailbox call is that
SmtpClientAuthenticationDisabled is tri-state, and the middle state is the
one that catches people out:
$true SMTP AUTH explicitly blocked for this mailbox
$false SMTP AUTH explicitly allowed for this mailbox
$null inherit the tenant-wide setting
A mailbox showing $null looks harmless in a spreadsheet and is in fact
fully exposed whenever the tenant allows SMTP AUTH. Filtering only on
`-eq $false`, which is the usual advice, silently misses every one of them.
.PARAMETER CsvPath
Also write the per-mailbox results to this path, for handing to whoever
owns the devices.
.PARAMETER SkipConnect
Use an Exchange Online session you have already established instead of
calling Connect-ExchangeOnline.
.EXAMPLE
.\Find-SmtpAuthExposure.ps1
.EXAMPLE
.\Find-SmtpAuthExposure.ps1 -CsvPath .\smtp-auth-exposure.csv
.NOTES
Needs the ExchangeOnlineManagement module:
Install-Module ExchangeOnlineManagement -Scope CurrentUser
Configuration is only half the picture. A mailbox that is allowed to use
SMTP AUTH but has no device pointed at it does not matter, and a device
nobody remembers configuring does. For actual recent usage, open the
Exchange admin center: Reports -> Mail flow -> SMTP AUTH client submission
report. That report is the fastest way to find the forgotten device.
Part of https://github.com/msgwing/ZeroSMTP
#>
[CmdletBinding()]
param(
[string] $CsvPath,
[switch] $SkipConnect
)
$ErrorActionPreference = 'Stop'
function Write-Section {
param([string] $Text)
Write-Host ''
Write-Host $Text -ForegroundColor Cyan
Write-Host ('-' * $Text.Length) -ForegroundColor DarkGray
}
# --- connect ---------------------------------------------------------------
if (-not (Get-Command Get-CASMailbox -ErrorAction SilentlyContinue)) {
if (-not (Get-Module -ListAvailable -Name ExchangeOnlineManagement)) {
throw 'The ExchangeOnlineManagement module is not installed. Run: Install-Module ExchangeOnlineManagement -Scope CurrentUser'
}
Import-Module ExchangeOnlineManagement -ErrorAction Stop
}
if (-not $SkipConnect) {
Write-Host 'Connecting to Exchange Online...' -ForegroundColor DarkGray
Connect-ExchangeOnline -ShowBanner:$false
}
# --- tenant-wide setting ---------------------------------------------------
Write-Section 'Tenant-wide SMTP AUTH'
$transport = Get-TransportConfig
$tenantBlocks = [bool] $transport.SmtpClientAuthenticationDisabled
if ($tenantBlocks) {
Write-Host ' SMTP AUTH is DISABLED tenant-wide.' -ForegroundColor Green
Write-Host ' Only mailboxes with an explicit per-mailbox override can still use it.'
} else {
Write-Host ' SMTP AUTH is ALLOWED tenant-wide.' -ForegroundColor Yellow
Write-Host ' Every mailbox inherits that unless it opts out explicitly.'
}
# --- per-mailbox ------------------------------------------------------------
Write-Section 'Per-mailbox configuration'
Write-Host ' Reading mailboxes (this takes a while on a large tenant)...' -ForegroundColor DarkGray
$mailboxes = Get-CASMailbox -ResultSize Unlimited
$results = foreach ($mailbox in $mailboxes) {
$setting = $mailbox.SmtpClientAuthenticationDisabled
# Tri-state, resolved to the answer the admin actually wants: can this
# mailbox authenticate over SMTP AUTH today, and why.
if ($null -eq $setting) {
$state = 'Inherits tenant'
$exposed = -not $tenantBlocks
} elseif ($setting) {
$state = 'Explicitly blocked'
$exposed = $false
} else {
$state = 'Explicitly allowed'
$exposed = $true
}
[pscustomobject] @{
DisplayName = $mailbox.DisplayName
Address = $mailbox.PrimarySmtpAddress
Setting = $state
BreaksInDec = $exposed
}
}
$exposedList = @($results | Where-Object BreaksInDec)
$explicit = @($exposedList | Where-Object Setting -eq 'Explicitly allowed')
$inherited = @($exposedList | Where-Object Setting -eq 'Inherits tenant')
Write-Host (' {0} mailboxes checked' -f $results.Count)
Write-Host (' {0} can still use SMTP AUTH' -f $exposedList.Count) -ForegroundColor (
if ($exposedList.Count) { 'Yellow' } else { 'Green' })
if ($explicit.Count) {
Write-Host (' {0} explicitly allowed (someone set this deliberately)' -f $explicit.Count)
}
if ($inherited.Count) {
Write-Host (' {0} inheriting the tenant setting - easy to miss' -f $inherited.Count)
}
if ($exposedList.Count) {
Write-Host ''
$exposedList |
Sort-Object Setting, Address |
Format-Table DisplayName, Address, Setting -AutoSize |
Out-String |
Write-Host
}
# --- authentication policies ------------------------------------------------
Write-Section 'Authentication policies'
$policies = @(Get-AuthenticationPolicy -ErrorAction SilentlyContinue)
if (-not $policies.Count) {
Write-Host ' None defined.'
} else {
foreach ($policy in $policies) {
# AllowBasicAuthSmtp is the property that matters here; a policy can
# block SMTP AUTH for its assigned users regardless of the settings
# above.
$allows = $policy.AllowBasicAuthSmtp
Write-Host (' {0}: AllowBasicAuthSmtp = {1}' -f $policy.Name, $allows)
}
}
# --- output -----------------------------------------------------------------
if ($CsvPath) {
$results | Sort-Object -Property @{ Expression = 'BreaksInDec'; Descending = $true }, Address |
Export-Csv -Path $CsvPath -NoTypeInformation -Encoding UTF8
Write-Host ''
Write-Host (' Full results written to {0}' -f $CsvPath) -ForegroundColor Cyan
}
Write-Section 'What to do with this'
if ($exposedList.Count) {
Write-Host @'
Each exposed mailbox is only a problem if something is actually sending
through it. Check the SMTP AUTH client submission report in the Exchange
admin center (Reports -> Mail flow) to see which ones have authenticated
recently, then for each device or application decide:
- firmware or software update that adds OAuth 2.0, if the vendor shipped one
- Direct Send, for internal-only recipients
- an SMTP relay that still accepts a username and password
Vendor advisories, including models where the vendor has stated no OAuth
firmware is planned:
https://github.com/msgwing/ZeroSMTP/blob/main/docs/AFFECTED-SYSTEMS.md
'@
} else {
Write-Host ' Nothing found that will break. Worth re-running before December.'
}
Write-Host ''
# Exit code carries the finding, so the script is usable from a scheduled task
# or a pipeline: 0 means nothing exposed, 1 means something needs attention.
if ($exposedList.Count) { exit 1 } else { exit 0 }