How to Turn On ADFS Security Auditing with Powershell

Providing the best user experience with a Single-Sign-On  (SSO) capability without compromising security is key of successful implementations of federation services. I personally like the ADFS model and SAML (Security Assertion Markup Language) because is robust, effective and suitable from small to large organizations offering an incredible amount of features if it configured/implemented correctly.

What Does ADFS really do?

Active Directory Federation Services (AD FS) provides simplified, secured identity federation and Web single sign-on (SSO) capabilities for end users who want to access applications within an AD FS-secured enterprise, in federation partner organizations, or in the cloud.

What are the default settings that we can leverage for troubleshooting or security?

Security and Operations Teams frequently work on the same issues but on a different angle and most of the times they agree on some default values and to change others.  Configure AD FS Extranet Soft Lockout Protection
is one of these and to achieve this result we need to delve into the ADFS and AD configuration and policies.

When your authentication requests come through the WAP (Web Application Proxy), by default ADFS will NOT stop trying to authenticate any attempt legitimate or malicious. In short, there is no limit.

Let me clarify why this is so important, but to look at the full picture we need to start to have a look to Active Directory where every Authentication Request against the domain get logged and update the AD User attributes if the login is successful or not.

In AD, every username has a default (and possibly a fine-grained) policy applied that after a certain number of unsuccessful authentication attempts will lead to a lockout event.

PS U:\> Get-ADDefaultDomainPasswordPolicy


ComplexityEnabled           : True
DistinguishedName           : DC=CONTOSO,DC=COM
LockoutDuration             : 00:15:00
LockoutObservationWindow    : 00:15:00
LockoutThreshold            : 10
MaxPasswordAge              : 90.00:00:00
MinPasswordAge              : 00:00:00
MinPasswordLength           : 8
objectClass                 : {domainDNS}
objectGuid                  : 48591777-8edf-4334-9e98-0838eefcb45e
PasswordHistoryCount        : 15
ReversibleEncryptionEnabled : False

Check also if there is a specific FineGrained Policy applied:

Get-ADFineGrainedPasswordPolicy -filter *

Last week article was on this topic (Powershell: Monitoring AD Account Lock-Out Events).

Lockout Events are an effective protection against brute force attacks and monitor them can be crucial to identify risks and troubleshoot authentication issues.

ADFS is authenticating against AD a username and password on behalf of a trusted external application, but without leaving any trace of that attempt in AD.  In other words, by default is not locking out your account will be triggered by ADFS to let the AD account block. This is not completely a bad thing, otherwise will expose AD to a big DDOS risk, but the fact that there is no audit for successful or failed requests will be basically potentially exposed to brute-force attacks.

So what can we do to mitigate that risk and be more aware of what is going on on ADFS?

The answer is turning on Security Auditing and enable AD FS Extranet Soft Lockout Protection.

Let’s first check our ADFS settings

Let’s start with checking if ADFS is installed (repeat these steps for all ADFS servers)

#Check if ADFS is installed
Get-WindowsFeature adfs-federation

Display Name                                            Name                       Install State
------------                                            ----                       -------------
[X] Active Directory Federation Services                ADFS-Federation                Installed

And for your information let’s list all the available cmd-lets for this powershell module:

 get-command -module adfs

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Cmdlet          Add-AdfsAttributeStore                             adfs
Cmdlet          Add-AdfsCertificate                                adfs
Cmdlet          Add-AdfsClaimDescription                           adfs
Cmdlet          Add-AdfsClaimsProviderTrust                        adfs
Cmdlet          Add-AdfsClient                                     adfs
Cmdlet          Add-AdfsDeviceRegistrationUpnSuffix                adfs
Cmdlet          Add-AdfsFarmNode                                   adfs
Cmdlet          Add-AdfsNonClaimsAwareRelyingPartyTrust            adfs
Cmdlet          Add-AdfsRelyingPartyTrust                          adfs
Cmdlet          Add-AdfsWebApplicationProxyRelyingPartyTrust       adfs
Cmdlet          Disable-AdfsClaimsProviderTrust                    adfs
Cmdlet          Disable-AdfsClient                                 adfs
Cmdlet          Disable-AdfsDeviceRegistration                     adfs
Cmdlet          Disable-AdfsEndpoint                               adfs
Cmdlet          Disable-AdfsNonClaimsAwareRelyingPartyTrust        adfs
Cmdlet          Disable-AdfsRelyingPartyTrust                      adfs
Cmdlet          Disable-AdfsWebApplicationProxyRelyingPartyTrust   adfs
Cmdlet          Enable-AdfsClaimsProviderTrust                     adfs
Cmdlet          Enable-AdfsClient                                  adfs
Cmdlet          Enable-AdfsDeviceRegistration                      adfs
Cmdlet          Enable-AdfsEndpoint                                adfs
Cmdlet          Enable-AdfsNonClaimsAwareRelyingPartyTrust         adfs
Cmdlet          Enable-AdfsRelyingPartyTrust                       adfs
Cmdlet          Enable-AdfsWebApplicationProxyRelyingPartyTrust    adfs
Cmdlet          Export-AdfsAuthenticationProviderConfigurationData adfs
Cmdlet          Export-AdfsDeploymentSQLScript                     adfs
Cmdlet          Export-AdfsWebContent                              adfs
Cmdlet          Export-AdfsWebTheme                                adfs
Cmdlet          Get-AdfsAdditionalAuthenticationRule               adfs
Cmdlet          Get-AdfsAttributeStore                             adfs
Cmdlet          Get-AdfsAuthenticationProvider                     adfs
Cmdlet          Get-AdfsAuthenticationProviderWebContent           adfs
Cmdlet          Get-AdfsCertificate                                adfs
Cmdlet          Get-AdfsClaimDescription                           adfs
Cmdlet          Get-AdfsClaimsProviderTrust                        adfs
Cmdlet          Get-AdfsClient                                     adfs
Cmdlet          Get-AdfsDeviceRegistration                         adfs
Cmdlet          Get-AdfsDeviceRegistrationUpnSuffix                adfs
Cmdlet          Get-AdfsEndpoint                                   adfs
Cmdlet          Get-AdfsGlobalAuthenticationPolicy                 adfs
Cmdlet          Get-AdfsGlobalWebContent                           adfs
Cmdlet          Get-AdfsNonClaimsAwareRelyingPartyTrust            adfs
Cmdlet          Get-AdfsProperties                                 adfs
Cmdlet          Get-AdfsRegistrationHosts                          adfs
Cmdlet          Get-AdfsRelyingPartyTrust                          adfs
Cmdlet          Get-AdfsRelyingPartyWebContent                     adfs
Cmdlet          Get-AdfsSslCertificate                             adfs
Cmdlet          Get-AdfsSyncProperties                             adfs
Cmdlet          Get-AdfsWebApplicationProxyRelyingPartyTrust       adfs
Cmdlet          Get-AdfsWebConfig                                  adfs
Cmdlet          Get-AdfsWebTheme                                   adfs
Cmdlet          Import-AdfsAuthenticationProviderConfigurationData adfs
Cmdlet          Import-AdfsWebContent                              adfs
Cmdlet          Initialize-ADDeviceRegistration                    adfs
Cmdlet          Install-AdfsFarm                                   adfs
Cmdlet          New-AdfsClaimRuleSet                               adfs
Cmdlet          New-AdfsContactPerson                              adfs
Cmdlet          New-AdfsOrganization                               adfs
Cmdlet          New-AdfsSamlEndpoint                               adfs
Cmdlet          New-AdfsWebTheme                                   adfs
Cmdlet          Publish-SslCertificate                             adfs
Cmdlet          Register-AdfsAuthenticationProvider                adfs
Cmdlet          Remove-AdfsAttributeStore                          adfs
Cmdlet          Remove-AdfsAuthenticationProviderWebContent        adfs
Cmdlet          Remove-AdfsCertificate                             adfs
Cmdlet          Remove-AdfsClaimDescription                        adfs
Cmdlet          Remove-AdfsClaimsProviderTrust                     adfs
Cmdlet          Remove-AdfsClient                                  adfs
Cmdlet          Remove-AdfsDeviceRegistrationUpnSuffix             adfs
Cmdlet          Remove-AdfsFarmNode                                adfs
Cmdlet          Remove-AdfsGlobalWebContent                        adfs
Cmdlet          Remove-AdfsNonClaimsAwareRelyingPartyTrust         adfs
Cmdlet          Remove-AdfsRelyingPartyTrust                       adfs
Cmdlet          Remove-AdfsRelyingPartyWebContent                  adfs
Cmdlet          Remove-AdfsWebApplicationProxyRelyingPartyTrust    adfs
Cmdlet          Remove-AdfsWebTheme                                adfs
Cmdlet          Revoke-AdfsProxyTrust                              adfs
Cmdlet          Set-AdfsAdditionalAuthenticationRule               adfs
Cmdlet          Set-AdfsAttributeStore                             adfs
Cmdlet          Set-AdfsAuthenticationProviderWebContent           adfs
Cmdlet          Set-AdfsCertificate                                adfs
Cmdlet          Set-AdfsCertSharingContainer                       adfs
Cmdlet          Set-AdfsClaimDescription                           adfs
Cmdlet          Set-AdfsClaimsProviderTrust                        adfs
Cmdlet          Set-AdfsClient                                     adfs
Cmdlet          Set-AdfsDeviceRegistration                         adfs
Cmdlet          Set-AdfsDeviceRegistrationUpnSuffix                adfs
Cmdlet          Set-AdfsEndpoint                                   adfs
Cmdlet          Set-AdfsGlobalAuthenticationPolicy                 adfs
Cmdlet          Set-AdfsGlobalWebContent                           adfs
Cmdlet          Set-AdfsNonClaimsAwareRelyingPartyTrust            adfs
Cmdlet          Set-AdfsProperties                                 adfs
Cmdlet          Set-AdfsRegistrationHosts                          adfs
Cmdlet          Set-AdfsRelyingPartyTrust                          adfs
Cmdlet          Set-AdfsRelyingPartyWebContent                     adfs
Cmdlet          Set-AdfsSslCertificate                             adfs
Cmdlet          Set-AdfsSyncProperties                             adfs
Cmdlet          Set-AdfsWebApplicationProxyRelyingPartyTrust       adfs
Cmdlet          Set-AdfsWebConfig                                  adfs
Cmdlet          Set-AdfsWebTheme                                   adfs
Cmdlet          Test-AdfsFarmInstallation                          adfs
Cmdlet          Test-AdfsFarmJoin                                  adfs
Cmdlet          Unregister-AdfsAuthenticationProvider              adfs
Cmdlet          Update-AdfsCertificate                             adfs
Cmdlet          Update-AdfsClaimsProviderTrust                     adfs
Cmdlet          Update-AdfsRelyingPartyTrust                       adfs

Let’s focus of checking if the extranet lockout is enabled or not if Get-ADFSProperties:

Get-AdfsProperties | select ExtranetLockOutThreshold, ExtranetLockoutEnabled,ExtranetObservationWindow |Fl

ExtranetLockoutThreshold : 2147483647
ExtranetLockoutEnabled : False
ExtranetObservationWindow : 00:30:00

#Or with this more elegant cmd-let 

Get-AdfsProperties | fl *extranet*

ExtranetLockoutThreshold : 2147483647
ExtranetLockoutEnabled : False
ExtranetObservationWindow : 00:30:00

Checking the ADFS log level:

Get-AdfsProperties | fl *log*


LogLevel : {Errors, Information, Verbose, Warnings}

No Failure or Success Audits are turned on by default, so I need to change it  to :

Set-ADFSProperties –LogLevel Information,Errors,Verbose,Warnings,FailureAudits,SuccessAudits

Turn On Loggin with Group Policy:

auditpol.exe /set /subcategory:"Application Generated" /failure:enable /success:enable

Let’s turn on the Extranet Lockout

Set-AdfsProperties -EnableExtranetLockout $true -ExtranetLockoutThreshold 8 -ExtranetObservationWindow (new-timespan -Minutes 15)

Note that is recommended that ADFS Lockout Threshold is smaller than the AD Lockout event.

AD FS extranet lockout functions independently from the AD lockout policies. However, we strongly recommend that you set the ExtranetLockoutThreshold parameter value to a value that is less than the AD account lockout threshold. Failing to do so would result in AD FS being unable to protect accounts from being locked out in Active Directory.

When AD FS Extranet lockout on Server 2012 R2 is enabled all authentication requests through the WAP are validated by AD FS on the PDC. When the PDC is unavailable, users will be unable to authenticate from the extranet.

There is also a new addition for Server 2016 where you can allow AFDS to fallback to another DC if a Primary Domain Controller (PDC) is not available. This Parameter is called ExtranetLockoutRequirePDC  and the Type is Boolean.

Checking the Security Events from the Event Log of ADFS

Get-EventLog -LogName Security -computername "adfs.contoso.com" -source "AD FS Auditing" -newest 10}

#if You have more than one ADFS
"adfs01.contoso.com","adfs02.contoso.com","adfs03.contoso.com" |%{Get-EventLog -LogName Security -computername $_ -source "AD FS Auditing" -newest 10}

This is a summary from microsoft doc:

Key points to remember
------------------------------
The Extranet Lockout feature only works for the extranet scenario where the authentication requests come through the Web Application Proxy
The Extranet Lockout feature only applies to username & password authentication
AD FS does not keep any track of badPwdCount or users that are soft-locked out. AD FS uses AD for all state tracking
AD FS performs a lookup for the badPwdCount attribute through LDAP call for the user on the PDC for every authentication attempt
AD FS older than 2016 will fail if it cannot access the PDC. AD FS 2016 introduced improvements that will allow AD FS to fall back to other domain controllers in case of the PDC is not available.
AD FS will allow authentication requests from extranet if badPwdCount < ExtranetLockoutThreshold
If badPwdCount >= ExtranetLockoutThreshold AND badPasswordTime + ExtranetObservationWindow < Current time, AD FS will reject authentication requests from extranet
To avoid malicious account lockout, you should make sure ExtranetLockoutThreshold < Account Lockout Threshold AND ExtranetObservationWindow > Reset Account Lockout Counter

Troubleshooting

Once the security auditing is turned on ADFS and on the Local Security Policy the troubleshooting options available to engineers and sysadmin are a lot more. This article offers some good idea on how to troubleshoot ADFS Authentication issues.

More about ADFS

Since the introduction of Active Directory Federation Services, authorization policies have been available to restrict or allow users access to resources based on attributes of the request and the resource. As AD FS has moved from version to version, how these policies are implemented has changed.

(2016) ADFS and Banned IP address (and subnets)

On Windows Server 2016 (since June ADFS 2018 update)

This update enables you to configure a set of IP addresses globally in AD FS, so that requests coming from those IP addresses, or that have those IP addresses in the x-forwarded-for or x-ms-forwarded-client-ip headers, will be blocked by AD FS.

Set-AdfsProperties -AddBannedIps "1.2.3.4", "::3", "1.2.3.4/16"

ADFS Conditional Access /MFA

(2019) ADFS Additional authentication methods:

Scenario 1: protect the password
Protect password-based login from brute-force attacks and lockouts by prompting for an additional, external factor first. Only if the external authentication is successfully completed does the user then see a password prompt. This eliminates a convenient way attackers have been trying to compromise or disable accounts.

This scenario consists of two components:

Prompting for Azure MFA or an external authentication factor as primary authentication
Username and password as additional authentication in AD FS
Scenario 2: password-free!
Eliminate passwords entirely but completing a strong, multi-factor authentication using entirely non password based methods in AD FS

Azure MFA with Authenticator app
Windows 10 Hello for Business
Certificate authentication
External authentication providers

Extranet Soft LockOut vs (ADFS 2019 ) Smart lockout

Extranet Smart Lockout in AD FS 2019 adds the following advantages compared to AD FS 2016:

  • Set independent lockout thresholds for familiar and unfamiliar locations so that users in known good locations can have more room for error than requests from suspect locations

  • Enable audit mode for smart lockout while continuing to enforce previous soft lockout behavior

Wrap Up

Turning on Audits for ADFS is essential to work with lockout events, but audits are essential for overall security and troubleshooting purposes. The next step will be turning on Windows Events Forwarding (WEF)  to collect and analyze all attempts. Last year I read this nice article about WEF and I definitely recommend it in case you missed it.

3 Replies to “How to Turn On ADFS Security Auditing with Powershell”

  1. how can I control the level of auditting on the adfs web proxy server (verbose vs. basic) ???

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.