Jorge's Quest For Knowledge!

All About Identity And Security On-Premises And In The Cloud – It's Just Like An Addiction, The More You Have, The More You Want To Have!

(2018-11-06) Meet Poshkatz – Mimikatz On PowerShell Steroids

Posted by Jorge on 2018-11-06


We all know Mimikatz right? If you do not, Mimikatz is a tool that really can do some geeky funky stuff with regards to Windows/AD security. It can do stuff like: extract plaintexts passwords, hash, PIN code and kerberos tickets from memory. mimikatz can also perform pass-the-hash, pass-the-ticket or build Golden tickets.

Now meet Poshkatz! Poshkatz is a PowerShell module/wrapper around Mimikatz with tab completion! The module was created by Adam Driscoll and Lee Berg

Enjoy!

Cheers,
Jorge

————————————————————————————————————————————————————-
This posting is provided "AS IS" with no warranties and confers no rights!
Always evaluate/test everything yourself first before using/implementing this in production!
This is today’s opinion/technology, it might be different tomorrow and will definitely be different in 10 years!
DISCLAIMER:
https://jorgequestforknowledge.wordpress.com/disclaimer/
————————————————————————————————————————————————————-
########################### Jorge’s Quest For Knowledge ##########################
####################
http://JorgeQuestForKnowledge.wordpress.com/ ###################
————————————————————————————————————————————————————-

Advertisements

Posted in PowerShell | Leave a Comment »

(2018-11-05) Azure AD Connect v1.2.65.0 Has Been Released

Posted by Jorge on 2018-11-05


Integrating your on-premises directories with Azure AD makes your users more productive by providing a common identity for accessing both cloud and on-premises resources. With this integration users and organizations can take advantage of the following:

  • Organizations can provide users with a common hybrid identity across on-premises or cloud-based services leveraging Windows Server Active Directory and then connecting to Azure Active Directory.
  • Administrators can provide conditional access based on application resource, device and user identity, network location and multifactor authentication.
  • Users can leverage their common identity through accounts in Azure AD to Office 365, Intune, SaaS apps and third-party applications.
  • Developers can build applications that leverage the common identity model, integrating applications into Active Directory on-premises or Azure for cloud-based applications

Azure AD Connect makes this integration easy and simplifies the management of your on-premises and cloud identity infrastructure.

Download "Microsoft Azure Active Directory Connect"

Azure AD Connect: Version Release History

1.2.65.0

Released: 10/25/2018

Released for download

Prerequisites for Azure AD Connect

More information about Azure AD Connect

IMPORTANT: I upgraded Azure AD Connect v1.1.882, and the next time it synched it triggered a full import and full sync for both the AD connector and the AAD connector. Since this may take some time, depending on the size of your AD/AAD environment in terms of number objects being synched, make sure that you have taken the necessary steps to support this or hold off on upgrading until you have found a convenient moment to do so.

New features and improvements
  • Changed the functionality of attribute write-back to ensure hosted voice-mail is working as expected. Under certain scenarios, Azure AD was overwriting the msExchUcVoicemailSettings attribute during write-back with a null value. Azure AD will now no longer clear the on-premises value of this attribute if the cloud value is not set.
  • Added diagnostics in the Azure AD Connect wizard to investigate and identify Connectivity issues to Azure AD. These same diagnostics can also be run directly through Powershell using the Test- AdSyncAzureServiceConnectivity Cmdlet.
  • Added diagnostics in the Azure AD Connect wizard to investigate and identify Connectivity issues to AD. These same diagnostics can also be run directly through Powershell using the Start-ConnectivityValidation function in the ADConnectivityTools Powershell module. For more information see What is the ADConnectivityTool PowerShell Module?
  • Added an AD schema version pre-check for Hybrid Azure Active Directory Join and device write-back
  • Changed the Directory Extension page attribute search to be non-case sensitive.
  • Added full support for TLS 1.2. This release supports all other protocols being disabled and only TLS 1.2 being enabled on the machine where Azure AD Connect is installed. For more information see TLS 1.2 enforcement for Azure AD Connect

Fixed issues
  • Fixed a bug where Azure AD Connect Upgrade would fail if SQL Always On was being used.
  • Fixed a bug to correctly parse OU names that contain a forward slash.
  • Fixed an issue where Pass-Through Authentication would be disabled for a clean install in staging mode.
  • Fixed a bug that prevented the PowerShell module to be loaded when running the Troubleshooting tools
  • Fixed a bug that would block customers from using numeric values in the first character of a host name.
  • Fixed a bug where Azure AD Connect would allow invalid partitions and container selection
  • Fixed the “Invalid Password” error message when Desktop SSO is enabled.
  • Various Bug fixes for AD FS Trust Management
  • When configuring Device Writeback – fixed the schema check to look for the msDs-DeviceContainer object class (introduced on WS2012 R2)

I (finally) ran the MSI and upgraded from the previous version without any issues!

Cheers,
Jorge

————————————————————————————————————————————————————-
This posting is provided "AS IS" with no warranties and confers no rights!
Always evaluate/test everything yourself first before using/implementing this in production!
This is today’s opinion/technology, it might be different tomorrow and will definitely be different in 10 years!
DISCLAIMER:
https://jorgequestforknowledge.wordpress.com/disclaimer/
————————————————————————————————————————————————————-
########################### Jorge’s Quest For Knowledge ##########################
####################
http://JorgeQuestForKnowledge.wordpress.com/ ###################
————————————————————————————————————————————————————-

Posted in Azure AD Connect, Windows Azure Active Directory | Tagged: , | Leave a Comment »

(2018-11-01) Deploying The Sample Azure AD GraphAPI B2B Web Portal, Starting From “App Registrations (Preview)”

Posted by Jorge on 2018-11-01


If you are interested in Azure AD B2B, and especially in the self-service part, you may also be interested in deploying and testing the sample Azure AD GraphAPI B2B Web Portal. I’m one of those persons that falls into that category!

The sample Azure AD GraphAPI B2B Web Portal can be found here. A detailed instruction to configure and deploy can be found here.

Reasons for this blog post are:

  • You should be good when starting from “App Registrations”, but if you start from “App Registrations (Preview)” (or whatever it will be called in the future), then some steps are slightly different and you may or may not understand what you need to do;
  • The sample Azure AD GraphAPI B2B Web Portal may not work in the end, which needs fixing.

So, let’s get started while starting from “App Registrations (Preview)”

[Step 1] Determine Your Tenant ID

No changes in the steps

[Step 2] Registering The AAD B2B Admin Application

When creating a new registration for the AAD B2B Admin Application, go to the “App Registrations (Preview)” and click “New Registration”

  • For the “user-facing display name for this application” enter for example “Azure AD B2B Admin Application”
  • For the “Supported Account Types” choose “Accounts In This Organization Directory Only” (meaning, all user accounts and all guests accounts from this directory only)
  • For the “Redirect URI” choose “Web” and as a URL specify “https://loopback” (will be updated later!)
  • At the bottom click “Register”

image

Figure 1: Registering The Azure AD B2B Admin Application

Right after registering, it will open in the “Overview” node.

  • Write down the “application ID” which is required later in the Web Application/App Service as the client ID for the admin application

image

Figure 2: Overview Details Of The Azure AD B2B Admin Application

Click on the “Authentication” node

  • Make sure to check “ID Tokens” or you will have some fun later on!
  • Click on SAVE at the top

image

Figure 3: Selecting The Required Token For The Implicit Grant Flow

Click on the “Certificates And Secrets” node

  • Click on “New Client Secret”

image

Figure 4: The Certificates And Secrets Page

  • As a “Description” enter for example “Azure AD B2B Admin Application Secret – Key 1”
  • Select an expiration period that you are comfortable with
  • Click ADD

image

Figure 5: Adding A Client Secret For The Azure AD B2B Admin Application

  • Make sure to copy or write down the value as you will not have a chance to get it back later!

image

Figure 6: Client Secret Defined For The Azure AD B2B Admin Application

Click on the API Permissions node

  • If correct, the “Delegated” permission for “Sign In And Read User Profile” is already configured
  • Click on Add A Permission

image

Figure 7: API Permissions For The Azure AD B2B Admin Application

  • On the new pane at the right that opens click on Microsoft Graph

image

Figure 8: Selecting The Microsoft Graph As The API To Grant Permissions To

  • If the “Delegated” permissions are not yet configured, click on “Delegated Permissions”, otherwise skip this step

    • Scroll down to User and expand User and select User.Read (“Sign In And Read User Profile”)

    • Click Add Permissions

image

Figure 9: Selecting Delegated Permissions

image

Figure 10: User Permissions To Assign As Delegated Permissions

  • Click on Add A Permission

    • On the new pane at the right that opens click on Microsoft Graph

    image

    Figure 11: Selecting The Microsoft Graph As The API To Grant Permissions To

      • Click on “Application Permissions”
        • Scroll down to Directory and expand Directory and select Directory.ReadWrite.All (“Read And Write Directory Data”)
        • Scroll down to User and expand User and select User.ReadWrite.All (“Read And Write All Users’ Full Profiles”)
        • Click Add Permissions

      image

      Figure 12: Selecting Application Permissions

      image

      Figure 13: Directory Permissions To Assign As Application Permissions

      image

      Figure 14: User Permissions To Assign As Application Permissions

      [Step 3] Registering The AAD B2B Pre-AuthN Application

      When creating a new registration for the AAD B2B Pre-AuthN Application, go to the “App Registrations (Preview)” and click “New Registration”

      • For the “user-facing display name for this application” enter for example “Azure AD B2B Pre-AuthN Application”
      • For the “Supported Account Types” choose “Accounts In Any Organization Directory And Personal Microsoft Accounts” (meaning, any user account from any Azure AD directory and any personal Microsoft Account) OR choose “Accounts In Any Organization Directory” (meaning, any user account from any Azure AD directory)
      • For the “Redirect URI” choose “Web” and as a URL specify “https://loopback” (will be updated later!)
      • At the bottom click “Register”

      image

      Figure 15: Registering The Azure AD B2B Pre-AuthN Application

      Right after registering, it will open in the “Overview” node.

      • Write down the “application ID” which is required later in the app service as the client ID for the pre-authN application

      image

      Figure 16: Overview Details Of The Azure AD B2B Pre-AuthN Application

      Click on the “Authentication” node

      • Make sure to check “Access Tokens” and “ID Tokens” or you will have some fun later on!
      • Click on SAVE at the top

      image

      Figure 17: Selecting The Required Tokens For The Implicit Grant Flow

      Click on the “Certificates And Secrets” node

      • Click on “New Client Secret”

      image

      Figure 18: The Certificates And Secrets Page

      As a “Description” enter for example “Azure AD B2B Admin Application Secret – Key 1”

      • Select an expiration period that you are willing to accept
      • Click ADD

      image

      Figure 19: Adding A Client Secret For The Azure AD B2B Pre-AuthN Application

      • Make sure to copy or write down the value as you will not have a chance to get it back later!

      image

      Figure 20: Client Secret Defined For The Azure AD B2B Pre-AuthN Application

      Click on the “API Permissions” node

      • If correct, the “Delegated” permission for “Sign In And Read User Profile” is already configured
      • If the “Delegated” permissions are not yet configured (otherwise skip this step)
        • Click on “Click on Add A Permission”
        • Click on “Microsoft Graph”
        • Click on “Delegated Permissions”
        • Scroll down to User and expand User and select User.Read (“Sign In And Read User Profile”
        • Click Add Permissions

      image

      Figure 21: API Permissions For The Azure AD B2B Pre-AuthN Application

      image

      Figure 22: Selecting The Microsoft Graph As The API To Grant Permissions To

      image

      Figure 23: Selecting Delegated Permissions

      image

      Figure 24: User Permissions To Assign As Delegated Permissions

      Click on the “Manifest” node

      • Find the line "oauth2AllowImplicitFlow", and change "false" to "true". Don’t include quotes, just replace the word.
      • Click SAVE

      image

      Figure 25: Editing The Manifest

      [Step 4] Deploying The Web Application

      No changes in the steps

      [Step 5] Post Configuration Cleanup

      No changes in the steps for the The Azure AD B2B Admin Application

      However, for the The Azure AD B2B Pre-AuthN Application, you should specify 2 reply URLs instead of just 1.

      The following Reply URLs must be specified:

      image

      Figure 26: Reply URLs For The Azure AD B2B Pre-AuthN Application

      [Step 6] Trying It Out

      Navigate to the URL of the Web Application and you will see the following

      image

      Figure 27: Notification The B2B Portal Requires Configuration By An Admin

      After clicking on Admin Sign In on the right and signing in, you should see

      image

      Figure 28: Site Configuration Screen For The B2B Portal

      …but if you see

      image

      Figure 29: Error Notification Something Is Wrong

      Error

      An error occurred while processing your request.

      link: /Home/Error?message=unsupported_response_type">https://<Web_Application_URL>/Home/Error?message=unsupported_response_type

      Something is really wrong (duh!)

      Now retry it again until you need to authenticate, but don’t!. Now look at the URL which should be similar to the one below

      image

      Figure 30: The URL At The Time Of Authentication

      It is expecting a response type of “code” and “id_token” for the client with ID as specified by the red arrow (which is the Application ID of the Admin application registration)

      have you checked “ID Token” for the Admin application registration? If not, then go back and check it (Picture 3)

      After changing that, retry and it should work!

      In all three cases below, when the invited user logs in to /Profile">https://<Web_Application_URL>/Profile, everything is OK.

      However, as soon as the user tries to sync its profile from its home tenant to the inviting tenant, you will experience the following:

      … if the “ID Token” is not checked for the Azure AD B2B Pre-AuthN Application (Figure 17)

      image

      Figure 31: Error When The “ID Token” Is Not Selected For The Azure AD B2B Pre-AuthN Application

      … if only one reply URL is configured (main URL for the web application) and not 2 as shown in figure 26

      image

      Figure 32: Error When The “ID Token” Is Not Selected For The Azure AD B2B Pre-AuthN Application

      … if the “Access Token” is not checked for the Azure AD B2B Pre-AuthN Application (Figure 17)

      image

      Figure 33: Error When The “Access Token” Is Not Selected For The Azure AD B2B Pre-AuthN Application

      Cheers,
      Jorge

      ————————————————————————————————————————————————————-
      This posting is provided "AS IS" with no warranties and confers no rights!
      Always evaluate/test everything yourself first before using/implementing this in production!
      This is today’s opinion/technology, it might be different tomorrow and will definitely be different in 10 years!
      DISCLAIMER:
      https://jorgequestforknowledge.wordpress.com/disclaimer/
      ————————————————————————————————————————————————————-
      ########################### Jorge’s Quest For Knowledge ##########################
      ####################
      http://JorgeQuestForKnowledge.wordpress.com/ ###################
      ————————————————————————————————————————————————————-

      Posted in Azure AD B2B, Windows Azure Active Directory | Leave a Comment »

      (2018-11-01) Transform Rules In ADFS – Send E-Mail Address Value For E-mail, Otherwise Send UPN Value For E-Mail

      Posted by Jorge on 2018-11-01


      A few days ago I got the following question:

      • Some accounts have a mailbox, some do not;
      • For accounts that do have a mailbox I need to send the e-mail address value as the claim value in the e-mail address claim type;
      • For accounts that do not have a mailbox I need to send the upn value as the claim value in the e-mail address claim type;

      How can I achieve that through the claims rule language in ADFS?

      It is not that difficult. See below for an example as the answer to the question above:

      RULENAME1: User Identity Claims – Windows Account Name
      COMMENT1: if the windows account name claim exists and has a value send it through

      c:[Type == "
      http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"]
      => issue(claim = c);

      RULENAME2: User Identity Claims – upn
      COMMENT2: if the UPN claim exists and has a value send it through

      c:[Type == "
      http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"]
      => issue(claim = c);

      RULENAME3: User Identity Claims – E-Mail Address
      COMMENT3: get mail from AD and put it in claim

      c:[Type == "
      http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"]
      => issue(store = "Active Directory", types = ("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"), query = ";mail;{0}", param = c.Value);

      RULENAME4: System Claims – Check E-Mail Address Existence
      COMMENT4: check if the mail address claim exist or not

      NOT EXISTS([Type == "
      http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"])
      => add(Type = "http://temp.org/system/claims/eMailAddressExistance", Value = "False");

      RULENAME5: User Identity Claims – upn To E-Mail Address (When E-Mail Address DOES NOT Exist)
      COMMENT5: send the UPN value into mail address claim if no mail claim address exists

      c1:[Type == "
      http://temp.org/system/claims/eMailAddressExistance", Value == "False"] &&
      c2:[Type == "
      http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"]
      => issue(Type = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", Value = c2.Value);

      Make sure to test this first in a TEST environment!

      Cheers,
      Jorge

      ————————————————————————————————————————————————————-
      This posting is provided "AS IS" with no warranties and confers no rights!
      Always evaluate/test everything yourself first before using/implementing this in production!
      This is today’s opinion/technology, it might be different tomorrow and will definitely be different in 10 years!
      DISCLAIMER:
      https://jorgequestforknowledge.wordpress.com/disclaimer/
      ————————————————————————————————————————————————————-
      ########################### Jorge’s Quest For Knowledge ##########################
      ####################
      http://JorgeQuestForKnowledge.wordpress.com/ ###################
      ————————————————————————————————————————————————————-

      Posted in Active Directory Federation Services (ADFS), Claims, Claims Rule Language | Leave a Comment »

      (2018-10-26) Running The Azure AD Password Protection Summary Report May Generate An Error

      Posted by Jorge on 2018-10-26


      When on one of the Azure AD Password Protection Proxy servers, you can generate an Azure AD Password Protection Summary report through one of the following commands:

      Targeting a specific DC:

      Get-AzureADPasswordProtectionSummaryReport -DomainController <RWDC FQDN>

      Targeting all DCs in a specific AD Domain:

      Get-AzureADPasswordProtectionSummaryReport -Domain <AD DOMAIN FQDN>

      Targeting all DCs in a specific AD Forest:

      Get-AzureADPasswordProtectionSummaryReport -Forest <AD FOREST FQDN>

      Targeting all DCs in the local AD Forest:

      Get-AzureADPasswordProtectionSummaryReport

      So, whatever your targeted scope is, if all DCs have have the Azure AD Password Protection DC Agent installed, they will also have the corresponding event logs, which are:

      Get-WinEvent -ListLog * | ?{$_.LogName -like "*AzureADPasswordProtection*"}

      image

      Figure 1: All The Azure AD Password Protection DC Agent Event Logs On An RWDC

      ….and for completeness on the Azure AD Password Protection Proxy servers

      Get-WinEvent -ListLog * | ?{$_.LogName -like "*AzureADPasswordProtection*"}

      image

      Figure 2: All The Azure AD Password Protection Proxy Event Logs On The Proxy Servers

      However, if you see errors similar to the one below…

      image

      Figure 2: Error When Generating The Azure AD Password Protection Summary Report Against Targeted DCs

      …then the targeted event logs are missing. And of the events logs are missing, then the Azure AD Password Protection DC Agent is most likely not installed on the RWDC.

      Solution? Install the Azure AD Password Protection DC Agent on the RWDC that throws the error.

      Please be aware that querying for DCs that have the Service Connection Point (SCP) registered in AD, may not be accurate. Why? If you installed the Azure AD Password Protection DC Agent and then uninstall it, for whatever reason, the SCP for that RWDC is not cleaned during the uninstall. Also be aware that if you force removed any DC and did not clean up its metadata, you will be trying to reach an RWDC that does not exist anymore when running the summary report.

      Although more intense, the most accurate way is checking for any of the following:

      • If the Azure AD Password Protection DC Agent is installed (against every RWDC –> Get-WmiObject -Class win32_product -Filter "Name like ‘Azure AD Password Protection DC Agent’")
      • If the Azure AD Password Protection DC Agent service is installed (against every RWDC –> Get-Service AzureADPasswordProtectionDCAgent)
      • If the Azure AD Password Protection DC Agent is installed (against every RWDC –> Get-WinEvent -ListLog * | ?{$_.LogName -like "*AzureADPasswordProtection*"})

      Cheers,
      Jorge

      ————————————————————————————————————————————————————-
      This posting is provided "AS IS" with no warranties and confers no rights!
      Always evaluate/test everything yourself first before using/implementing this in production!
      This is today’s opinion/technology, it might be different tomorrow and will definitely be different in 10 years!
      DISCLAIMER:
      https://jorgequestforknowledge.wordpress.com/disclaimer/
      ————————————————————————————————————————————————————-
      ########################### Jorge’s Quest For Knowledge ##########################
      ####################
      http://JorgeQuestForKnowledge.wordpress.com/ ###################
      ————————————————————————————————————————————————————-

      Posted in Azure AD Password Protection, Windows Azure Active Directory | Leave a Comment »

      (2018-10-25) When Installing The Azure AD Password Protection DC Agent Generates An Error

      Posted by Jorge on 2018-10-25


      If you are installing the Azure AD Password Protection DC Agent on an RWDC and you receive the following error….

      image

      Figure 1: An Error The Azure AD Password Protection DC Agent Setup Wizard Ended Prematurely

      ….execute the AADPwdProtection\AzureADPasswordProtectionDCAgent.msi with the following options

      MSIEXEC /i AzureADPasswordProtectionDCAgent.msi /log AzureADPasswordProtectionDCAgent.log

      After it errors again, open the log file and search for the word ERROR. When you do, you will most likely find why it errors. If it has the same cause as I had, you will see something similar to the following:

      Dumping MSI properties of interest:
        ‘INSTALLDIR’ = ‘C:\Program Files\Azure AD Password Protection DC Agent\’
        ‘Installed’ = ”
        ‘INSTALLLEVEL’ = ‘1’
        ‘ProductCode’ = ‘{67E66797-A45C-4C3C-B481-554F9F427227}’
        ‘ProductID’ = ”
        ‘ProductName’ = ‘Azure AD Password Protection DC Agent’
        ‘ProductState’ = ‘-1’
        ‘ProductVersion’ = ‘1.2.10.0’
        ‘ProgramFiles64Folder’ = ‘C:\Program Files\’
        ‘Remove’ = ”
        ‘UPGRADINGPRODUCTCODE’ = ”
        ‘BPL_NONUPGRADEABLEAPPFOUND’ = ”
        ‘BPL_STATEMIGRATIONFOLDER’ = ”
      Done with MSI property dump
      CheckForNonUpgradeableApps – opened Uninstall key with 9 subkeys
      CheckForNonUpgradeableApps – a nonupgradeable app was found ‘Azure AD Password Protection DC Agent’ – ‘1.1.10.3’
      CustomAction BPL_CheckForNonUpgradeableApps returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox)
      Action ended 16:30:01: BPL_CheckForNonUpgradeableApps. Return value 3.
      Action ended 16:30:01: INSTALL. Return value 3.


      In plain English this means you are trying to install a newer version on top of an version that cannot be upgraded. Check the versions. The old version here was installed by means months ago when I participated in the public preview. Today I wanted to install the officially released version and had forgotten the old version was still installed.

      The solution here? Uninstall the old version first and install the newer version. After both the uninstall and the install a reboot of the RWDC is required.

      To determine if a version is already installed and if yes to uninstall it, execute the following commands:

      WMIC PRODUCT GET NAME | FIND /I "Azure AD Password Protection DC Agent"

      WMIC PRODUCT WHERE NAME="Azure AD Password Protection DC Agent" CALL UNINSTALL

      ….and if you are a PowerShell junky, you can also use the following for the uninstall

      $product = Get-WmiObject -Class win32_product -Filter "Name like ‘Azure AD Password Protection DC Agent’"

      $product

      $product.Uninstall() # WARNING: Reboot is immediate, no mercy and no questions asked!!!

      After the uninstall and reboot, install the newest AzureADPasswordProtectionDCAgent.msi available from Microsoft

      Cheers,
      Jorge

      ————————————————————————————————————————————————————-
      This posting is provided "AS IS" with no warranties and confers no rights!
      Always evaluate/test everything yourself first before using/implementing this in production!
      This is today’s opinion/technology, it might be different tomorrow and will definitely be different in 10 years!
      DISCLAIMER:
      https://jorgequestforknowledge.wordpress.com/disclaimer/
      ————————————————————————————————————————————————————-
      ########################### Jorge’s Quest For Knowledge ##########################
      ####################
      http://JorgeQuestForKnowledge.wordpress.com/ ###################
      ————————————————————————————————————————————————————-

      Posted in Azure AD Password Protection, Windows Azure Active Directory | Leave a Comment »

      (2018-10-24) Setting/Fixing The Correct Permissions On Your ADFS Certificates And/Or On The Certificate Sharing Container

      Posted by Jorge on 2018-10-24


      Are the permissions on any of the private keys of your certificates in use by ADFS and/or the certificate sharing container screwed up? If YES, then you can use the PowerShell code below to fix those permissions for the account the ADFS Service is running under. Make sure to test this is a test environment first!

      ### Function To Permission Private Key Of Custom/Non-ADFS Managed Certificates
      Function permissionPrivateKey($certificate,$certType,$svcAccount) {
          $ace = $svcAccount,"Read,Synchronize","Allow"
          $machineKeysLocation = $ENV:ALLUSERSPROFILE + "\Microsoft\Crypto\RSA\MachineKeys\"
          $CertKeyFile = $certificate.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName
          $CertKeyFileFullPath = $MachineKeysLocation + $CertKeyFile
          $CertKeyFileACL = Get-Acl $CertKeyFileFullPath
          Write-Host "+++ RESULT +++" -ForeGroundColor Magenta
          $certSubject = $null
          $certSubject = $certificate.Subject
          Write-Host "Certificate Type……..: $certType" -ForegroundColor Yellow
          Write-Host "Certificate Subject…..: $certSubject" -ForegroundColor Yellow
          Write-Host ""
          Write-Host "Private Key Permissions (BEFORE)" -ForegroundColor Yellow
          $CertKeyFileACL.Access | FT @{n='[Account]’;e={$_.IdentityReference}},@{n='[Control]’;e={$_.AccessControlType}},@{n='[Permissions]’;e={$_.FileSystemRights}}
          $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $ace
          $CertKeyFileACL.SetAccessRule($accessRule)
          $CertKeyFileACL | Set-Acl $CertKeyFileFullPath
          $CertKeyFileACL = $null
          $CertKeyFileACL = Get-Acl $CertKeyFileFullPath
           Write-Host ""
          Write-Host "Private Key Permissions (AFTER)" -ForegroundColor Yellow
          $CertKeyFileACL.Access | FT @{n='[Account]’;e={$_.IdentityReference}},@{n='[Control]’;e={$_.AccessControlType}},@{n='[Permissions]’;e={$_.FileSystemRights}}
      }
         
      ### Determining Current ADFS Service Account
      $adfsService = Get-WmiObject win32_service -filter "name=’ADFSSRV’"
      $currentADFSServiceAccount = $adfsService.StartName

      ### Determining Database Type Being Used
      $adfsSTS = Get-WmiObject -namespace root/ADFS -class SecurityTokenService
      $configDBConnectionString = $adfsSTS.ConfigurationDatabaseConnectionString
      If ($configDBConnectionString.contains("\\.\pipe\")) {
          Write-Host ""
          Write-Host "Windows Internal Database Is Being Used" -ForegroundColor Yellow
           $dbType = "WID"
          $roleADFSServer = (Get-AdfsSyncProperties).Role
          If ($roleADFSServer -eq "SecondaryComputer") {
               Write-Host ""
              Write-Host "Running On Secondary ADFS Server" -ForegroundColor Yellow
              Function portConnectionCheck($fqdnServer,$port,$timeOut) {
                  $tcpPortSocket = $null
                  $portConnect = $null
                  $tcpPortWait = $null
                  $tcpPortSocket = New-Object System.Net.Sockets.TcpClient
                  $portConnect = $tcpPortSocket.BeginConnect($fqdnServer,$port,$null,$null)
                  $tcpPortWait = $portConnect.AsyncWaitHandle.WaitOne($timeOut,$false)
                  If(!$tcpPortWait) {
                      $tcpPortSocket.Close()
                       Return "ERROR"
                  } Else {
                      $ErrorActionPreference = "SilentlyContinue"
                      $tcpPortSocket.EndConnect($portConnect) | Out-Null
                      If (!$?) {
                          Return "ERROR"
                      } Else {
                          Return "SUCCESS"
                      }
                       $tcpPortSocket.Close()
                      $ErrorActionPreference = "Continue"
                  }
              }
              $primaryADFSServer = (Get-AdfsSyncProperties).PrimaryComputerName
              $adfsWIDIsSecondary = $true
          } Else {
              Write-Host "Running On Primary ADFS Server" -ForegroundColor Yellow
              $adfsWIDIsSecondary = $false
          }
      } Else {
          Write-Host "SQL Server Is Being Used" -ForegroundColor Yellow
          $dbType = "SQL"
      }

      ### Getting ADFS Properties And Certificates
      If ($dbType -eq "WID") {
          If ($adfsWIDIsSecondary) {
              $ports = 5985,443,80 # WinRM For Remote PowerShell, ADFS HTTPS, ADFS HTTP
              $connectionCheckOK = $true
              $ports | %{
                  $port = $null
                  $port = $_
                  $connectionResult = $null
                  $connectionResult = portConnectionCheck $primaryADFSServer $port 500
                  If ($connectionResult -eq "ERROR") {
                      $connectionCheckOK = $false
                  }
              }
              If ($connectionCheckOK) {
                  $primaryADFSServerSession = New-PSSession -ComputerName $primaryADFSServer
                  $fedSvcConfig = Invoke-Command -Session $primaryADFSServerSession -ScriptBlock {
                      $fedSvcProperties = Get-AdfsProperties
                      $fedSvcCertificates = Get-AdfsCertificate
                      Return $fedSvcProperties,$fedSvcCertificates
                  }
                  Remove-PSSession $primaryADFSServerSession
                  $fedSvcProps = $fedSvcConfig[0]
                  $fedSvcCerts = $fedSvcConfig[1]
              } Else {
                   Write-Host ""
                  Write-Host "The Primary ADFS Server IS NOT Reachable" -ForegroundColor Red
                  Write-Host "Aborting…" -ForegroundColor Red
                  Write-Host ""
                  EXIT
              }
          } Else {
              $fedSvcProps = Get-AdfsProperties
              $fedSvcCerts = Get-AdfsCertificate
           }
      }
      If ($dbType -eq "SQL") {
          $fedSvcProps = Get-AdfsProperties
          $fedSvcCerts = Get-AdfsCertificate
      }

      ### Checking If Certificate Sharing Container Has Been Configured
      If ($fedSvcProps.CertificateSharingContainer) {
          Write-Host ""
          Write-Host "Certificate Sharing Container IS Configured" -ForegroundColor Yellow
          $certSharingContainerConfigured = $true
          $certSharingContainerState = "Configured"
          $certSharingContainerDN = ($fedSvcProps.CertificateSharingContainer).ToString()
      } Else {
           Write-Host ""
          Write-Host "Certificate Sharing Container IS NOT Configured" -ForegroundColor Yellow
          $certSharingContainerConfigured = $false
          $certSharingContainerState = "NOT Configured"
          $certSharingContainerDN = "N.A."
      }

      ### Checking If Custom Certificates Are Being Used Or ADFS Managed Self-Signed Certificates For Token Signing/Encryption
      If ($fedSvcProps.AutoCertificateRollover -eq $false) {
          Write-Host ""
          Write-Host "ADFS Managed Self-Signed Certs ARE NOT Being Used" -ForegroundColor Yellow
          $adfsManagedCerts = $false
          $certManagement = "NON-ADFS Managed"
      } ElseIf ($fedSvcProps.AutoCertificateRollover -eq $true) {
          Write-Host ""
          Write-Host "ADFS Managed Self-Signed Certs ARE Being Used" -ForegroundColor Yellow
          $adfsManagedCerts = $true
          $certManagement = "ADFS Managed"
      }

      ### Displaying All The Info Gathered
      Invoke-Command -ScriptBlock {
          Write-Host ""
          Write-Host "Database Type………………………: $dbType" -ForegroundColor Yellow
          Write-Host ""
          Write-Host "Certificate Sharing Container State…..: $certSharingContainerState" -ForegroundColor Yellow
          Write-Host ""
          Write-Host "Certificate Sharing Container DN……..: $certSharingContainerDN" -ForegroundColor Yellow
          Write-Host ""
           Write-Host "Certificate Management………………: $certManagement" -ForegroundColor Yellow
          Write-Host ""
          Write-Host "Current Service Account……………..: $currentADFSServiceAccount" -ForegroundColor Yellow
          Write-Host ""
          Write-Host "Token-Signing Certificate(s)…" -ForegroundColor Yellow
          $fedSvcTokenSigningCert = $fedSvcCerts | ?{$_.CertificateType -eq "Token-Signing"}
          $fedSvcTokenSigningCert | FT Thumbprint,@{n=’Subject’;e={$_.Certificate.Subject}},@{n=’Not Before’;e={$_.Certificate.NotBefore}},@{n=’Not After’;e={$_.Certificate.NotAfter}}
          Write-Host "Token-Encryption Certificate(s)…" -ForegroundColor Yellow
          $fedSvcTokenEncryptCert = $fedSvcCerts | ?{$_.CertificateType -eq "Token-Decrypting"}
          $fedSvcTokenEncryptCert | FT Thumbprint,@{n=’Subject’;e={$_.Certificate.Subject}},@{n=’Not Before’;e={$_.Certificate.NotBefore}},@{n=’Not After’;e={$_.Certificate.NotAfter}}
          Write-Host "Service Communications / SSL Certificate…" -ForegroundColor Yellow
          $fedSvcSvcCommCert = $fedSvcCerts | ?{$_.CertificateType -eq "Service-Communications"}
          $fedSvcSvcCommCert | FT Thumbprint,@{n=’Subject’;e={$_.Certificate.Subject}},@{n=’Not Before’;e={$_.Certificate.NotBefore}},@{n=’Not After’;e={$_.Certificate.NotAfter}}
      }

      ### Setting Permissions On Private Key Of Custom Token Certificates
      If (!$adfsManagedCerts) {
          Write-Host ""
          Write-Host "Permissioning Custom Token Certificates" -ForegroundColor Yellow
          $certStoreLocation = "Cert:\LocalMachine\My"
          $fedSvcCerts | ?{$_.CertificateType -ne "Service-Communications"} | %{
              $certificateType = $null
              $certificateType = $_.CertificateType
              $certificateThumbprint = $null
              $certificateThumbprint = $_.Thumbprint
              $certificateInStore = $null
              $certificateInStore = Get-ChildItem $($certStoreLocation + "\" + $certificateThumbprint) -ErrorAction SilentlyContinue
              If ($certificateInStore -And $certificateInStore.HasPrivateKey) {
                  permissionPrivateKey $certificateInStore $certificateType $currentADFSServiceAccount
              } Else {
                   Write-Host ""
                  Write-Host "The Certificate With Thumbprint ‘$certificateThumbprint’ ($certificateType) Does Not Exist" -ForegroundColor Red
                  Write-Host "Or" -ForegroundColor Red
                  Write-Host "The Certificate With Thumbprint ‘$certificateThumbprint’ ($certificateType) Does Not Have A Private Key" -ForegroundColor Red
                  Write-Host ""
              }
          }
      }

      ### Setting Permissions On Private Key Of SSL/Service-Communication Certificate
      $fedSvcCerts | ?{$_.CertificateType -eq "Service-Communications"} | %{
          $certificateType = $null
          $certificateType = $_.CertificateType
          $certificateThumbprint = $null
          $certificateThumbprint = $_.Thumbprint
           $certificateInStore = $null
          $certificateInStore = Get-ChildItem $($certStoreLocation + "\" + $certificateThumbprint) -ErrorAction SilentlyContinue
          If ($certificateInStore -And $certificateInStore.HasPrivateKey) {
              permissionPrivateKey $certificateInStore $certificateType $currentADFSServiceAccount
          } Else {
              Write-Host ""
              Write-Host "The Certificate With Thumbprint ‘$certificateThumbprint’ ($certificateType) Does Not Exist" -ForegroundColor Red
              Write-Host "Or" -ForegroundColor Red
              Write-Host "The Certificate With Thumbprint ‘$certificateThumbprint’ ($certificateType) Does Not Have A Private Key" -ForegroundColor Red
              Write-Host ""
          }
      }

      ### If Configured Setting Permissions On Certificate Sharing Container
      ### WARNING: ADDS PowerShell Module Required!!! – Will Be Installed!
      If ($certSharingContainerConfigured) {
          Write-Host ""
          Write-Host "Certificate Sharing Container Is Configured Used" -ForegroundColor Yellow

          # Install RSAT PowerShell Tools And Load Module
          Install-WindowsFeature RSAT-AD-Tools -IncludeAllSubFeature
           Import-Module ActiveDirectory

          # Get The Certificate Sharing Container DN, Its ACL And Present The Results Of That
          $dnPathCertSharingContainer = ($fedSvcProps.CertificateSharingContainer).ToString()
          $dnPathCertSharingContainerPath = $(Join-Path "AD:\" $dnPathCertSharingContainer)
          Write-Host ""
          Write-Host "Certificate Sharing Container Permissions (BEFORE)" -ForegroundColor Yellow
          $aclCertSharingContainer = Get-Acl $dnPathCertSharingContainerPath
          $aclCertSharingContainer.Access | FT @{n='[Account]’;e={$_.IdentityReference}},@{n='[Control]’;e={$_.AccessControlType}},@{n='[Permissions]’;e={$_.ActiveDirectoryRights}}
         
          # Object Class And Inheritance Scope
          $schemaIDGUIDScopedObject = [guid]"00000000-0000-0000-0000-000000000000"
          $inheritanceScope = "All"

          # Security Principal To Assign Permissions To
          $securityPrincipalAccount = $currentADFSServiceAccount
          $securityPrincipalObject = New-Object System.Security.Principal.NTAccount($securityPrincipalAccount)

          # Define ACE
          $rightsCollection = [System.DirectoryServices.ActiveDirectoryRights]::"CreateChild","Self","WriteProperty","DeleteTree","GenericRead","WriteOwner"
          $aclType = [System.Security.AccessControl.AccessControlType]::"Allow"
          $aceDefinition = $securityPrincipalObject,$rightsCollection,$aclType,$schemaIDGUIDScopedObject,$inheritanceScope
          $accessRule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($aceDefinition)   

          # Set The New Access Rule
          $aclCertSharingContainer.AddAccessRule($accessRule)
          $aclCertSharingContainer | Set-Acl $dnPathCertSharingContainerPath

          # Get The Certificate Sharing Container ACL And Present The Results Of That
          Write-Host ""
          Write-Host "Certificate Sharing Container Permissions (AFTER)" -ForegroundColor Yellow
          $aclCertSharingContainer = Get-Acl $dnPathCertSharingContainerPath
          $aclCertSharingContainer.Access | FT @{n='[Account]’;e={$_.IdentityReference}},@{n='[Control]’;e={$_.AccessControlType}},@{n='[Permissions]’;e={$_.ActiveDirectoryRights}}
          $aclCertSharingContainer.Access | ?{$_.IdentityReference -eq $securityPrincipalAccount} | FT @{n='[Account]’;e={$_.IdentityReference}},@{n='[Control]’;e={$_.AccessControlType}},@{n='[Permissions]’;e={$_.ActiveDirectoryRights}}
          $aclCertSharingContainer.Access | ?{$_.IdentityReference -eq $securityPrincipalAccount}
      }

      Cheers,
      Jorge

      ————————————————————————————————————————————————————-
      This posting is provided "AS IS" with no warranties and confers no rights!
      Always evaluate/test everything yourself first before using/implementing this in production!
      This is today’s opinion/technology, it might be different tomorrow and will definitely be different in 10 years!
      DISCLAIMER:
      https://jorgequestforknowledge.wordpress.com/disclaimer/
      ————————————————————————————————————————————————————-
      ########################### Jorge’s Quest For Knowledge ##########################
      ####################
      http://JorgeQuestForKnowledge.wordpress.com/ ###################
      ————————————————————————————————————————————————————-

      Posted in Active Directory Federation Services (ADFS), Certificates, PowerShell | Leave a Comment »

      (2018-10-23) How Do You Know Your ADFS Server Is Lacking Permissions On Its Certificates?

      Posted by Jorge on 2018-10-23


      Even through the ADFS Service starts and everything “appears” to be right, NOTHING works! In the ADFS Admin Event Log you may see the following event

      image

      Figure 1: An Error In The ADFS Admin Event Log Referencing The Lack Of Permissions On The Private Key

      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.ArgumentNullException: Value cannot be null.
      Parameter name: certificate
          at System.IdentityModel.Tokens.X509SecurityToken..ctor(X509Certificate2 certificate, String id, Boolean clone, Boolean disposable)
          at Microsoft.IdentityServer.Service.Configuration.MSISSecurityTokenServiceConfiguration.Create(Boolean forSaml, Boolean forPassive)
          at Microsoft.IdentityServer.Service.Policy.PolicyServer.Service.ProxyPolicyServiceHost.ConfigureWIF()
          at Microsoft.IdentityServer.Service.SecurityTokenService.MSISConfigurableServiceHost.Configure()
          at Microsoft.IdentityServer.Service.Policy.PolicyServer.Service.ProxyPolicyServiceHost.Create()
          at Microsoft.IdentityServer.ServiceHost.STSService.StartProxyPolicyStoreService(ServiceHostManager serviceHostManager)
          at Microsoft.IdentityServer.ServiceHost.STSService.OnStartInternal(Boolean requestAdditionalTime)

      The solution? Fix the permissions on the private keys and restart the ADFS Service on every ADFS server where the permissions were fixed

      When the ADFS Service is finished starting your should ALWAYS see the following informational events (may be slightly different depending on the version of Windows):

      • Event ID 397 (WinHTTP Settings)
      • Event ID 349 (Administration Service)
      • Event ID 251 (For Every Attribute Store)
      • Event ID 278 (SAML Artifact)
      • Event ID 106 (For Every Authentication Provider (Multiple Times))
      • Event ID 100 (Federation Service Started Successfully)
      • Event ID 298 (Windows Hello For Business)
      • Event ID 399 (Certificate Archiving)
      • Event ID 386 (Certificate Expiration)
      • ….And Last But Not Least

      image

      Figure 2: ADFS Mentioning Everything Is Correct Regarding The ADFS Certificates

      AD FS detected that all the service certificates have appropriate access given to the AD FS service account.

      Cheers,
      Jorge

      ————————————————————————————————————————————————————-
      This posting is provided "AS IS" with no warranties and confers no rights!
      Always evaluate/test everything yourself first before using/implementing this in production!
      This is today’s opinion/technology, it might be different tomorrow and will definitely be different in 10 years!
      DISCLAIMER:
      https://jorgequestforknowledge.wordpress.com/disclaimer/
      ————————————————————————————————————————————————————-
      ########################### Jorge’s Quest For Knowledge ##########################
      ####################
      http://JorgeQuestForKnowledge.wordpress.com/ ###################
      ————————————————————————————————————————————————————-

      Posted in Active Directory Federation Services (ADFS), Certificates | Leave a Comment »

      (2018-10-22) Cloning Windows 10 Or Windows Server 2016 May Break Hybrid Azure AD Domain Join

      Posted by Jorge on 2018-10-22


      When cloning Windows computers you are basically copying everything from some source computer to one or more target computers. One of the benefits is the speed in deployment and the time you same to have to configure stuff every single time. Are there downsides? Yes, there are, at least if you do not take some risk mitigating measures. One of those is the SID of the local computer. Every time you deploy a cloned version of Windows you MUST execute SYSPREP to make the clone gets its own unique SID. If you don’t at the beginning and along the way things may appear to be correct. However, at some point in time you may find yourself with a huge headache trying to understand why something does not work or shows weird behavior.

      Recently I found another downside of cloning, that in the end can be mitigated with some post-deployment actions.

      For more info about Hybrid Azure AD Domain Join (HAADJ) please also have a look at

      I was trying to Hybrid Azure AD Domain Join (HAADJ) a AD domain joined Windows Server 2016 by logging on and waiting for the scheduled task to kick in and checking the correct Event Logs, and later on under the context of “NT AUTHORITY\SYSTEM” by running DSREGCMD.EXE /DEBUG. When running that last command I kept seeing the following error at the end:

      DsrDeviceAutoJoinFederated failed with -2146893802
      wmain: failed with error code 0x80090016.

      After some troubleshooting I discovered that Windows was a cloned deployment. One of the thing that is also cloned is the key material. The key material is in the folder “C:\ProgramData\Microsoft\Crypto\Keys” to “C:\ProgramData\Microsoft\Crypto\Keys”. The solution therefore is to get rid of the old key material and start fresh from the beginning. You can do that by running the following PowerShell commands:

      # Rename The “Keys” Folder To “KeysOLD”

      Rename-Item -Path "C:\ProgramData\Microsoft\Crypto\Keys" -NewName "KeysOLD"

      # Create A New “Keys” Folder

      New-Item -Path "C:\ProgramData\Microsoft\Crypto\Keys" -ItemType Directory

      # Copy The ACL From The “KeysOLD” Folder To The New “Keys” Folder

      Get-Acl -Path "C:\ProgramData\Microsoft\Crypto\KeysOLD" | Set-Acl -Path "C:\ProgramData\Microsoft\Crypto\Keys"

      Now retry HAADJ by rebooting the Windows computers and logging on, or executing DSREGCMD.EXE /DEBUG under the context of  “NT AUTHORITY\SYSTEM”. It should work now!

      REMARK: If you did not know it yet, you can get into the context of “NT AUTHORITY\SYSTEM” by using PSEXEC and running the following command: PSEXEC –i –s CMD.EXE

      Cheers,
      Jorge

      ————————————————————————————————————————————————————-
      This posting is provided "AS IS" with no warranties and confers no rights!
      Always evaluate/test everything yourself first before using/implementing this in production!
      This is today’s opinion/technology, it might be different tomorrow and will definitely be different in 10 years!
      DISCLAIMER:
      https://jorgequestforknowledge.wordpress.com/disclaimer/
      ————————————————————————————————————————————————————-
      ########################### Jorge’s Quest For Knowledge ##########################
      ####################
      http://JorgeQuestForKnowledge.wordpress.com/ ###################
      ————————————————————————————————————————————————————-

      Posted in Azure AD Join, Windows Azure Active Directory, Windows Client, Windows Server | 3 Comments »

      (2018-10-21) Grant, Revoke Or Get DCOM Permissions Using PowerShell

      Posted by Jorge on 2018-10-21


      Have you ever needed to script granting or revoking DCOM Permissins, or maybe just retrieving DCOM Permissions? If the answer is “Yes”, then look no further! It is a pitty there is no native PowerShell way to manage stuff like this. But, it is a good thing there are MVPs like Tony who has created a PowerShell module that does some interesting things around DCOM Permissions on Windows systems. All credits for this PowerShell module of course go to Tony as he build and owns it.

      The PowerShell Module to manage DCOM Permissions can be downloaded from here.

      Benefits:

      • No dependency on external files
      • Can change permissions on DCOM objects where Administrator doesn’t have access
      • Does not remove callback permissions (Using the Component Services GUI often does)
      • Doesn’t write temporary files during operation
      • Pure PowerShell implementation
      • Fully documented and self contained
      • No code hidden in DLL files or other compiled libraries; fully transparent

      Requirements:

      • PowerShell 4.0
      • Elevated administrative rights on local computer
      • Tested on Windows 10, Server 2012 R2, Server 2016

      Available Cmdlets:

      • Get-DCOMPermission
      • Grant-DCOMPermission
      • Revoke-DCOMPermission 

      Cheers,
      Jorge

      ————————————————————————————————————————————————————-
      This posting is provided "AS IS" with no warranties and confers no rights!
      Always evaluate/test everything yourself first before using/implementing this in production!
      This is today’s opinion/technology, it might be different tomorrow and will definitely be different in 10 years!
      DISCLAIMER:
      https://jorgequestforknowledge.wordpress.com/disclaimer/
      ————————————————————————————————————————————————————-
      ########################### Jorge’s Quest For Knowledge ##########################
      ####################
      http://JorgeQuestForKnowledge.wordpress.com/ ###################
      ————————————————————————————————————————————————————-

      Posted in Windows Client, Windows Server | Leave a Comment »

       
      %d bloggers like this: