Category: PowerShell

AD FS Extranet Smart Lockout user management via remote PowerShell

Recently had experienced issue when trying to execute AD FS Extranet Smart Lockout user management cmdlet via remote PowerShell.

Invoke-Command -ComputerName Win2016-ADFS01 -scriptBlock {Get-AdfsAccountActivity -Identity user@domain.com}

Error in PowerShell:

Exception of type
‘Microsoft.IdentityServer.User.UserActivityRestServiceException’ was thrown.
+ CategoryInfo         : NotSpecified: (:) [Get-AdfsAccountActivity], User
ActivityRestServiceException
+ FullyQualifiedErrorId : Microsoft.IdentityServer.User.UserActivityRestSer
viceException,Microsoft.IdentityServer.Management.Commands.GetAdfsAccountAc
tivity
+ PSComputerName       : Win2016-ADFS01

In AD FS Admin logs on Win2016-ADFS01 server saw following error:

Log Name:     AD FS/Admin
Source:       AD FS
Date:         10/29/2018 5:20:39 PM
Event ID:     1100
Task Category: None
Level:         Error
Keywords:     AD FS
User:         domain\adfs_service_account
Computer:     Win2016-ADFS01
Description:
The Federation Service could not authorize a request to one of the REST endpoints.
Additional Data
Exception details:
Microsoft.IdentityServer.WebHost.Rest.RestRequestAuthorizationFailedException: Only AD FS Service can access this endpoint. The client was authenticated as NT AUTHORITY\ANONYMOUS LOGON.
at Microsoft.IdentityServer.Web.UserActivity.UserStoreAuthenticationVerificationMethod.VerifyTrustedRequest(WrappedHttpListenerContext context, String& auditInformation)
at Microsoft.IdentityServer.Web.Rest.RestRequestHandler.OnGetContext(WrappedHttpListenerContext context)

Solution was to enable CredSSP on management machine and Win2016-ADFS01 server and use following commands:

$cred = Get-Credential
Invoke-Command -ComputerName Win2016-ADFS01 -Authentication Credssp -credential $cred -ScriptBlock {Get-AdfsAccountActivity user@domain.com}

You can read more about managing the second hop in PowerShell remoting and consideration when enabling CredSSP in this article – https://docs.microsoft.com/en-us/powershell/scripting/setup/ps-remoting-second-hop?view=powershell-6

Update 2-14-2019: Microsoft has updated the documentation how to delegate ADFS PowerShell access to non-admin users – https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/operations/delegate-ad-fs-pshell-access

 

Advertisements

AD FS 2016 Extranet Smart Lockout behavior

I’m sure you are familiar with the following articles discussing the Federated account lockouts and AD FS Extranet Smart Lockout (ESL) feature and set up recommendations.

https://blogs.technet.microsoft.com/tspring/2017/01/20/federated-to-microsoft-cloud-and-account-lockouts/

https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/operations/configure-ad-fs-extranet-smart-lockout-protection

https://samilamppu.com/2018/07/09/w2016-adfs-smart-lockout/

Recently was helping the customer whose environment was experiencing high volume of on-premises AD accounts lockouts due to the external bad passwords attempts via AD FS 2016 farm.

As per second article, Microsoft recommends enabling the AD FS ESL in the log only mode. It is recommended to run AD FS ESL in such mode for 5-7 days to build the list of familiar locations per user.

Since the impact of the AD lockouts was high to the customer, they decided to switch from log to enforce mode after 24 hours of enabling the ESL, but ran into following issue.

It was not enough time to build the familiar IPs list, and some users accounts still experiencing heavy bad passwords attempts were locked out on AD FS side due to empty familiar IP addresses list.

This happened because in case in the output of Get-AdfsAccountActivity PowerShell cmdlet you see the familiar IP list is empty and the UnknownLockout = True, the user will not be able to sign in with correct password until the observationWindows time elapses or ADFS admin resets the count. In such scenario AD FS ESL works in AD FS Extranet Lockout mode introduced in AD FS 3.0.

This issue was addressed in AD FS 2019 where you can enable audit mode for smart lockout while continuing to enforce the soft lockout behavior (ADPasswordCounter)

Discover and protect from crypto miners in your network using pfSense firewall

In a raise of popularity of crypto mining there is a shift in the threat landscape. Attackers “are beginning to recognize that they can realize all the financial upside of previous attacks, like ransomware, without needing to actually engage the victim and without the extraneous law enforcement attention that comes with ransomware attacks,” Talos researchers write in a new post(http://blog.talosintelligence.com/2018/01/malicious-xmr-mining.html ).

One of the steps you can take to protect your network, is to block outgoing connection to the IP addresses associated with crypto mining pools. Those IPs are easy to get from SANS API (See isc.sans.edu/api for details).

I have used following PowerShell scrip to get the latest IP list.

$date = Get-Date -format "yyyyMMdd"
$url = "https://isc.sans.edu/api/threatlist/miner?xml"
$membersList = Invoke-RestMethod -Uri $url
$membersList | select threatlist -ExpandProperty threatlist |
select miner -ExpandProperty miner | select ipv4 -ExpandProperty ipv4 |
Sort-Object ipv4 -Descending |
out-file "D:\Temp\miners$date.txt"

After that sign in your pfSense firewall, go to Firewall – Aliases menu.

pfSense Aliases menu allows bulk IP addresses upload. Press Import button on the bottom of Aliases page and use the content of the TXT file created earlier to create the alias for the IPs associated with crypto mining pools. I would recommend giving the alias meaningful name which includes the date of creation (will make the firewall rule and aliases management easier as you update the list).

pfSenseCrypto

After creating the alias, go to your LAN rules and create the rule to block any connection from your LAN network to the CryptoMining alias and make sure the rule is on the top of the list (right after rules allowing access to pfSense management ports). Optionally you can select log to monitor what stations in your network tried the malicious outbound connection.

pfSenseCrypto2

On regular basis you can update the IP list and create the new alias (with new date in the name). After that you can easily update the firewall rule by simply changing the destination to new alias.

Also its always recommended to place a default block all LAN rule for outgoing traffic to make sure only authorized connections are successful to the Internet from your hosts.

 

AD FS Single Sign on is not working with Internet Explorer 11

Symptom: when accessing the federated application from inside of the corporate network using Internet Explorer, the users are presented with AD FS Forms Based authentication (FBA) page instead of Windows Integrated Authentication taking place. At the same time Edge and Chrome WIA are working as expected from intranet.

Since there was no Windows security pop up asking for user credentials and other browsers work, this was definitely not an issue related to Windows Authentication not being enabled in ADFS Primary Authentication Methods and not an issue when ADFS host name is missing from Local intranet security zone (https://technet.microsoft.com/en-us/library/jj203438.aspx) in Internet Explorer.

Have checked the list of supported WAI agents in the ADFS global properties by using this command:

Get-AdfsProperties |
Select WIASupportedUserAgents -ExpandProperty WIASupportedUserAgents

 The output was following. Can you find the missing agent string?

ADFSWIAsupportedUserAgents

Correct, the “Trident/7.0” was missing.

Using the following command has resolved the issue:

Set-AdfsProperties -WIASupportedUserAgents ((Get-ADFSProperties |
Select -ExpandProperty WIASupportedUserAgents) + “Trident/7.0”)

You can read more about configuration of intranet form-based authentication for the devices that do not support WIA in this article – https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/operations/configure-intranet-forms-based-authentication-for-devices-that-do-not-support-wia

Query Supercell Clash of Clans API with PowerShell

This is pretty simple example how to query Clash Of Clans API with PowerShell.

First you need to create your account at https://developer.clashofclans.com/#/

Second you need to generate new key ($APIKey) for your IP address.

You can use the Documentation section to get the URL variable depending on what exact info you want to pull.

Get clan members list:

#Get members
$APIkey = ""
$url = "https://api.clashofclans.com/v1/clans/%239yQRPL2C/members"
$headers = @{Authorization = "Bearer:$APIkey"}
$membersList = Invoke-RestMethod -Uri $url -Headers $headers
$membersList

 

RelayState support for AD FS 2016 in the mixed mode ADFS farm

You might experience issues if you are migrating from AD FS 3.0 farm level to AD FS 2016 by gradually introducing AD FS 2016 servers in the farm (running farm in the mixed mode) and if you are using IdP initiated RelayState.

NOTE: the mixed mode is not recommended for production, it was designed to make transition from AD FS 3.0 to AD FS 2016 smoother. 

You can view the AD FS Farm Behavior Level by running following command:  

Get-AdfsProperties | Select CurrentFarmBehavior

A value of 1 indicates that the farm is at the Windows Server 2012 R2 FBL and a value of 3 indicates a Windows Server 2016 FBL.

For the Windows Server 2016 FBL you can enable RelayState support by issuing following command:

Set-AdfsProperties -EnableRelayStateForIdpInitiatedSignOn $True

You might also need to enable IdPInitiatedSignOn page on each AD FS 2016 server. Its disabled by default.

Set-AdfsProperties -EnableIdpInitiatedSignonPage $True

But mentioned two commands will not work for Windows Server 2012 R2 FBL.

If you have AD FS 2016 servers in the AD FS 3.0 farm (farm in the mixed mode), you have to use C:\Windows\ADFS\Microsoft.IdentityServer.ServiceHost.exe.Config file to enable RelayState support.

In the microsoft.identityServer.web section, add a line for useRelyStateForIdpInitiatedSignOn as follows, and save the change:

<microsoft.identityServer.web>    

 <useRelayStateForIdpInitiatedSignOn enabled="true" />    

</microsoft.identityServer.web>

NOTE: you must have 2018-01 Cumulative Update for Windows Server 2016 for x64-based Systems (KB4057142) (for some reason the update description is missing RelayState fix description) installed on each ADFS 2016 server to make it work. Otherwise you will get following errors after making changes in the config file and restarting the ADFS service.  

Log Name:      AD FS/Admin
Source:        AD FS
Date:          1/18/2018 11:57:43 AM
Event ID:      383
Task Category: None
Level:         Error
Keywords:      AD FS
User:          XXX
Computer:      XXX
Description:
The Web request failed because the web.config file is malformed.
User Action:
Fix the malformed data in the web.config file.
Exception details:
MSIS2008: A configuration error has occurred in section ‘microsoft.identityServer.web’.
Unrecognized element ‘useRelayStateForIdpInitiatedSignOn’. (C:\Windows\ADFS\Microsoft.IdentityServer.ServiceHost.exe.Config line 37)

 

 And

Log Name:      AD FS/Admin
Source:        AD FS
Date:          1/18/2018 11:57:43 AM
Event ID:      102
Task Category: None
Level:         Error
Keywords:      AD FS
User:          XXX
Computer:      XXX
Description:
There was an error in enabling endpoints of Federation Service. Fix configuration errors using PowerShell cmdlets and restart the Federation Service.
Additional Data
Exception details:
System.Configuration.ConfigurationErrorsException: MSIS2008: A configuration error has occurred in section ‘microsoft.identityServer.web’. —> System.Configuration.ConfigurationErrorsException: Unrecognized element ‘useRelayStateForIdpInitiatedSignOn’. (C:\Windows\ADFS\Microsoft.IdentityServer.ServiceHost.exe.Config line 37)
at System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] keys, SectionInput input, Boolean isTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult)
at System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, Object& result, Object& resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSection(String configKey)
at System.Configuration.ConfigurationManager.GetSection(String sectionName)
at Microsoft.IdentityServer.Configuration.ConfigurationSectionLoader`1.GetSection()
— End of inner exception stack trace —
at Microsoft.IdentityServer.Configuration.ConfigurationSectionLoader`1.GetSection()
at Microsoft.IdentityServer.Web.Configuration.FederationPassiveConfigurationSection.get_Current()
at Microsoft.IdentityServer.Web.PassiveProtocolListener.LoadProtocolHandlers()
at Microsoft.IdentityServer.Web.PassiveProtocolListener.InitializePipeline()
at Microsoft.IdentityServer.Web.PassiveProtocolListener.Start()
at Microsoft.IdentityServer.ServiceHost.STSService.OnStartInternal(Boolean requestAdditionalTime)