Control Extended Protection for Authentication using Security Policy

Microsoft has introduced additional security measures for authentication known as Extended Protection for Authentication, also known as channel binding token (CBT). Extended protection can cause a variety of interoperability issues including but not limited to:

  • Windows clients that support channel binding fail to be authenticated by a non-Windows Kerberos server
  • NTLM authentication failures from Proxy servers
  • NTLM authentication failures from non-Windows NTLM servers
  • NTLM authentication failures when there is a time difference between the client and DC or workgroup server

Note: Read more about Extended Protection for Authentication in Microsoft Knowledge base article 968389 and MSDN.

Administrators may want to control the state of Extended Protection to multiple client computers. This can be accomplished using security policy. Security policy is the most appropriate solution to distribute the registry setting that controls Extended Protection for Authentication because the setting is stored under the LSA key in HKEY_LOCAL_MACHINE. Also, distributing the setting using security policy increases the chance of the desired settings winning all conflicts because, by default, security settings always apply during Group Policy Processing. Once the policy is applied, any user or application that changes the registry location will be reverted back to the desired configuration during the next application of security policy.

Add the policy setting to Security Policy settings

The Extended Protection for Authentication policy setting must be added to Security Policy editor to include the policy setting in Group Policy. To accomplish this:

==== Start copy after this line ====

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SeCEdit\Reg Values\MACHINE/System/CurrentControlSet/Control/Lsa/SuppressExtendedProtection] 
“ValueType”=dword:00000004 
“DisplayType”=dword:00000003 
“DisplayName”=”Network Security: Extended Protection for Authentication” 
“DisplayChoices”=hex(7):30,00,7c,00,45,00,6e,00,61,00,62,00,6c,00,65,00,64,00,\ 
  00,00,33,00,7c,00,44,00,69,00,73,00,61,00,62,00,6c,00,65,00,64,00,00,00,00,\ 
  00

==== Stop copy before this line ====
  1. Copy the above text.
  2. Open Notepad and paste the text from step one into Notepad.
  3. Click File and then Click Save As.
  4. In the File name box, type secpoladd.reg.
  5. In the Save as type list, click All Files. Remember the path to which the file is saved.
  6. Click Save and close Notepad.
  7. Locate the saved file from the path in step
  8. Double-click the secpoladd.reg file. Click Yes to the Registry Editor dialog box.

It is only required to modify the security editor on the computer used to manage Group Policy. This allows the Extended Protection for Authentication policy setting to be included in a Group Policy object. Extending this security setting to other computers is not required for client computers to receive the security setting.

Include the Extended Protection for Authentication policy setting in Group Policy

00extendedProtection

With the security editor extended, you can now include the security setting within a Group Policy object. To do this:

  1. Using GPMC, edit the Group Policy object that is to contain the security setting.
  2. Navigate to Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\Security Options.
  3. In the right pane of the MMC, scroll through the list of security settings to locate Network Security: Extended Protection for Authentication. Double-click the security setting.
  4. Select Define this policy setting. Choose the desired configuration from the list and click OK.
  5. Close the Group Policy object.
  6. The Group Policy object now contains the security policy setting. Use GPMC to deploy the GPO to clients as needed.

Conclusion

Improving security always poses a risk with application compatibility. The long term solution is to determine why applications no longer work when security in heightened. A short-term solution during the investigation may be to reduce security to allow the application to work, pending the results of the investigation. Controlling this using Group Policy helps manage the setting for the enterprise.

— Mike Stephens

What occurs when the Security Group Policy CSE encounters a null DACL

The Group Policy security client side extension can distribute security descriptors on files and registry keys. This extension is difficult to troubleshoot because it is considerably durable when it comes to failures. In most situations, it completes processing, but not without leaving behind the ever popular SCECLI 1202 event.

Event Type: Warning
Event Source: SceCli
Event Category: None
Event ID: 1202
Date: 21/09/1999
Time: 18:15:14
User: N/A
Computer: MachineName
Description:
Security policies are propagated with warning. 0x4b8 : An extended error occurred. Please look for more details in TroubleShooting section in Security Help.

You can start your troubleshooting by following Microsoft Knowledge base article 324383 Troubleshooting SCECLI 1202 Events. Unfortunately, the return code 0x4b8 is ambiguous because it serves as generic alert of a nondeterministic problem– it means something happened; but what happened was not catastrophic. Therefore, the security extension keeps processing,

NOTE: The knowledge base article uses the command secedit /refreshpolicy machine_policy /enforce. For Windows XP and later use the command gpupdate /force.

Security extension processing has many facets. Using the previously mentioned knowledge base article should help you understand the general area within security processing that is failing. However, it’s not enough evidence to confirm Professor Plum, did it in the library with the candlestick. But you should be able to determine the misbehaving portion of security processing from the winlogon.log. Scan the log file for the Configure File Security… section. It may look like:

—-Configure File Security…
Configure c:\.
File Security configuration was completed with one or more errors.

If you suspect your file system security settings as the culprit, then you may want to use Process Monitor to help further determine where in the failure occurs. It’s difficult to provide prescriptive guidance when there are many reasons for the resulting error. However, one scenario where we see this problem is in the case of a nested file or folder containing a null discretionary access control list (DACL).

NOTE: You can read more about the differences between null and empty discretionary access control list by reading the Null and Empty DACLs ASKDS blog post.

The scenario we encounter usually involves using the security policy extension to assign file permissions to a particular folder. Files and folders residing beneath the targeted folder inherit the permissions that are assigned to the targeted folder, unless that file or folder specifically blocks inheritance. If one of the underlying files or folders beneath the targeted folder contains a null DACL, then the security extension halts processing the remainder of file system security. Furthermore, an entry appears in the winlogon.log stating the configuration completed with one or more errors and, an event with the event ID 1202 appears is recorded to the event log. The return code reported in the event log is 0x4b8. Lastly, the winlogon.log file does not contain information on the file or folder responsible for stopping the process. The parent folder is the only item listed in the log. This means that one or more files or folder beneath the folder listed in the log file is responsible for halting security processing. The problem now is how to identify those files or folders. But, let’s explain why security processing halts.

Why a null DACL halts file security Group Policy processing

I previously mentioned that permissions we assign to folders through security policy processing propagate to all files and folders hosted within the targeted folder. Propagating security is known as inheritance, where a file or folder beneath a folder receives subset of the permissions from the containing folder. Windows must calculate the subset of permissions to apply to files and folders beneath the targeted folder. Windows derives these permissions by combining permission from the targeted folder and the file or folder beneath the targeted folder. Permission from the targeted folder are known as inherited permissions. Permissions on the file or folder residing in the targeted folder are explicit permissions. The problem with security processing occurs when the file or folder residing in the targeted folder contains a null DACL. Explicitly, this file or folder does not have any permissions. So Windows cannot determine how to propagate inherited permissions to the object because the object itself does not actually have permissions ( see ASKDS blog post Null and Empty DACLs).

More on inheritance

The security extension must compute inheritance. Computing inheritance, is essentially asking the security extension to figure out how to add permissions from the parent object to the a child object that does not have room to store permissions. This would require the security extension to make arbitrary decision on intent. Is the null DACL on purpose? When does the extension observe the null DACL and when does it not? These are a few reasons why the security extension halts permission processing when it attempts to propagate inherited permissions after encountering a null DACL; it is not clear what the resulting permissions should be. Therefore, the security extension halts file security processing and moves forward with the next phase of Group Policy security processing. The recorded event is a warning, not an error. It is a warning because Group Policy security processing processed as a whole– meaning none of the events that occur were catastrophic to the entire processing phase. However, one or more subcomponents did experience errors.

What to do

Detecting a null DACL is challenging. The Windows ACL editor interpret a null DACL for you; so your unaware if the DACL is null, or Everyone has Full Control. Windows includes CACLS.EXE, which reports if permissions are not set. This is an effective way to determine a null DACL exists but, you must have an idea of the file or folder containing the null DACL.

00commandPrompt

Identifying the a nested file or folder with a null DACL within a deep folder structure is difficult. Manually investigating these files or folders is not practical. Fortunately, ADSI provides a security descriptor interface we can use through scripting to recursively search folders, sub-folders, and files that may have a null DACL. Below is a sample script that can be copied and pasted into a text document.

‘========================================================================== 
‘ 
‘ VBScript Source File 
‘ 
‘ NAME: CheckNullDacl.vbs 
‘ 
‘ AUTHOR: Mike Stephens , Microsoft Corporation 
‘ DATE  : 7/15/2003 
‘ 
‘ COMMENT: 
‘ 
‘========================================================================== 
‘  Microsoft provides programming examples for illustration only, without warranty either expressed or 
‘  implied, including, but not limited to, the implied warranties of merchantability and/or fitness for a 
‘  particular purpose.  This sample assumes that you are familiar with the programming language being 
‘  demonstrated and the tools used to create and debug procedures. Microsoft support professionals 
‘  can help explain the functionality of a particular procedure, but they will not modify these examples 
‘  to provide added functionality or construct procedures to meet your specific needs. 
‘ =============================================================================

Option Explicit 
Const ADS_PATH_FILE     = 1 
Const ADS_SD_FORMAT_IID = 1 
Const SE_DACL_PRESENT = &h4 
Const Dbg = False 


Dim oArgs : Set oArgs = WScript.Arguments

If Not (oArgs.Count >= 1) Then  
        WScript.Quit(0) 
End If

WScript.Echo VbCrLf & “Recursivly searching “ & oArgs.Unnamed(0) & ” for NULL DACLs…” & vbCr

SearchSDsInFolder oArgs.Unnamed(0)

WScript.Echo VbCrLf & “-=[Complete]=-“ & VbCrLf

WScript.Quit(0)

Sub IsNullDacl(fileArg, bFolder) 
        Dim fso : Set fso = CreateObject(“Scripting.FileSystemObject”) 
        Dim sdUtil  : Set sdUtil = CreateObject(“ADsSecurityUtility”) 
        Dim sd :  Set sd = CreateObject(“SecurityDescriptor”) 
        Dim dacl        

        Dim sdControl, sdObject, DaclAceCount

        If(bFolder) = False Then  
                If(fso.FileExists(fileArg)) = False Then 
                        Exit Sub 
                Else 
                        Set sdObject = fso.GetFile(fileArg) 
                End If 
        Else 
                If(fso.FolderExists(fileArg)) = False Then 
                        Exit Sub 
                Else 
                        Set sdObject = fso.GetFolder(fileArg) 
                End If 
        End If 

        Set sd = sdUtil.GetSecurityDescriptor( sdObject.Path, ADS_PATH_FILE, ADS_SD_FORMAT_IID)       

        ‘  Get the SD Control 
        sdControl = sd.Control               

        ‘  Get the SD DACL  
        Set dacl = sd.DiscretionaryAcl 
        On Error Resume Next 
                DaclAceCount = dacl.AceCount 
                If Err.Number = 424 Then  
                        DaclAceCount = –1 
                        Err.Clear  
                End If  
        On Error GoTo 0

        If(sdControl And SE_DACL_PRESENT  SE_DACL_PRESENT) Then  
                WScript.Echo “- Null DACL detected on “ & cStr(sdObject.Path) & “.” 
                Exit Sub 
        ElseIf(DaclAceCount = -1) Then 
                WScript.Echo “- Null DACL detected on “ & cStr(sdObject.Path) & “.” 
                Exit Sub 
        Else 
                DebugPrint “Processed “ & cStr(sdObject.Path) 
        End If 
End Sub

Sub SearchSDsInFolder( folderArg) 
        Dim fso : Set fso = CreateObject(“Scripting.FileSystemObject”) 
        Dim flder, folder, folderCollection 
        Dim file, fileCollection

        Set flder = fso.GetFolder(folderArg)

        If(flder.SubFolders.Count > 0) Then  
                Set folderCollection = flder.SubFolders   
                For Each folder In folderCollection 
                        SearchSDsInFolder(folder) 
                Next 
        End If

        IsNullDacl flder.Path, true

        Set fileCollection = flder.Files 
        For Each file In fileCollection 
                Dim f : Set f = fso.GetFile(file) 
                IsNullDacl file.Path, False 
        Next
End Sub

Sub DebugPrint( text) 
        If( Dbg = True) Then  
                WScript.Echo text & vbCr 
        End If 
End Sub

Use cscript.exe to start the script. Provide a single argument when starting the script. This argument is the folder at which the search for null DACLs begins. The search is recursive; therefore, it searches all nested folders and files. Files or folders identified as having a null DACL are printed to the screen.

 

— Mike Stephens

Deploying Legal Notices to domain computers using Group Policy

Every so often, I’ll talk with a customer wanting to deploy a legal notice to their workstations using Group Policy. Sounds simple, right? Well, it is actually a little tricky to make the legal notice work correctly. Here is a solution that I share with customers that want to do this and have it look right.

It’s a natural assumption to have this done through Group Policy. Every computer in the domain applies it—it makes the job easy. Searching the Microsoft Knowledgebase does yield a few results—here is one.

310430 How to configure Windows Server 2003 to display a message when users log on
http://support.microsoft.com/default.aspx?scid=kb;EN-US;310430

The following shows the security policy setting that helps us accomplish this task. So, we follow the article and view the results.00-legal

NOTE: These examples are from a computer running Windows Vista Service Pack 1 with Remote Server Administration Tools. However, you can use Windows Server 2003 or Windows XP with the Group Policy Management Console (GPMC) to accomplish these results.

Now, notice our Legal Notice on a Windows Vista SP1 computer and on Windows Server 2003 computer.01-legal

02-legal

Where is the formatting? How quickly we go from pretty to… “not so pretty”. There’s no way we are going to let the legal department see this. We have to fix it. But first, let’s briefly explain why this is happening.

This problem originates from Windows NT 4; when we added Legal Notice Text to the operating system. At that time, it was a single string and did not support carriage returns. We made several attempts to change this behavior shortly after Windows 2000. Interestingly enough, those changes resulted in using a comma (,) as a delimiter for the carriage return. Kinda cool huh?…. Not!

Eight years later, legal council craft very concise legal goo—which just might have a few commas included within the text. Then, administrators would have to enclose grammatical commas in quotation marks so Windows would not parse it as a carriage return. That didn’t work well.

In Windows Server 2003, we changed the editor to accept a carriage return; now allowing you to format your text within the policy, as we did in the example. Well, that only solves the comma problem because there was not a change on how Windows parses the strings. Windows now inserts the commas and quotes for you when it writes the policy setting. And, as you can see in our example; we started with two paragraphs or more and ended with a single blob of text in window. Lastly, this behavior has not changed with Windows Server 2008 or Windows Vista Service Pack 1. So—how do I format this text?

You need to use a script to have your legal notice text appear properly formatted. Figure 4 shows a script you can use in a computer startup script (not a user logon script). The script writes the legal notice text to the policy registry key—just as if it were applied using the security policy settings. But, the script allows you to keep your formatting.

Here is the code for the script. Copy and paste this code into a text file. Be sure to save the text file with a .vbs extension or it will not run correctly. Each command should appear on its own line (no text wrapping) as some of the text in the example is wrapped for readability.

‘=========================================================================
‘
‘ VBScript Source File —
‘
‘ NAME: legal.vbs
‘
‘ AUTHOR: Mike Stephens , Microsoft Corporation
‘
‘ DATE: 11/26/2007
‘
‘ COMMENT: sample computer startup script to deploy legalcaption and legaltext
‘

‘ ==========================================================================
set wShell = CreateObject(“Wscript.Shell”)

strLegalCaption = “Legal Notice”Const POLICY_KEY = “HKLM\Software\Microsoft\Windows\CurrentVersion\policies\system\”

Const LEGAL_CAPTION_VALUENAME = “legalnoticecaption”

Const LEGAL_TEXT_VALUENAME = “legalnoticetext”strLegalText = “”strLegalText = strLegalText & “The easiest way is to insert the entire paragraph on one

line, between the quotation marks.” & vbcrlf &vbcrlf

‘ Copy the line above and repeat for each paragraph in the legal notice.
‘ Remember it is best to limit your notice to two paragraph that contain no more than 4
‘ sentences.

wShell.RegWrite POLICY_KEY & LEGAL_CAPTION_VALUENAME, strLegalCaption, “REG_SZ”
WShell.RegWrite POLICY_KEY & LEGAL_TEXT_VALUENAME, strLegalText, “REG_SZ”

You’ll want to modify the sample code from Figure 4 to include your legal notice. Let me explain the script and which part requires your modifications.

Line 1: set wShell = CreateObject(“Wscript.Shell”)

This line creates a Windows Scripting Host shell object. The script uses method (or function) from the shell object to write to the registry.

Line 2: strLegalCaption = “Legal Notice”

Line 2 creates a variable named strLegalCaption and assigns the text Legal Notice to the variable. This is the text Windows uses for the title of the legal notice dialog box, which appears when the user presses CTRL+ALT+DEL.

Line 3-5:

Const POLICY_KEY = “HKLM\Software\Microsoft\Windows\CurrentVersion\policies\system\”
Const LEGAL_CAPTION_VALUENAME = “legalnoticecaption”
Const LEGAL_TEXT_VALUENAME = “legalnoticetext”

These lines create what is called a constant. Constants mean just that- they remain constant—their values cannot change; unlike the values of a variable, which can change. Line 3 is representative of the registry key location to which the script writes. Line 4 holds the registry value name for the legal caption (title of the dialog box) while line 5 holds the value of the legal text (message in the dialog box). Constants work similarly to search and replace features found in text editors and word processors. When Windows runs the script, it looks at the constants declared in the script and then searches the remainder of the script for those words which are designated as constants. It then replaces the word with the assigned value. Then, Windows continues running the script.

Line 6: strLegalText = “”

Line 6 creates a variable named strLegalText and assigns and empty string to the variable. The is equivalent to a blank line (without a carriage return).

Line 7:

strLegalText = strLegalText & “The easiest way is to insert the entire paragraph on one
line, between the quotation marks.” & vbcrlf & vbcrlf

This line is the important line. This line defines the text of your legal notice ( the text appearing in the dialog box). The registry value name LegalNoticeText is a single string value. Therefore, the script must concatenate your entire legal text notice into one line of text, to include carriage returns.

The first part of line 7 shows strLegalText = StrLegalText &. This command phrase handles concatenating your paragraphs into a single line of text; so we can write it into the single string registry value. The next phrase in the script is between the quotation marks. This represents the first paragraph of your legal notice. You’ll want to paste the entire paragraph between the quotation marks. The best way to do this is paste your paragraph into notepad ensuring that word wrap is off (click Format from the menu to ensure there is not a check next to Word Wrap).

Position the cursor to the end of the first line. Use the delete key to move the text on the next to the current line. Be sure to keep your spaces. Follow this process until the entire paragraph is on one line (you’ll more than likely have to scroll to the right. Make sure you have an opening and closing quotation marks. It is likely your script will fail if the command is not on a single line.

NOTE: Quotation mark (“) represents the beginning and end of string when using Vbscript. Any alpha-numeric characters between the quotation marks, including spaces is included in the string—just like if you were typing a long file name as an argument for a command line application. Be certain your legal text does not include any quotation marks. If possible, you single quote marks (‘).

Copy and paste your original line 7 and repeat the above for each paragraph you want included in your legal text. Things to look for are:

  • Inserting quotation marks between the beginning and ending quotation marks.
  • The entire command is not on a single line
  • You keep the & vbcrlf & vbcrlf immediately after the ending quotation mark at the end of each line that represents a paragraph in your legal text.

My legal text notice in this example is three paragraphs with the last paragraph being a single sentence. Therefore, lines 7-9 will look similar for my example script.

strLegalText = strLegalText & ” Alle Menschen sind frei und gleich an Würde und Rechten geboren. Sie sind mit Vernunft und Gewissen begabt und sollen einander im Geist der Brüderlichkeit begegnen.” & vbcrlf & vbcrlf
strLegalText = strLegalText & ” Alle Menschen sind frei und gleich an Würde und Rechten geboren. Sie sind mit Vernunft und Gewissen begabt und sollen einander im Geist der Brüderlichkeit begegnen.” & vbcrlf & vbcrlf
strLegalText = strLegalText & ” Alle Menschen sind frei und gleich an Würde und Rechten geboren.” & vbcrlf & vbcrlf

Line 8, 9 (Sample script in Figure 4)

wShell.RegWrite POLICY_KEY & LEGAL_CAPTION_VALUENAME, strLegalCaption, “REG_SZ”
WShell.RegWrite POLICY_KEY & LEGAL_TEXT_VALUENAME, strLegalText, “REG_SZ”

These two lines do all the work. Both lines use the Windows Scripting Host shell object to write to the registry of the local computer. This is accomplished using the RegWrite method. The first parameter to the RegWrite method is the full registry path (hive and value name). The second parameter is the value the script writes into the value name. The last parameter is the data type if the value name—in this case both value are strings, which are REG_SZ data types.

Line 8 uses the POLICY_KEY constant and the LEGAL_CAPTION_VALUENAME constant to build the path to which the scripts writes. StrLegalCaption is the variable we used to hold the value of the legal caption. Line 9 uses the POLICY_KEY constant and the LEGAL_TEXT_VALUENAME constant to build the path to which the script writes. StrLegalText is the variable we used to hold the value of the legal text.

Below is the example script created for contoso.com’s legal text notice, which is based on the sample script from Figure 4.

‘=========================================================================
‘
‘ VBScript Source File —
‘
‘ NAME: legal.vbs
‘
‘ AUTHOR: Mike Stephens , Microsoft Corporation
‘
‘ DATE: 11/26/2007
‘
‘ COMMENT: sample computer startup script to deploy legalcaption and legaltext
‘
‘ ==========================================================================set wShell = CreateObject(“Wscript.Shell”)

strLegalCaption = “Legal Notice”Const POLICY_KEY = “HKLM\Software\Microsoft\Windows\CurrentVersion\policies\system\”

Const LEGAL_CAPTION_VALUENAME = “legalnoticecaption”

Const LEGAL_TEXT_VALUENAME = “legalnoticetext”strLegalText = “”strLegalText = strLegalText & ” Alle Menschen sind frei und gleich an Würde und Rechten geboren. Sie sind mit Vernunft und Gewissen begabt und sollen einander im Geist der Brüderlichkeit begegnen.” & vbcrlf & vbcrlf

strLegalText = strLegalText & ” Alle Menschen sind frei und gleich an Würde und Rechten geboren. Sie sind mit Vernunft und Gewissen begabt und sollen einander im Geist der Brüderlichkeit begegnen.” & vbcrlf & vbcrlf

strLegalText = strLegalText & ” Alle Menschen sind frei und gleich an Würde und Rechten geboren.” & vbcrlf & vbcrlf

‘ Copy the line above and repeat for each paragraph in the legal notice.
‘ Remember it is best to limit your notice to two paragraph that contain no more than 4
‘ sentences.

wShell.RegWrite POLICY_KEY & LEGAL_CAPTION_VALUENAME, strLegalCaption, “REG_SZ”
WShell.RegWrite POLICY_KEY & LEGAL_TEXT_VALUENAME, strLegalText, “REG_SZ”

If you can, disable your existing Group Policy object that contains your legal text notice security policy settings. Now, create a new Group Policy object and assign this at the level appropriate for your environment. Configure this GPO with a computer startup script and include your script. Refresh Group Policy and then logoff your workstation. Press CTRL+ALT+DEL.

03-legal

– Mike Stephens