PSKerb.psm1
#region Globals $script:KEY_PATH = "Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters" class EncryptionType { [int]$Mask [int]$Value [string]$Name EncryptionType([int]$m, [int]$v, [string]$n) { $this.Mask = $m $this.Value = $v $this.Name = $n } [bool] EnabledInMask([int]$mask) { return ($mask -band $this.Mask) -eq $this.Mask } } class KerbRegDwordSetting { [string]$Name hidden [int]$Value hidden [int]$DefaultValue hidden [bool]$IsDefined hidden [scriptblock]$Callback [string]$Setting hidden [void] Init($name, $defaultValue, $callback) { $this.Name = $name $this.DefaultValue = $defaultValue $this.Callback = $callback $this.IsDefined = $false $this.Setting = "" } [void] Update() { try { $this.Value = Get-ItemPropertyValue -Path $script:KEY_PATH -Name $this.Name -ErrorAction Stop $this.IsDefined = $true } catch { Write-Verbose "Exception while processing registry key $script:KEY_PATH with value $($this.Name)`n$_)" $this.Value = $this.DefaultValue $this.IsDefined = $false } if ($null -ne $this.Callback) { $this.Setting = $this.Callback.Invoke($this.Value) } else { $this.Setting = $this.Value } } KerbRegDwordSetting($name, $defaultValue, $callback) { $this.Init($name, $defaultValue, $callback) } KerbRegDwordSetting($name, $defaultValue) { $this.Init($name, $defaultValue, $null) } [pscustomobject] Display([bool]$detailed) { $obj = [pscustomobject]@{ Name = $this.Name Setting = $this.Setting } if ($detailed) { Add-Member -InputObject $obj -Name "Value" -Value $this.Value Add-Member -InputObject $obj -Name "DefaultValue" -Value $this.DefaultValue Add-Member -InputObject $obj -Name "IsDefined" -Value $this.IsDefined Add-Member -InputObject $obj -Name "IsDefault" -Value $this.Value -eq $this.DefaultValue } return $obj } } #region definitions $script:DES_CRC = [EncryptionType]::new(0x1, 1, "DES-CRC") $script:DES_MD5 = [EncryptionType]::new(0x2, 3, "DES-MD5") $script:RC4 = [EncryptionType]::new(0x4, -128, "RC4") $script:AES128 = [EncryptionType]::new(0x8, 17, "AES128-SHA96") $script:AES256 = [EncryptionType]::new(0x10, 18, "AES256-SHA96") $script:AES_SK = [EncryptionType]::new(0x20, 18, "AES-SK") $script:AES128_SHA2 = [EncryptionType]::new(0x40, 19, "AES128-SHA256") $script:AES256_SHA2 = [EncryptionType]::new(0x80, 20, "AES256-SHA384") $script:ETYPES = ( $script:DES_CRC, $script:DES_MD5, $script:RC4, $script:AES128, $script:AES256, $script:AES_SK, $script:AES128_SHA2, $script:AES256_SHA2 ) $script:KEY_SET = [KerbRegDwordSetting]::new("SupportedEncryptionTypes", 0x1c, { param([int]$mask) $etypes_string = "" foreach ($etype in $script:ETYPES) { if ($etype.EnabledInMask($mask)) { if (-not [string]::IsNullOrEmpty($etypes_string)) { $etypes_string += ", " } $etypes_string += $etype.Name } } if ([string]::IsNullOrEmpty($etypes_string)) { $etypes_string = "None" } return $etypes_string.TrimEnd() }) $script:KEY_SKEWTIME = [KerbRegDwordSetting]::new("SkewTime", 5, { return "$args minutes" }) $script:KEY_LOGLEVEL = [KerbRegDwordSetting]::new("LogLevel", 0) $script:KEY_MAXPACKETSIZE = [KerbRegDwordSetting]::new("MaxPacketSize", 1465, { return "$args bytes" }) $script:KEY_STARTUPTIME = [KerbRegDwordSetting]::new("StartupTime", 120, { return "$args seconds" }) $script:KEY_KDCWAITTIME = [KerbRegDwordSetting]::new("KdcWaitTime", 10, { return "$args seconds" }) $script:KEY_KDCBACKOFFTIME = [KerbRegDwordSetting]::new("KdcBackoffTime", 10, { return "$args seconds" }) $script:KEY_KDCSENDRETRIES = [KerbRegDwordSetting]::new("KdcSendRetries", 3) $script:KEY_DEFAULTENCRYPTIONTYPE = [KerbRegDwordSetting]::new("DefaultEncryptionType", 18, { param([int]$value) foreach ($etype in $script:ETYPES) { if ($etype.Value -eq $value) { return $etype.Name } } return "None" }) $script:KEY_FARKDCTIMEOUT = [KerbRegDwordSetting]::new("FarKdcTimeout", 10, { return "$args minutes" }) $script:KEY_NEARKDCTIMEOUT = [KerbRegDwordSetting]::new("NearKdcTimeout", 30, { return "$args minutes" }) $script:KEY_STRONGLYENCRYPTDATAGRAM = [KerbRegDwordSetting]::new("StronglyEncryptDatagram", 1, { return $args -eq 1 }) $script:KEY_MAXREFERRALCOUNT = [KerbRegDwordSetting]::new("MaxReferralCount", 6) $script:KEY_MAXTOKENSIZE = [KerbRegDwordSetting]::new("MaxTokenSize", 48000) $script:KEY_SPNCACHETIMEOUT = [KerbRegDwordSetting]::new("SpnCacheTimeout", 15, { return "$args minutes" }) $script:KEY_S4UCACHETIMEOUT = [KerbRegDwordSetting]::new("S4UCacheTimeout", 15, { return "$args minutes" }) $script:KEY_S4UTICKETLIFETIME = [KerbRegDwordSetting]::new("S4UTicketLifetime", 15, { return "$args minutes" }) $script:KEY_RETRYPDC = [KerbRegDwordSetting]::new("RetryPdc", 0, { if ($args -ne 0) { "True" } else { "False" } }) $script:KEY_REQUESTOPTIONS = [KerbRegDwordSetting]::new("RequestOptions", 0x00010000, { return "0x{0:x}" -f $args }) $script:KEY_CLIENTIPADDRESSES = [KerbRegDwordSetting]::new("ClientIpAddresses", 0, { if ($args -ne 0) { "True" } else { "False" } }) $script:KEY_TGTRENEWALTIME = [KerbRegDwordSetting]::new("TgtRenewalTime", 600, { return "$args seconds" }) $script:KEY_ALLOWTGTSESSIONKEY = [KerbRegDwordSetting]::new("AllowTgtSessionKey", 0, { if ($args -ne 0) { "True" } else { "False" } }) $script:KEYS = ( $script:KEY_SET, $script:KEY_SKEWTIME, $script:KEY_LOGLEVEL, $script:KEY_MAXPACKETSIZE, $script:KEY_STARTUPTIME, $script:KEY_KDCWAITTIME, $script:KEY_KDCBACKOFFTIME, $script:KEY_KDCSENDRETRIES, $script:KEY_DEFAULTENCRYPTIONTYPE, $script:KEY_FARKDCTIMEOUT, $script:KEY_NEARKDCTIMEOUT, $script:KEY_STRONGLYENCRYPTDATAGRAM, $script:KEY_MAXREFERRALCOUNT, $script:KEY_MAXTOKENSIZE, $script:KEY_SPNCACHETIMEOUT, $script:KEY_S4UCACHETIMEOUT, $script:KEY_S4UTICKETLIFETIME, $script:KEY_RETRYPDC, $script:KEY_REQUESTOPTIONS, $script:KEY_CLIENTIPADDRESSES, $script:KEY_TGTRENEWALTIME, $script:KEY_ALLOWTGTSESSIONKEY ) #endregion #region Functions function Get-KerbConfig { <# .SYNOPSIS Get-KerbConfig displays the current Windows Kerberos client registry based configurations. .DESCRIPTION Get-KerbConfig reads the current registry values for the Windows Kerberos client to determine what the state of the Kerberos client is. These configurations are based around the publicy documented keys here: https://learn.microsoft.com/en-us/troubleshoot/windows-server/windows-security/kerberos-protocol-registry-kdc-configuration-keys .PARAMETER Configurations A list of configuration names to be displayed. Otherwise, all configurations will be displayed. .PARAMETER Detailed Display the current unparsed setting along with if the configuration has been adjusted from the default value. .EXAMPLE Get-KerbConfig Name Setting ---- ------- SupportedEncryptionTypes RC4, AES128-SHA96, AES256-SHA96 SkewTime 5 minutes LogLevel 0 MaxPacketSize 1465 bytes StartupTime 120 seconds KdcWaitTime 10 seconds KdcBackoffTime 10 seconds KdcSendRetries 3 DefaultEncryptionType AES256-SHA96 FarKdcTimeout 10 minutes NearKdcTimeout 30 minutes StronglyEncryptDatagram 1 MaxReferralCount 6 MaxTokenSize 48000 SpnCacheTimeout 15 minutes S4UCacheTimeout 15 minutes S4UTicketLifetime 15 minutes RetryPdc False RequestOptions 0x10000 ClientIpAddresses False TgtRenewalTime 600 seconds AllowTgtSessionKey False .EXAMPLE Get-KerbConfig -Detailed Name Setting Value DefaultValue IsDefined IsDefault ---- ------- ----- ------------ --------- --------- SupportedEncryptionTypes RC4, AES128-SHA96, AES256-SHA96 28 28 False True SkewTime 5 minutes 5 5 False True LogLevel 0 0 0 False True MaxPacketSize 1465 bytes 1465 1465 False True StartupTime 120 seconds 120 120 False True KdcWaitTime 10 seconds 10 10 False True KdcBackoffTime 10 seconds 10 10 False True KdcSendRetries 3 3 3 False True DefaultEncryptionType AES256-SHA96 18 18 False True FarKdcTimeout 10 minutes 10 10 False True NearKdcTimeout 30 minutes 30 30 False True StronglyEncryptDatagram 1 1 1 False True MaxReferralCount 6 6 6 False True MaxTokenSize 48000 48000 48000 False True SpnCacheTimeout 15 minutes 15 15 False True S4UCacheTimeout 15 minutes 15 15 False True S4UTicketLifetime 15 minutes 15 15 False True RetryPdc False 0 0 False True RequestOptions 0x10000 65536 65536 False True ClientIpAddresses False 0 0 False True TgtRenewalTime 600 seconds 600 600 False True AllowTgtSessionKey False 0 0 False True #> [CmdletBinding(DefaultParameterSetName = "All")] param( [Parameter(ValueFromPipeline, ParameterSetName = "Configurations", Mandatory)] [ValidateSet( "SupportedEncryptionTypes", "SkewTime", "LogLevel", "MaxPacketSize", "StartupTime", "KdcWaitTime", "KdcBackoffTime", "KdcSendRetries", "DefaultEncryptionType", "FarKdcTimeout", "NearKdcTimeout", "StronglyEncryptDatagram", "MaxReferralCount", "MaxTokenSize", "SpnCacheTimeout", "S4UTicketLifetime", "RetryPdc", "RequestOptions", "ClientIpAddresses", "TgtRenewalTime", "AllowTgtSessionKey")] [string[]]$Configurations, [Parameter(ParameterSetName = "All")] [switch]$All, [Parameter()] [switch]$Detailed ) begin { $originalPreference = $null if ($PSCmdlet.MyInvocation.BoundParameters["Verbose"]) { $originalPreference = $VerbosePreference $VerbosePreference = 'Continue' } } process { $selectedKeys = if ($PSCmdlet.ParameterSetName -eq "All") { $script:KEYS } else { $script:KEYS | Where-Object { $Configurations.Contains($_.Name) } } $selectedKeys | ForEach-Object { $_.Update() $_.Display($Detailed) } } end { if ($null -ne $originalPreference) { $VerbosePreference = $originalPreference } } } Export-ModuleMember -Function 'Get-KerbConfig' #end region |