Protect Your Windows Network: From Perimeter to Data

Access Control Lists

For most of the history of computing, ACLs have been the principal means of verifying and enforcing authorization to resources and data. After you have identified and authenticated yourself, some mechanism (tokens, tickets, or similar) authorizes you against an ACL and either permits or denies access. And for the most part, ACLs have worked wellat least until the advent of portable computing.

Types of Access Control Lists

There are three types of ACLs:

An MACL is a system-enforced ACL that even the administrator cannot modify. It is not used in most general-purpose operating systems. Rather, it is a core component of a multilevel security (MLS) operating system. MLS systems are not in common use today, although there have been many variants produced in the past. They might use an MACL, for instance, to enforce data classifications, such as Top Secret, Confidential, and so on. The administrator cannot modify this ACL. As soon as something is classified , the system automatically enforces access from users based on their classification rating and the operation they are performing. Since Windows does not support this type of ACL, we do not consider it in the rest of this chapter. If you want to learn more about them, pick up just about any textbook on security or take a Certified Information Systems Security Professional (CISSP) review seminar. In spite of the fact that no off-the-shelf systems today provide this functionality, both devote significant amount of time to the topic.

A DACL is what we typically mean when we refer to an ACL. It is an ACL that is at the discretion of the data owner, the administrator, or both. A DACL is composed of access control list entries (ACEs). Each ACE defines some permission that is allowed or not allowed to some user or group . For instance, some object may have an ACE that defines that administrators have full control and another that defines that Everyone has read access.

An SACL is identical in structure to a DACL, but it defines not what access is allowed but what access is audited. If the ACEs in an SACL defined Administrators:Full Control and Everyone:Read, as we showed earlier, it would instead mean that any access by administrators is audited but that only read access is audited for Everyone.

Because DACLs are identical in structure to SACLs, we use the term ACL collectively to refer to both of them. If we specify either DACL or SACL, we refer only to that specific form of ACL.

Security Descriptors and Access Control List Entries

Permissions defined on objects are granted to security principals; they define who can do what to those objects. Objects always have an owner, and the owner can always alter an object's permissions. Remember that permissions are hierarchical throughout much of Windowsin the file system, in the Registry, in the directoryso keep this in mind as you develop your ACL'ing scheme. There are times when rights will override permissionsthe classic example is file backups . Even if the owner of a file sets a permission that denies Everyone access, those who have the right to back up files will still be able to read the file.

The implementation of the permission is in the form of a security descriptor (SD). When a program tries to access a securable object on behalf of some user, the program presents an access token which contains information about the user, membership in groups, privileges, and so on. The program also presents an access mask containing the desired access. The OS compares the information in the security descriptor with the information in the access token and the requested access methods. As long as the user, or some group or set of groups the user is a member of, has all the requested access methods listed in an allow ACE in the DACL, the access is permitted. If any single requested access method listed in a deny ACE is encountered before collecting all the access methods from allow ACEs, the entire access is disallowed .

The SD on an object contains both the DACL and the SACL (if one is defined). All objects have an SD, but they may have an empty, or null, DACL or SACL field in them. If an SD has a null SACL, it simply means that there will not be any auditing done on that object. However, a null DACL is much more problematic . It means that there are no restrictions on access to that object. In other words, a null DACL means that all users, including anonymous users, get full control over the object. Null DACLs are rare on the file system and Registry, but there have been multiple security bulletins issued to correct null DACLs on other objects, such as services and various other system objects.

SDs are typically represented in string format in the Security Descriptor Definition Language (SDDL). Since this is the way they are represented in the security templates we use to harden systems, it is worth reviewing the format here.

An SD contains information on the owner of the object, the primary group (not used in Windows but included for compatibility with other operating systems), the DACL, and the SACL. The format is as follows :

O:owner_sid G:group_sid D:dacl_flags(string_ace1)(string_ace2)... (string_acen) S:sacl_flags(string_ace1)(string_ace2)... (string_acen)

The security identifier (SID) was explained in Chapter 12, "Server and Client Hardening," so we do not repeat that description here.

The line that starts with D: represents the DACL, and the line that starts with S: represents the SACL. They are formatted identically, containing a set of flags and zero or more ACEs. The flags define the inheritance behavior of the ACL. There are three possible flags. (These show the DACL names for the flags. The SACL names are identical, except they have SACL instead of DACL.)

A string ACE is a string representation of the ACE. The string representation has the following fields, separated by semicolons:

The generic and standard rights on a file or directory define a set of file and directory-specific rights. Table 17-1 shows the actual meaning of these rights.

Table 17-1. The Actual Meaning of the Generic Rights on a File

Generic Right

File-Specific Rights

Generic execute

The ability to read the attributes of the file.

The ability to read the SD of the file. This is defined as the STANDARD_RIGHTS_EXECUTE and is what gives the subject the ability to execute the file.

The ability to use the file handle in a wait object. This right, known as SYNCHRONIZE, is typically used in multithreaded programming to be alerted to when a file changes. It is not particularly important for administrators.

Generic read

The ability to read the attributes of the file.

The ability to read the data in the file. Note that if you have only execute permission on a file but not read you cannot actually read the data in the file.

The right to read the extended attributes for the file.

The ability to read the SD of a file. This is defined as STANDARD_RIGHTS_READ and is identical currently to STANDARD_RIGHTS_EXECUTE because they are both defined as READ_CONTROL.

The ability to use the file handle in a wait object. This right, known as SYNCHRONIZE, is typically used in multithreaded programming to be alerted to when a file changes. It is not particularly important for administrators.

Generic write

The right to append data to an existing file, or to add subdirectories to a directory.

The right to change the attributes of a file.

The right to add data to a file or add files to a directory.

The ability to modify the extended attributes of a file.

The ability to read the SD of a file. This is defined as STANDARD_RIGHTS_WRITE and is identical currently to STANDARD_RIGHTS_EXECUTE since they are both defined as READ_CONTROL.

The ability to use the file handle in a wait object. This right, known as SYNCHRONIZE, is typically used in multithreaded programming to be alerted to when a file changes. It is not particularly important for administrators.

Although Table 17-1 only shows the meaning of the generic rights on a file, the same exercise can be undertaken for any securable object. The exact meaning is defined in the Windows Platform Software Developers Kit (SDK). If you want to learn more, start with the definition of an SDDL string at http://msdn.microsoft.com/library/en-us/security/security/security_descriptor_string_format.asp.

Now that you understand the structure of an SDDL string, we can work through an example to drive home how these are used. Consider the default ACL on the C: drive in Windows XP and Server 2003. It is shown in Figure 17-2.

The SDDL representation of this DACL is as follows:

[View full width]

[View full width]

D:(A;OICI;FA;;;BA)(A;OICI;FA;;;SY)(A;OICIIO;GA;;;CO)(A;OICI;0x1200a9;;;BU)(A;CI;LC;;;BU) (A;CIIO;DC;;;BU)(A;;0x1200a9;;;WD)

There are seven separate ACEs in this DACL. The first is (A;OICI;FA;;;BA). The ACE type A denotes that this is an access allowed ACE. The OI and CI ACE flags indicate that it should be inherited by both directories and files. The right FA indicates that the ACE gives the subject full control. The object GUIDs are empty, because this is a file. Finally, we see that the SID is the SID string for built-in administrators (i.e., the local Administrators group). The GUI shows this ACE as the first line.

The next ACE, (A;OICI;FA;;;SY), is identical to the first, except that the SID string specifies SA, for Local System, i.e. the operating system itself.

The third ACE, (A;OICIIO;GA;;;CO), is very much like the first two, with a few distinct differences. First, the flag IO is also specified, indicating that ACE is only used for inheritance. This ACE, specified for the user CO, or Creator/Owner, is what gives users access to directories they create underneath the C: drive. The right they get is GA (in other words, generic all, or full control).

The next three ACEs apply to BU, or the built-in Users group. The first one, (A;OICI;0x1200a9;;;BU), specifies access on C: as well as is inherited by subdirectories and files. The right is specified by a hexadecimal bitmask, in this case 0x1200a9. This indicates the bits that are used in the access mask. An access mask is a 32-bit construct that is shown in Table 17-2.

Table 17-2. The Access Mask in Windows Specifies Granular Object Rights

3

3

2

2

2

2

2

2

2

2

2

2

1

1

1

1

1

1

1

1

1

1

                   

1

9

8

7

6

5

4

3

2

1

9

8

7

6

5

4

3

2

1

9

8

7

6

5

4

3

2

1

GR

GW

GE

GA

Reserved

MA

AS

Standard access rights

Object-specific access rights

Using Table 17-2, it is simple to interpret the bitmask. 0x1200a9 is specified in binary as follows:

100100000000010101001

In Table 17-3, we have pasted in this bitmask as the second row and added a row below showing how each of these bits is interpreted for files.

Table 17-3. Evaluating an Access Mask

[View Full Width]

As we can see from Table 17-3, the rights granted to users by specifying 0x1200a9 are as follows:

The file-specific access right FR includes READ_CONTROL, SYNCHRONIZE, FILE_READ_DATA, FILE_READ_ATTRIBUTES, and FILE_READ_EA. The file-specific right FX includes READ_CONTROL, FILE_READ_ATTRIBUTES, FILE_EXECUTE, and SYNCHRONIZE. In other words, 0x1200a9 is equivalent to granting both FR, read, and FX, execute to Users. If you go back to Figure 17-2, you will find that there is an ACE shown in there for Read and Execute on this folder, subfolders , and files. That is the ACE we just found.

The next ACE, (A;CI;LC;;;BU), is also for Users. It specifies the right LC. LC is actually a directory service-specific access right. It is not normally used on files. On an Active Directory object, it specifies the right to list child objects. It corresponds to 0x4 in hex, in other words, bit 3 in the access mask. Bit 3 is FILE_APPEND_DATA. In other words, even though LC is not a valid object-specific access right on a file or directory object, it just represents a bitmask that can be interpreted on a file or directory object. The result is the ACE that gives Users the right to create folders in the C: directory. It is inherited by subdirectories, as we see by the CI flag.

The following ACE, (A;CIIO;DC;;;BU) is also defined for Users. This one is also inherited by containers, but in this case it specifies the IO, or inherit only, flag. That means it does not define any ACE on the C: directory itself. The right, DC in this case, is another directory service-specific right that would govern whether the subject can delete child objects were it applied to an AD object. It evaluates to 0x2, or bit 1 in the access mask. Applied to a directory, bit 1 means FILE_ADD_FILE, or the ability to create files. This is the ACE we see in Figure 17-2 that allows users to create files and write data in subfolders.

The final ACE on the C: directory, (A;;0x1200a9;;;WD), applies to the SID string WD, or World (in other words, Everyone). No inheritance bits are specified, and hence this ACE is not inherited. The right is 0x1200a9, which we now know means read and execute. In other words, this ACE gives Everyone the right to read and execute everything in the C: directory.

The " Troublesome " Everyone Group

We hear far too often from various people who think they understand security that the Everyone group is extremely troublesome and needs to be removed at all cost. Typically, that means they replace it with the Authenticated Users group instead. This is completely counterproductive. The reason is that Everyone is identical to Authenticated Users in Windows XP and Server 2003. Unless the security policy has been changed from the default, the Everyone group no longer includes the anonymous user, which was the only difference between Everyone and Authenticated Users in Windows 2000. Thus, performing wholesale ACL replacements to replace Everyone with Authenticated Users does absolutely nothing to secure the system. And, if you have actually set the switch to include anonymous in Everyone, chances are it was done for a reason. In this case, replacing Everyone with Authenticated Users breaks that change, calling into question why it was done in the first place.

To make things worse , these types of changes are typically made by people who do not fully understand SDDL strings and treat them very casually. The last time we dealt with a network where the administrators had attempted to replace Everyone with Authenticated Users, we found that the Administrator's profile was now world readable and that the recycle bin no longer worked. This happened because they had propagated the new ACL down the tree, blowing away the built-in ACLs on those directories. Because there were user directories already defined on the system it was impossible to automatically return the ACLs to the defaults. The net result was that they needed to rebuild several thousand machines that had these new ACLs defined.

Using the same method, you can analyze any SDDL string. For example, as an exercise we leave you to analyze the SDDL representation of the ACL on the %systemroot% directory, which is

D:P(A;CIOI;GRGX;;;BU)(A;CIOI;GRGWGXSD;;;PU)(A;CIOI;GA;;;BA)(A;CIOI;GA;;;SY)(A;CIOI;GA;;;CO)

You do not need to understand SDDL strings to set ACLs on files and directories that you create yourself, but an intricate knowledge of them will help impress people at cocktail parties. In addition, you absolutely must understand them forward and backward if you are going to modify the built-in ACLs. You must also understand the concept of Creator Owner. There are, as you have seen, a lot of ACEs for Creator Owner. When a user creates a directory, or the system creates a directory on behalf of the user, that ACE is replaced with one containing the user's SID on the new directory. This happens, for instance, on all the subdirectories under Documents and Settings. Now, if you go through and propagate an ACL through that hierarchy, you would reset not only the Creator Owner ACL on the Documents and Settings directory, you would also reset the ACL on the subdirectories owned by particular users. To restore those, you would have to manually re-create all the ACLs on those directories. It was by propagating ACLs through the Documents and Settings directory that the administrators mentioned in the sidebar "The 'Troublesome' Everyone Group" managed to make the Administrator's profile world readable. We ask you to make life easier on yourself by leaving system-defined ACLs alone and focusing on setting appropriate ACLs on objects you create yourself. The system-defined ACLs are perfectly adequate in Windows XP and higher. In Windows 2000, you need to set one ACL, on the root of the C: drive. However, do not do this yourself. Use the Windows 2000 Hardening Guide to do it for you. It took us the better part of a day to ensure we got exactly the right effect on the ACL in that guide. The guide is available at http://go.microsoft.com/fwlink/?LinkId=28591.

WARNING: Do not try to modify the default ACLs on files installed by the operating system. There is nothing wrong with them in Windows XP and higher, and the risk is much greater that you will put the system into an unrecoverable state than the chance that you will actually provide any additional security.

Typically, we see administrators trying to change these ACLs to remove the Everyone group, or to destroy the Power Users group. Neither of these is a worthwhile thing to do. As described in the sidebar "The 'Troublesome' Everyone Group," there is nothing wrong with the Everyone group any longer. The Power Users group should not be used at all. Power Users are basically administrators who have not made themselves administrators yet. It provides no meaningful separation from administrators other than to make it take one additional API call to shoot yourself in the foot . Instead of trying to destroy that group, use security policy to make it a restricted group and ensure there is nobody in it. That way it does not matter what permissions and rights it has.

Категории