Forum Discussion
Dealing with high number of failed log on attempts from foreign countries utilizing Exchange Online
- Dec 21, 2018
Not sure if any one has seen this. There is a new tool for your basket. This has helped us greatly.
A couple of months ago Microsoft released to preview and then has pushed forward 'Authentication Policies'.
These authentication policies are processed prior to being passed to AAD or ADFS saving the failed login against the account
And yes this can be applied to individual or small groups to test first (just remember to wait to assure the policy is applied to the user in question before calling it good or not)
See "https://docs.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/disable-basic-authentication-in-exchange-online"
Basic outline
Assure you have modern authentication enabled for your organization
Create an authentication policy blocking basic auth for pop, imap and such (The biggest one we were seeing was imap)
If you have any user or service accounts that requires basic auth for any of the protocols you are disabling in the previous policy, create a second policy allowing the protocols
If you have any users that utilizing pop, imap or any other method you determine don't need basic authentication, get them migrated to some other form of client app or access
If there are any accounts that absolutely require basic auth (ie we have a ticketing system that utilizes imap with basic auth to connect to a specific mailbox), make note of them to exclude in your query for users to apply your restricted policy to
Query for and apply unrestricted policy to service account or user that requires the basic auth for the protocols disabled by the restricted policy
Query for and apply restricted policy to the majority of your users
Apply restricted policy as global default (for new users)
Either wait 24 hours for it to be applied or touch a user property on the user and wait approximately 30 minutes.
Note, the below worked for me. Make sure you research and adjust for your own needs. I take no responsibility for what you do to your environment. These are only examples
Exchange Powershell commands used
connect-exopssession -UserPrincipalName {exchangeonline admin}
New-AuthenticationPolicy -Name "Block_Basic_Auth_Selective”
{Blocks basic auth for imap, pop, smtp but allows for things like activesync}
(Adjust according to your needs)
Set-AuthenticationPolicy -Identity “Block_Basic_Auth_Selective” -AllowBasicAuthActiveSync -AllowBasicAuthAutodiscover -AllowBasicAuthImap:$false -AllowBasicAuthMapi -AllowBasicAuthOfflineAddressBook -AllowBasicAuthOutlookService:$false -AllowBasicAuthPop:$false -AllowBasicAuthReportingWebServices -AllowBasicAuthRest -AllowBasicAuthRpc -AllowBasicAuthSmtp:$false -AllowBasicAuthWebServices -AllowBasicAuthPowerShellNew-AuthenticationPolicy "Allow_Basic_Auth"
(Adjust according to your needs)
Set-AuthenticationPolicy -Identity “Allow_Basic_Auth” -AllowBasicAuthActiveSync:$true -AllowBasicAuthAutodiscover:$true -AllowBasicAuthImap:$true -AllowBasicAuthMapi:$true -AllowBasicAuthOfflineAddressBook:true -AllowBasicAuthOutlookService:$true -AllowBasicAuthPop:$true -AllowBasicAuthReportingWebServices -AllowBasicAuthRest -AllowBasicAuthRpc -AllowBasicAuthSmtp:$true -AllowBasicAuthWebServices:true -AllowBasicAuthPowerShellTo simplifiy things for my environment I manually set the users that required basic auth (I only had two)
set-user -Identity "User One" -AuthenticationPolicy "Allow_Basic_Auth"
To touch the user to make the policy get applied quicker
set-user -Identity "User One" -STSRefreshTokensValidFrom $([System.DateTime]::UtcNow)
For the rest of my users
$Users = Get-User -ResultSize unlimited | Where {$_.RecipientType -eq "UserMailbox" -and $_.AuthenticationPolicy -eq $null}
$users =$users.WindowsEmailAddress
$users | %{Set-User -Identity $_ -AuthenticationPolicy “Block_Basic_Auth_Selective”}
If you want to touch the users to apply policy quicker, since the query is already in memory
$users | %{Set-User -Identity $_ -STSRefreshTokensValidFrom $([System.DateTime]::UtcNow)}
Now the following command will apply the restricted policy as the global default. (Note, when I first implemented this, the unrestricted users did not have a policy applied and as such I thought they would have no policy applied, but once the default policy was applied to the global config, it affected the unrestricted unconfigured users.)Set-OrganizationConfig -DefaultAuthenticationPolicy “Block_Basic_Auth_Selective”
Remember, mileage will vary. Read everything you can find on Authentication Policy/iesFor us, for now, this has completely removed the issues we were having with illigitimate failed login attempts and account lockouts.
We ran into only the one issue mentioned above with the accounts that had no policy assigned and then the global policy being appliedRemember, it takes approximately 24 hours for the policy to be applied to a user unless one of the user's properties are modified
There is one thing I will mention, at this time, when this is applied, there is nothing logged for failed attempts that fall afoul of the blocked basic auth policy even in Azure Ad Sign-ins
-Gene
I know that this is a super old thread, but it's still on the front page of google when you're trying to figure out how to fix this issue, so I thought that I'd share what I've found after a ton of research and troubleshooting.
First off is Conditional Access policies, they require you to have an Azure AD Premium license, and they will not help with this. They only apply to modern authentication attempts, and this attack tends to leverage the old basic authentication method so that all the authentication attempts get tunnelled through the O365 servers before hitting your ADFS to prevent blocking them at the firewall. Additionally Conditional Access policies apply after the authentication attempt and lets you know if the password was correct or not, so the attacker finds out if they are successful and your accounts still get locked. If you can turn off basic authentication in your environment, then this will help prevent access to the apps, but it doesn't solve the root account lockout issue.
Next is extranet lockout, it can be useful, but as has been mentioned previously it's being bypassed for the most part by attackers by them using rate limiting. There's already some links to some good articles on here about it so that's all I'll say.
Then there is Custom Claims Rules on your ADFS servers. This looks promising, but outside of some guides for some very specific scenarios like locking down all authentication attempts external to your network, it was very hard to find documentation on how to do this or the claims language in general. I ended up leaving this option alone when I found Client Access Rules.
Client Access Rules, these are the best option that I've found so far. These are essentially O365 side firewall rules that apply on initial connection to O365 before the authentication is sent over to your ADFS server, and are based off of the external connecting IP of the attacker if you have an IP filter in place. They are only configurable via PowerShell at this time, and they are a fairly new feature, so they do have their limitations. For example some of the conditions don't work on all of the products yet, and certain condition and exception combinations you would expect to be able to use aren't available. The big issue I've run into with these is that there is no way to specify regions, only IPs and IP ranges, so I created a PowerShell script to automate grabbing the attacker's IPs from the ADFS logs and update the Blacklist Client Access Rule I have.
The script will parse your local ADFS logs, pick out the originating IPs for all the attacks, enumerate how many bad attempts you are getting per IP, then add any IPs that exceed a specified number of bad password attempts to a specified Client Access Rule to be blocked if it's not in the exclusion list in the script or the Client Access Rule. It also backs up the existing rule to XML before and after making changes, outputs a parsed version of the ADFS logs to CSV, records everything it's doing to a log file, and emails the log file to a specified email address if any errors occur in the script, or an IP gets added to the blacklist rule. Personally I have it setup to run every hour via a scheduled task on my ADFS server, and the number of attacks have dropped significantly since I implemented it. I keep meaning to make a blog to post this thing, but since I haven't gotten around to in in months I figure this would be a good place to share it.
You can find the script on GitHub here:
https://github.com/Khelbun/PowerShellHybridExchange/blob/master/BlacklistBruteForce.ps1
I've tried to explain how it all works in the code comments at the beginning and to put everything you would need to set in variables at the top of the script.
Here's the link to Microsoft's documentation on the Client Access Rules:
https://docs.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/client-access-rules/client-access-rules