(Updated) Federated to Microsoft Cloud and Account Lockouts

An important requirement to federated single sign on is the availability of the federated network endpoints over the internet. This availability is typically done via HTTP port 443 so that secure Transport Layer Security (TLS) connections can be used when clients need to obtain or pass a token for sign on.

This requirement is something that bad actors can take advantage of for malicious purposes.

The bad actors may be attempting to flood the legitimate business with network traffic or bad password attempts which must be processed or they may simply be attempting to try guessing passwords.

The result is the same in most cases: an impact to the availability of services to legitimate users and possible security breaches.

Malicious entities can target highly visible users like executives or managers. This kind of malicious attempt is most effective from a denial of service perspective if your organization uses Active Directory account lockout policies to lock user accounts on premise if a certain number of bad passwords are submitted. If you have strong passwords enforced, the issue quickly becomes less about the possibility of someone brute forcing the password and more about the account being locked out. This turns into a denial of service to the users as their accounts are locked out and the users are not able to authenticate on-premises or to their cloud services.

How is this possible?

One way is that it is easy for a bad actor to use Home Realm Discovery behavior (type in username@company.com at the Microsoft portals and press enter and be redirected) to discover the federated sign in endpoints.

Another way is to take advantage of any legacy protocols a tenant may have enabled for mail or other services. More on that later in this document.

When users are federated (meaning that their user principal (UPN) name matches one which has been configured in Azure AD/Office 365 for federated single sign on) the Microsoft Cloud forwards the authentication requests to the on-premises federated servers to verify the user's credentials. In the case of Windows ADFS, ADFS will immediately attempt a credential check against the user. If there is a bad password submitted for an identity that bad password will count against any configured Active Directory domain bad password attempt. Other federated services typically work in the same manner and increment the bad password count as well. If an Active Directory domain has a very low account lockout threshold then the user may be locked out in short order.

Malicious bad password attempts combined with an account lockout threshold will result in account lockouts and effective (and perhaps intentional) denial of service to users where they will not be able to access on-premises resources nor Microsoft Cloud services due to their account being locked out.

How do you protect against it?

There are several things to do in different stages of the incident.

Identify the Problem

Brute force and denial of service attacks are characterized by several common symptoms.

  • The logon attempts are persistent and do not stop.
  • They are from a specific geography but could be from ever changing source IP addresses.
  • In most cases the bad actor is taking advantage of Exchange Online basic authentication (also known as legacy authentication) so that the client IP address appears as a Microsoft one. The application side of basic authentication is for use in older mail protocols like IMAP, POP, and SMTP.
  • The attempts typically iterate sign in attempts for each user in an organization using a specific sequence and frequency.

If there is still ambiguity of whether this is truly malicious in nature then first thing is to identify where the bad password attempts are coming from and what identities they are targeting. To figure that out you can turn on ADFS auditing and then review the logs.

Turn on ADFS Auditing

Server 2012R2 and Server 2016 ADFS can be configured for security auditing and service verbose events. These events will show information about the accounts which are being targeted and the IP address of the malicious client doing it.

Note: Server 2012 ADFS (non-R2) does not support the verbosity needed for this investigation. If the customer is seeing suspected brute force behavior against their ADFS they should upgrade or parallel install to Server 2016 ADFS.

  1. Enable ADFS event verbosity using the ADFS Event Log Powershell Module.
  2. This can be downloaded from GitHub here: https://github.com/Microsoft/adfsLogTools
    1. If the ADFS farm is 2016 or is using PowerShell 5 then simply install the module using the command "install-module ADFSLogTools" .
  3. If the ADFS farm is Server 2012 R2 or earlier then on each ADFS server run "import-module ADFSEventsModule" and then "Enable-ADFSAuditing"
  4. If the ADFS farm is Server 2016 then on one ADFS server run "import-module ADFSEventsModule" and then "Enable-ADFSAuditing" to enable auditing on the entire farm.

Review Auditing Data

After enabling auditing events will start to appear on the ADFS servers which need to be reviewed. The critical items to look for are the user principal names being targeted and the IP addresses of the submitting clients.

Important: Azure AD Connect Health for ADFS is the best reporting and review option to review user and IP lists.

  • If the organization is using Azure AD Connect Health (AADCH) for ADFS and the agent is currently installed on all ADFS and WAPs in the farm then easy to use reporting will be available in the Connect health dashboard for ADFS in the Azure portal.
  • ADFS Auditing must already be enabled.
  • AADCH for ADFS requires AAD Premium P1 licensing.
  • AADCH has downloadable reporting on bad password attempts.
  • AADCH for ADFS can be configured to send mail notifications to admins if bad password thresholds (admin configurable) are met.

Important: If AAD Connect Health for ADFS is not available then the ADFS event logs must be reviewed using PowerShell.

If you have Windows Server 2012 R2 ADFS or later, you can search All ADFS Servers' Security event logs for Event ID 411 Source ADFS Auditing events.

  1. You can download the PowerShell script to search your ADFS servers for events 411 at this link. The script will provide a CSV file which contains the UserPrincipalName, IP address of submitter, and time of all bad credential submissions to your ADFS farm.
  2. You can open the CSV in Excel and quickly filter by username, or IP or times.
  3. More information on the 411 events themselves:
    1. These events will contain the user principal name (UPN) of the targeted user.
    2. These events will also contain a message "token validation failed" and will say if it was a bad password attempt or the account is locked out.
    3. There will be one per brute force attempt-there may be a lot.
  4. If your server has 411 events showing up but the IP address field isn't in the event make sure you have the latest ADFS hotfix on your servers.
    1. More information can be found in KB3134222.
  1. If you have Windows Server 2008 R2 or Windows Server 2012 ADFS you will not have the needed Event 411 details. Instead, download and run the PowerShell script below to correlate security events Security Event 4625 (bad password attempts) and 501 (ADFS audit details) together to find the details for the affected users.
    1. You can download the PowerShell script to search your ADFS servers for events at this link. The script will provide a CSV file which contains the UserPrincipalName, IP address of submitter, and time of all bad credential submissions to your ADFS farm.
    2. You can also use this method if you are planning on discovery of what connections are taking place successfully for the users in the 411 events you can search the ADFS events 501 for more detail.
    3. When running the PowerShell script to search your events, just pass the UPN of the user identified in the 411 event(s) or by account lockout reports to your helpdesk.
    4. The IP address of the malicious submitters will appear in one of two different fields in the 501 events.
      1. For web based and most application authentication scenarios the malicious IP will be in the x-ms-client-ip field.

Note

For non-Modern Authentication Outlook clients, the IP address of the malicious submitter will be in the x-ms-forwarded-client-ipand Microsoft Exchange Online server IPs will be in the x-ms-client-ip value.

This is a result of "legacy" or Basic authentication having the Exchange Online servers in the cloud proxying the authentication verification on behalf of the Outlook client. Mail clients which support Modern Authentication (aka ADAL) will not proxy the auth this way.

Mitigate the Immediate Problem (i.e. stop the bleeding)

When you see this issue, it is typically an "all hand on deck" thing. Many users are impacted by having their user accounts locked out and their voices are heard throughout the organization-typically starting with the help desk.

Important

If the organization is using ADFS then the best recommended option to mitigate the problem is to make sure that the customer has Server 2016 ADFS and sets the Extranet Smart Lockout (ESL) feature to enforce.

This may require a move to an ADFS 2016 farm. If the customer has a less complex ADFS configuration (for example one relying party trust and little or no claims rule configuration) then the easiest method would be to do a simply parallel install of ADFS 2016 farm and then switch over to it using a change to DNS and AADConnect to update the trust.

This article describes how to configure ESL on an ADFS farm:

Description of the Extranet Smart Lockout feature in Windows Server 2016

https://support.microsoft.com/en-us/help/4096478/extranet-smart-lockout-feature-in-windows-server-2016

Note that the ESL current configuration can easily be checked by using Get-ADFSProperties in PowerShell on an ADFS server.

The recommendation for using Extranet Smart Lockout is to follow this routine:

  1. Configure ESL in ADFSSmartLockoutLogOnly mode for a period. This period should be long enough for each federated user to have successfully signed in via ADFS at least once to populate their identities "familiar" IP address.
  2. During the ADFSSmartLockoutLogOnly phase the ADFS server will continue to see the brute force attempt impact just as it did with ADFS in prior Windows Server versions.
  3. Once the ADFSSmartLockoutLogOnly period is over set ADFS smart lockout to ADFSSmartLockoutEnforce. This should prevent the ADFS server from passing along bad password attempts from unknown IP addresses any longer.

Tracking User Logon Activity with Extranet Smart Lockout Enforcement Enabled

  1. The event for ADFS extranet lockout is Security event 1210 source AD FS Auditing. This should appear for any extranet lockout activity.

  2. The event does not differentiate between familiar and unfamiliar bad password attempts.

    An example of this event:

    Log Name: Security

    Source: AD FS Auditing

    Date: 6/29/2018 7:34:32 PM

    Event ID: 1210

    Task Category: (3)

    Level: Information

    Keywords: Classic,Audit Failure

    User: domain\serviceaccnt

    Computer: adfsserver.domain.com

    Description:

    An extranet lockout event has occurred. See XML for failure details.

    Additional Data

    XML: <?xml version="1.0" encoding="utf-16"?>

    <AuditBase xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:type="ExtranetLockoutAudit">

    <AuditType>ExtranetLockout</AuditType>

    <AuditResult>Failure</AuditResult>

    <FailureType>ExtranetLockoutError</FailureType>

    <ErrorCode>AccountRestrictedAudit</ErrorCode>

    <ContextComponents>

    <Component xsi:type="ResourceAuditComponent">

    <RelyingParty>https://sts.tspringtoys.com/adfs/services/trust</RelyingParty>

    <ClaimsProvider>N/A</ClaimsProvider>

    <UserId>domain\user5</UserId>

    </Component>

    <Component xsi:type="RequestAuditComponent">

    <Server>N/A</Server>

    <AuthProtocol>WSFederation</AuthProtocol>

    <NetworkLocation>Extranet</NetworkLocation>

    <IpAddress>167.220.148.83</IpAddress>

    <ForwardedIpAddress>167.220.148.83</ForwardedIpAddress>

    <ProxyIpAddress>N/A</ProxyIpAddress>

    <NetworkIpAddress>N/A</NetworkIpAddress>

    <ProxyServer>Proxy1</ProxyServer>

    <UserAgentString>Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko</UserAgentString>

    <Endpoint>/adfs/ls/</Endpoint>

    </Component>

    <Component xsi:type="LockoutConfigAuditComponent">

    <CurrentBadPasswordCount>3</CurrentBadPasswordCount>

    <ConfigBadPasswordCount>3</ConfigBadPasswordCount>

    <LastBadAttempt>06/29/2018 19:34:24</LastBadAttempt>

    <LockoutWindowConfig>00:01:00</LockoutWindowConfig>

    </Component>

    </ContextComponents>

    </AuditBase>

  3. If a user calls and is complaining about their account being locked out immediately run the two commands below and compare the results. These will tell you if they are running into extranet smart lockout behavior or not.

  4. Here is an example of an ADFS example of extranet locked user:

    PS C:\Users\udrt> $user = Get-ADUser -id userfive-Properties UserPrincipalName, BadPwdCount, Lockedout

    PS C:\Users\udrt> $user

    BadPwdCount : 0

    DistinguishedName : CN=User Five,CN=Users,DC=domain,DC=com

    Enabled : True

    GivenName : User

    LockedOut : False

    Name : User Five

    ObjectClass : user

    PS C:\Users\udrt> get-AdfsAccountActivity -UserPrincipalName userfive@domain.com

    Identifier : domain\userfive

    BadPwdCountFamiliar : 0

    BadPwdCountUnknown : 3

    LastFailedAuthFamiliar : 1/1/0001 12:00:00 AM

    LastFailedAuthUnknown : 6/29/2018 7:34:24 PM

    FamiliarLockout : False

    UnknownLockout : True

    FamiliarIps : {}

    Then signed in successfully which clears bad activity and adds Familiar IP:

    PS C:\Users\udrt> get-AdfsAccountActivity -UserPrincipalName userfive@domain.com

    Identifier : domain\userfive

    BadPwdCountFamiliar : 0

    BadPwdCountUnknown : 0

    LastFailedAuthFamiliar : 1/1/0001 12:00:00 AM

    LastFailedAuthUnknown : 6/29/2018 7:34:24 PM

    FamiliarLockout : False

    UnknownLockout : False

    FamiliarIps : {167.220.148.83}

  5. Example PowerShell code to get a specific user's current account lockout and smart lockout status:

    $User = Get-ADUser -id <user> -Properties UserPrincipalName, BadPwdCount, Lockedout

    $User | FL

    get-AdfsAccountActivity -UserPrincipalName <userPrincipalName>

ESL Frequently Asked Questions

  • Q: Will an ADFS farm using Extranet Smart Lockout in enforce mode ever see malicious user lockouts?
    • A: If ADFS Smart Lockout is set to enforce then you will never see the accounts locked out by brute force or denial of service. The only way a malicious account lockout can prevent a user sign in is if the bad actor has the user password or can send requests from a known good (familiar) IP address for that user.
  • Q: What happens if a bad guy has a user password?
    • A: The typical goal of the brute force attack scenario is to guess a password and successfully sign in. If a user is phished or if a password is guessed then the ESL feature will not block the access since the sign in will meet "successful" criteria of correct password plus new IP. The bad actors IP would then appear as a "familiar" one.
    • A: The best mitigation in this scenario is to clear the user's activity in ADFS and to require MFA for the users. More info on that later in the document.
  • Q: If my user has never signed in successfully from an IP and then tries with wrong password a few times will they be able to login once they finally type their password correctly?
    • A: When a user who has been submitting bad passwords (legitimately mis typing or for other legit reason) and finally gets the password correct then the user will immediately succeed to sign in.  This will clear the bad password count familiar and bad password count unknown and add that IP to the FamiliarIPs list.
  • Q: What should we expect when we set ADFS to log only mode?
    • A: If the ADFS server is set to ADFSSmartLockoutLogOnly mode then it will have the same Extranet behavior as the soft lockout feature in Server 2012 R2.
  • Q: Does ESL work on intranet too?
    • A: If the clients connect directly to the ADFS servers and not via Web Application Proxy servers then the ESL behavior will not apply.
  • Q: What if my clients all show as having the same client IP?
    • A: If all clients connect through a specific network provider or connection and use the same internet facing IP address then this will result in unexpected results from ESL. This can happen when all clients on the corporate network connect via the proxy servers or for other network reasons. Our recommendation is to only have external clients with individual IPs connect to ADFS for ESL.
  • Q: Will ESL block EXO proxied brute force attacks?
    • A: ESL will work well to prevent Exchange Online or other legacy authentication brute force attack scenarios. It does this by reviewing the header contents and requiring that all IPs be familiar ones.

More information on Modern Authentication and Basic Authentication Office 365 scenarios can be found online here.

Mitigation: Less Exciting Ways to Block the Bad Guys

If using another federated service provider other than ADFS or if Server 2016 ADFS is not an option, then less optimal methods need to be used to mitigate the scenario.

The best way to address this scenario is the same way you would address a denial of service to a public web site: block the IP address(es) of the submitters at the network level (firewall). This approach is basically the same one you would take if the scenario was your website being targeted for brute force or denial of service attacks.

Blocking by Policy or Block List at Exchange Online

Exchange Online has a new policy method for blocking the most common vector for password spray attacks.  It is in Preview mode however it can still be effective.  More information, including how to enable this feature, can be found at this blog post.

If you cannot disable all Basic Authentication in your environment (though you should!) then a block list cam be put in place at the Exchange Online (EXO) service side to block certain IPs or ranges of IP addresses. This method has the advantages of blocking a common avenue of attack and being a very easy method to enable. The disadvantages of this method are that it only covers the EXO basic authentication scenario and that, like all IP address black lists, the blocks must be updated as the attacker moves to new IP addresses.

Office 365 customers can self-manage domain-wide IP Block Lists. This is done via Exchange Online PowerShell in the following formats

  1. Standard IPv4 and IPv6 address
  2. IP range

For ex. IP Block ranges may be submitted using the following formats:

  1. CIDR format- 2001:0DB8::CD3/60
  2. High-Low format- 192.168.0.1-192.168.0.254
  3. sub masking format- 192.168.8.2(255.255.255.0)

Here are the steps for self-service management of EXO IP Block list.

  1. If you haven't already done so on the PS client being used, run the following 1x:Set-ExecutionPolicy RemoteSigned

  2. Connect to EXO using steps 1-3 in https://technet.microsoft.com/en-us/library/jj984289(v=exchg.160).aspx  using Global Admin or Exchange admin security context. If you have enabled MFA for your Administrator, please follow the steps in the document to get connect to EXO Powershell - https://technet.microsoft.com/en-us/library/mt775114(v=exchg.160).aspx

  3. Enable the block list for the IP address assigned to the test device used in step 1To enable the IP block on a single IP, use the syntax:Set-OrganizationConfig  -IPListBlocked 127.0.0.2To enable the IP block on multiple IPs using an array of IP formats depicted in formats 2a-2c above, use the syntax:

    Set-OrganizationConfig -IPListBlocked@{add="198.76.9.23", "172.16.0.0-172.31.255.255","2001:db8:0:1234:0:567:8:1", "2001:0DB8::CD3/60","192.168.8.2(255.255.255.0)","2001:db8::1","2001:0DB8:0000:CD30:0000:0000:0000:0000/60","ABCD:EF01:2345:6789:ABCD:EF01:2345:6789"}

  4. Verify your block list submission

    get-OrganizationConfig | select -ExpandProperty IPListBlocked

    1. 2001:0DB8:0000:CD30:0000:0000:0000:0000/60
    2. 2001:db8::1192.168.8.2(255.255.255.0)
    3. 2001:0DB8::CD3/60
    4. 2001:db8:0:1234:0:567:8:1
    5. 172.16.0.0-172.31.255.255
    6. 198.76.9.23
    7. ABCD:EF01:2345:6789:ABCD:EF01:2345:6789
    8. 127.0.0.2
  5. Wait 4 hours for the IP Block list change to fully propagate in the Exchange Online environment. You may see partial authentication request from blocked IPs until the blocked IP configuration is fully propagated.  

  6. Note: Please note that if you add and subsequently remove the IP Block list, the change request will be processed sequentially. Hence please take proper precaution the IP(s) you are blocking are not a part of your organization.

  7. To close the session, run the cmdlet below.

    Remove-PSSession $Session

For federated single sign on, the best practice is to have the proxy servers for ADFS (or any federated service) in a DMZ. Since DMZs have network traffic rules it would make sense to add a blocking rule at the DMZ to prevent the traffic from the suspect IPs from ever reaching the Web Application Proxy (WAP) servers. However, some environments make this an easier approach to do in the load balancer, or even at the internet service provider (ISP). The net result is to prevent the brute force traffic from ever reaching the ADFS servers in the first place.

The only fly in the ointment in the traffic blocking scenario is that "legacy" Exchange Online authentication mentioned above which will actually proxy the authentication of the thick "Basic Authentication" Outlook clients to the on premise ADFS servers. This scenario sounds complicated but really only means that Outlook connects to the Exchange Online servers and then the Exchange Online servers authenticate to your on premise ADFS servers on the users behalf. So there is a connection from the Exchange servers IP address as the client.

In that instance blocking the malicious IP address at the DMZ perimeter won't work since the IP address is actually a Microsoft Exchange Online one. Instead you would need to either examine your ADFS server's events for the IP address in the x-ms-forwarded-client-ip value or do SSL termination on your network before the Web Application Proxy servers and review the data on a network device. Again, this requires SSL termination in a network device prior to the WAP servers.

If your environment is seeing Exchange Online Basic Authentication being used to pass along brute force attempts then you should also consider disabling POP and IMAP protocols for the targeted users.

In addition to the account lockouts that you were experiencing due to constant Exchange Active Sync Authentication requests we also identified that there are similar types of requests on the IMAP, SMTP and POP protocol currently occurring.

Our recommendation is to disable these protocols if they are not needed for the users.  This will block the requests at the service side preventing it from being forwarded to your ADFS servers which will reduce the available attack service.

Unless you have an account that specifically relies on it you can disable IMAP and the POP protocols across all your mailboxes by running the following command:
get-mailbox | Set-CasMailbox -PopEnabled $False -ImapEnabled $False

This action should also help to mitigate the issues related around these protocols that also rely on basic authentication and may not be needed in your environment.

The GUI method in the Office 365 Portal is as follows:
Mitigation: Refine Sign In Security

Review AD Account Lockout Threshold, Implement ADFS Extranet Lockout feature, Enable MFA

Password security is important, so this should start with a review your organization's password complexity requirement to make sure passwords are sufficiently complex and cannot be quickly guessed via brute force attempts.

Once that is done review and consider raising the current Active Directory on-premises account lockout threshold to determine whether the current setting is providing sufficient security to prevent password guessing while at the same time preventing intentional or unintentional account lockouts from bad password attempts which will result in denial of services. This topic is discussed on TechNet here.

If your organization is seeing targeted account lockouts to a specific subset of users you may be very granular in addressing the concern by using Fine Grained Password Policy settings. This feature essentially allows for assignment of a different password complexity and account lockout configuration for a security group or specific users.

In my experience, organizations discover that the on-premises Active Directory account lockout threshold is set too low when there is a rash of maliciously based account lockouts or unintentional account lockouts from an application. In this scenario, I encourage reviewing the balance between preventing password guessing via brute force and allowing denial of services for users since their account had too many bad password attempts.

When using ADFS, it is also important to implement the ADFS 2016 Extranet Smart lockout feature. This feature will help mitigate large numbers of attempts from locking out accounts since it is a lower threshold than what you have defined in AD and will cause ADFS to stop forwarding the bad password attempts to AD.

Additionally, it's important to require Multi Factor Authentication (MFA) sign in for users. This can't be stressed enough as being a useful security item to implement. The MFA requirement will mitigate the risk if a password is guessed or phished since MFA will still be required to complete the authentication and a malicious user will lack the required additional factor of a phone call, a text message or other method.

Office 365 MFA or Azure AD Multi Factor Authentication (MFA) may be used. If you have your own MFA solution then that works too. In any case, MFA can be very quickly implemented via your cloud services. For Azure AD MFA the setup would require:

  • Assigning an Azure AD Premium license to the user(s)
  • Deciding on MFA settings for complexity, duration of MFA authentication, and a review of the user's device(s) and applications to ensure their device apps support MFA.

For organizations which need to decide which MFA solution to use, information on the differences between Office 365 and Azure AD MFA can be found online at this link and general pricing information for Azure AD MFA is documented here. Some additional MFA information can be found in Channel 9's MFA OVerview, in Azure online documentation here, and finally in the MFA Deployment Guide.

If your ADFS farm is Server 2012 R2 then you do not have to do additional steps to simply use Azure AD MFA. However, ADFS allows for on premise control of MFA via claims rules if you would like to implement them. For example, if a user is a member of a security group and they are signing in from extranet you can require MFA auth from them. More information on MFA related claims rules can be found in the blog posts below:

Review, Report, Monitor

It's important to review your online reports for Office 365 and Azure AD to see what impact (if any) the incident has had to online services and resources. This entails a review Azure AD Security Reports (for alerts on activity deemed to be malicious), Azure AD Audit Reports (for details on changes to anything in Azure AD), and Sign In Activity (which will show when denies attempted sign in, to what and the end result). A review of these reports for activity for and by the affected VIP users to gauge impact of the event is vital to address the concern.

More information on Azure AD reports is online here: /en-us/azure/active-directory/active-directory-view-access-usage-reports

Outside of the immediate review it's also important to implement a consistent routine of automatic download of Azure AD Security Reports, Audit Reports, and Sign In Activity reports.  This can be done by setting a scheduled task on a Windows computer to run PowerShell scripts to pull the reports down periodically for reference.

Just as important is to configure Azure AD to notify global administrators if anomalous sign ins are seen in the future.  This is a switch setting in Azure AD (screenshot below) in the Azure AD web portal:

Long Term Recommendation

Consider moving to a Windows Server 2016 ADFS farm in order to mitigate bad password submission attempts by using the Multi Factor Authentication feature in 2016. This will allow Azure MFA as the primary authentication method.  This prevents the scenario of a low account lockout threshold and malicious bad password attempts via brute force from being a concern.  This is discussed in more detail on TechNet here.

Note that a server 2016 ADFS farm could be in place as a parallel switch-over upgrade or an in place farm upgrade.

To sum things up, scenarios where malicious entities can submit bad password attempts can be a challenge at first. However, like any challenge you may face in life you can build strength and capability in how to address the problem and overcome it. Once you've overcome the challenge any next one won't be near as impactful or difficult.

difficult.