Recognizing Common Permissions Problems

At this point, you should understand Windows access control, but how do you know if there is a problem? The short answer is, never grant permission to a resource to anyone that should not have access. Sounds like a simple concept, but there are many ways in which permissions could be granted accidentally . This section covers the most common problems with access control and how to find such issues in your application.

Weak DACLs

To determine whether a user has access to an object, consider the following:

  • If a DACL exists and there are no ACEs, no one has access.

  • If ACEs exist, each ACE must be checked for the correct access control.

  • If a DACL does not exist, all users have full access.

A weak DACL means that you granted permissions on an object that allow too much access. This problem could be caused by placing the permissions on the object itself or the container in which the permissions where inherited. Examine each ACE in the DACL to understand who has access to the object. Some things to watch out for include the following:

  • Giving Everyone access

  • Giving large groups access

  • Giving too much access to the container

  • Using a deny ACE

Giving Everyone Access

There is a group in the Windows operating system called Everyone. If you see this group used, it should be a red flag. As such, any permission granted to the Everyone group is bad. For instance, if there is a Write ACE for Everyone, anyone can write to your object. This vulnerability can lead to several types of attacks.

Note  

In Microsoft Windows XP Professional Service Pack 2 (SP2) and Windows Server 2003, the Anonymous Logon group no longer is a member of the Everyone group. In previous versions of the Windows operating system, the Anonymous Logon group had access to many resources because it was a member of the Everyone group.

You should especially look for the following permissions and make sure that they are never granted to the broad groups, such as Everyone and Authenticated Users, unless in situations your application absolutely requires them:

  • WRITE_DAC   Allows the DACL to be modified

  • WRITE_OWNER   Allows the owner to be changed

  • FILE_ADD_FILE   Allows files to be created, including malicious executables

  • DELETE   Allows the object to be deleted

  • FILE_DELETE_CHILD   Allows any child file or folder object to be deleted, even if the user doesn t have access to the child object

Note  

The WRITE_OWNER permission allows a user to become the owner of an object. If you are the owner of an object, you have WRITE_DAC permission on it, which can be used to obtain all the rest of the permissions. Hence, any ACL that has the WRITE_OWNER or WRITE_DAC permission should be reviewed to make sure it was expected.

Giving Large Groups Access

Much like giving the Everyone group access to an object, you should be aware of other groups in the Windows operating system because they encompass a lot of users. Table 13-2 lists common SIDs that you should watch out for because they can give a lot of people access to your resources.

Table 13-2: Common Large Groups

Display name

SID

Reason

Everyone

S-1-1-0

Includes all users, even anonymous users and guests in some versions of the Windows operating system.

Local

S-1-2-0

Obsolete group that includes all users that are logged on locally. Because it is considered obsolete, do not use it.

Network

S-1-5-2

Includes all users that have logged on through a network connection, such as by accessing a network share.

Batch

S-1-5-3

Used when scheduled tasks are executed.

Interactive

S-1-5-4

Includes all users that have logged on interactively to the active desktop.

Service

S-1-5-6

Used when all Windows Services are started, except Local System services.

Anonymous

S-1-5-7

Includes all users that have logged on anonymously or that have a null logon session.

Authenticated Users

S-1-5-11

Includes all users and groups that have been authenticated. All users in a domain and all trusted domains are part of this group.

Remote Interactive Logon

S-1-5-14

Used when a user is logged on through Terminal Services.

Users

S-1-5-32-545

All local users are automatically added to this group when a local user account is created.

Guests

S-1-5-32-546

Includes the IUSR_ computername and IWAM_ computername that Microsoft Internet Information Server (IIS) uses for the anonymous user.

Depending on your application, it might make sense to grant such a group access to a resource. You need to analyze the ACE using the context of your feature, though, and question whether it is appropriate access or whether the developer was being too liberal with the permissions.

Logon rights  

When you log on to a computer that runs the Windows operating system, depending on how you log on, your access token is populated with certain SIDs, such as the ones mentioned in Table 13-2. For example, if you log on to a machine by approaching the console and typing in your user name and password, you get the Interactive SID. However, if you log on to the machine remotely using Terminal Services, you get the Remote Interactive Login SID in addition to the Interactive SID.

Often, when developers attempt to secure the ACL of an object, they add groups that allow greater access to the object than is expected or needed. However, if they remove too many groups from the ACL, the application might stop working properly in certain situations. We have encountered this situation several times when we have reported weak permissions on securable objects because the developer might not know exactly what the correct permissions should be.

For example, look at the following ACLs set for the command-line utility Tftp.exe on a machine running Windows XP Professional SP2:

 Owner : BUILTIN\Administrators Group : NT AUTHORITY\SYSTEM ACE[ 0] : Allow : BUILTIN\Users : 0x1200a9         : ( RCtl Sync )         :() 
 : ( Read ReadEA Execute ReadAttr )         :()          ACE[ 1] : Allow : BUILTIN\Power Users : 0x1200a9         : ( RCtl Sync )         :()         : ( Read ReadEA Execute ReadAttr )         :()          ACE[ 2] : Allow : BUILTIN\Administrators : 0x1f01ff         : ( Del RCtl WDac WOwn Sync )         :()         : ( Read Write Append ReadEA WriteEA Execute ReadAttr WriteAttr )         :()          ACE[ 3] : Allow : NT AUTHORITY\SYSTEM : 0x1f01ff         : ( Del RCtl WDac WOwn Sync )         :()         : ( Read Write Append ReadEA WriteEA Execute ReadAttr WriteAttr )         :() 

Notice that the ACL allows anyone with the Users SID to run the utility. This means that if a security flaw in another process has the Users SID in its token, the process would be able to run Tftp.exe, which could be used by an attacker to download malicious code onto the victim s machine. To prevent this attack, the developer must find a way to still allow the utility to be run, but reduce the numbers of users. Instead of the Users SID, the developer could use the Interactive SID. However, this also means that if a Windows Service must execute Tftp.exe, it wouldn t be able to unless the Service SID was included. Also, if a scheduled task must execute Tftp.exe, the Batch SID would need to be added to the ACL.

In Windows Server 2003, the permissions on several command-line utilities, including Tftp.exe, were modified for defense in depth. So, a compromised process, such as IIS, wouldn t allow the attacker to execute those utilities because the IIS worker process that handles the request does not have any of the groups mentioned in its token.

If you ever wondered about which groups a specific user is a member of, you can run the command-line tool Whoami.exe ( http://www.microsoft.com/downloads ) using the /groups argument. Or, you could run Gpresult.exe, which outputs the Resultant Set of Policy (RSoP) data for the current user and computer.

Giving Too Much Access to the Container

Even if all of your objects inside a container have the correct access control placed on them, you still need to check the container object to see if it gives too much access. Examples of a container object include these:

  • Directory   Can contain child directories and files

  • Registry key   Can contain other registry keys or data

  • Process   Can launch threads

Although it is possible to restrict the permissions on the child objects, the parent objects could have ACEs that allow too much access, such as allowing tampering with a parent object, additional child objects to be created, or permissions to be modified.

The following scenario demonstrates how giving too much access to the container might cause a problem:

  • An application is installed to a location on the hard drive.

  • All of the application s files have permissions set on them to allow access only to administrators.

  • The directory in which the application is installed allows any user to create new child objects.

  • The application does not directly use any other files in the installed directory.

Because an attacker can t tamper with any of the application files, the application is safe, right? If you said no, you are correct. Because the container directory has weak permissions that allow creation of child objects, an attacker could potentially place malicious files in that directory and cause the application to use them to execute malicious code. This situation is possible if the application relies on specific shared DLLs to start. The attacker can use a technique known as dynamic-link library redirection to force the application to load an attacker-supplied DLL instead of the shared one. For example, if the application is called Runme.exe, the presence of a file called Runme.exe.local in the same directory will cause the Windows operating system to load DLLs from that directory first, even if the application Runme.exe specifies the full path to the DLL when calling the LoadLibrary or LoadLibraryEx API.

More Info  

For more information about dynamic-link library redirection, refer to http://msdn.microsoft.com/library/en-us/dllproc/base/dynamic_link_library_redirection.asp .

Even if the application doesn t load DLLs, it might automatically load other files from the directory that could lead to an attack. Imagine that an application has a designated folder that contains scripts. When the application loads, it iterates through all of the scripts in the particular folder and runs them. Even if the script files have permissions set to prevent an attacker from tampering with them, the folder might allow anyone to add additional script files, which will also be loaded. And the problem does not apply just to files and directories. Any time the container has weak permissions, there is a security vulnerability.

Important  

Any time you give Write access to a directory that contains an executable, it is the equivalent of giving Write access to the executable itself.

Using a Deny ACE

As mentioned earlier, an ACE can either allow or deny access to a particular resource. Whereas using a deny ACE in addition can provide defense in depth, it can cause problems, too. A deny ACE is analogous to using block lists, which is generally a bad approach to use to set security restrictions.

You might wonder how denying access can be a bad thing. Like many block lists, this type of access denial is usually easy to get around. For instance, we worked on a product that denied a certain group access to a resource, but allowed all authenticated users access to the resource. To gain access, attackers simply needed to remove themselves from the group. Typically, an attacker cannot change the groups they belong to, but imagine that an organization uses a deny ACE on a group called Recruiters. If you are a recruiter, you belong to that group. However, what happens when you change jobs within the company and take on a marketing role in the organization? You would probably be removed from the Recruiters group and be added to the Marketers group. Now you aren t denied access anymore to the resources the Recruiters group is restricted from.

Maybe this setup is appropriate for your application, but you should be suspicious if you see any deny ACEs used for an application. If you can easily get around the check, there is a bug in the application. If you want to allow access only to a certain group of people, using an allow list is preferable to using deny ACEs.

NULL DACLs

If the current DACL in a security descriptor for an object is set to NULL, it is called a NULL DACL. A resource that has a NULL DACL has no access control, or, in other words, Everyone has Full Control to the object. Do you see the problem? If all users are granted Full Control of the object, they can do anything with the object. For example, an attacker could cause a denial of service (DoS) by changing the permissions to Deny everyone access to the object. In almost all cases, there is no reason to have a NULL DACL on an object. If you want to grant all users the ability to read, write, modify, and delete data in an object, set the DACL to allow just those permissions ”don t use a NULL DACL.

To find NULL DACLs, you can use the tools mentioned earlier in the chapter, or you can search the code. Sometimes the following might be a quicker way to spot problems with NULL DACLs:

  • Search the code for the SetSecurityDescriptorDacl API being called with a NULL DACL.

  • Search the code for the SECURITY_DESCRIPTOR structure being initialized with a NULL DACL.

Improper Ordering of ACEs

In a DACL, the order of the ACEs matters. The first ACE in the list takes precedence over the remaining ACEs. As mentioned earlier in this chapter, ACEs can also be inherited. The permissions that are applied most directly on an object should take precedence, meaning permissions set on an object should take priority over the permissions inherited by its container.

When you change the permissions using the Windows Security dialog box, the ACEs will always be ordered correctly. However, the problem of ordering ACEs is when ACLs are being built in code. For example, if your application adds an ACE to an existing ACL on a resource, it needs to ensure that it maintains the proper order, which is as follows :

  • Deny ACE

  • Allow ACE

  • Inherited Deny ACE from parent

  • Inherited Allow ACE from parent

  • Inherited Deny ACE from parent s parent (grandparent)

  • Inherited Allow ACE from parent s parent (grandparent)

  • And so forth

It is essential to get the ACE order right; otherwise , the security permissions on the resource will be useless. Although the Windows Security Properties dialog box will display an error if the order is incorrect, as shown in Figure 13-7, it is up to you to make the order correct by using tools like ObjSD.

image from book
Figure 13-7: Windows Security warning for a directory that has incorrect ACE order

Object Creator

When a securable object is created, the owner always has access to the resource, even if the ACL denies access to that user. Unless the system policy is changed, whoever creates the object becomes the owner, except in Windows Server when the object is created by an administrator, the Administrators group is the owner. The only way the owner of an object can change is if one of the following happens:

  • An administrator assigns a new owner.

  • Anyone with the WRITE_OWNER permission

  • Any user or group that has the Take Ownership ( SeTakeOwnershipPrivilege ) privilege

  • A user who has Restore Files And Directories ( SeRestorePrivilege ) privilege

Can you think of how this can be a problem? One simple example is if the system uses a quota system for users, restricting the number and/or size of files they own. If you could set the owner of an object to anyone, the object wouldn t count against your quota because you changed the owner of the file.

Also, if you create a container, you become the owner and have access to any child objects created in that container that inherit the ACL. For example, suppose an ordinary user is a member of a group. The user doesn t do anything malicious while a member of that group. Then, the user is removed from the group. Even after time passes and the machine is rebooted several times, the user is able to compromise the system because any container objects that allow a group to create a child object are owned by the user, not the group. When the user is removed from the group, the user still has access to the objects he or she created unless the application is designed so that group is the owner, not the individual creator.

Accessing Resources Indirectly

If a burglar cannot break into a house through the front door, do you think the thief will just give up? Of course not: the burglar would try a back door, a window, the roof, and so on. Even with ACLs, sometimes a resource isn t protected if there is more than one way to gain access to it. And some operating systems do not provide an access control mechanism to protect a resource. In these cases, you have to think of methods that might allow an attacker to bypass any protection.

Take the following example. Once we tested a Web site that provided news articles to the site s members . When a user clicked a link to display the article, the Web application loaded the file specified in the URL query string and displayed it in the browser. Can you see the potential problem? By using the directory traversal technique discussed in Chapter 12, Canonicalization Issues, we were able to retrieve files outside of the directory that stored the articles. Normally, we wouldn t have any access to those files because anonymous users aren t granted permission to access them. However, we didn t access the files using the anonymous user account. We were able to access the files as the account that the Web server was running as, and thus permission was granted.

When you are trying to protect a resource, you need to think of all the methods that might be able to gain access to it. In the preceding example, the Web application had a canonicalization bug that had to be fixed, but the unauthorized access could have been prevented if the account the Web server ran as was not granted access to the files. If there are multiple ways a resource can be accessed, restricting access using only one mechanism can still leave your resource vulnerable.

Forgetting to Revert Permissions

An application can change privileges and run under the context of another user in many different ways. If your application does this, you need to make sure that it properly reverts back to the proper user. For example, if you have a Web application that uses the permissions of the logged-on user, it might call RevertToSelf to perform higher-privilege operations on behalf of the user. However, if the application does not revert back, the user is now running under the context of a higher-privileged account. This flaw is introduced mainly by improper handling of error conditions. Look at the following code:

 public void DoSomething() {     // Revert to a higher-privileged user.     SecurityContext secCon = SecurityContext.RevertToSelf())          // Calling this method could throw an exception.     DoSomethingElse();          // Revert back to original impersonated user.     secCon.Dispose(); } 

When DoSomething is called, it reverts to self, which could be a higher-privileged user. At this point, the application is running in a different security context when DoSomethingElse is called. If calling DoSomethingElse throws an exception, it isn t being handled by the DoSome thing function. As such, it might be possible for malicious code that called DoSomething to catch the exception, and then that code is running under the higher-privileged user. This vulnerability uses a technique known as exception filtering, which is covered in more depth in Chapter 15, Managed Code Issues, but this example illustrates how forgetting to revert permissions can cause problems in your application.

Squatting Attacks

Permissions often are set on an object using the function that creates an object. Sometimes developers properly secure objects when the objects are created. (If they don t, it could lead to race condition attacks , which are discussed in the next section.) If the object already exists, the creation of an object using the same name will fail. A squatting attack , also referred to as a pre-creation attack , occurs when an attacker creates an object with the same name as an object the application will create prior to the program attempting to create it. If the name of the object is predictable, the attacker will easily be able to guess the name.

Squatting attacks can occur with any named object, including files, registry keys, sockets, and named pipes. The real problem is when users have Write access to a shared namespace. To test for squatting vulnerabilities, create an object with the same name as the object the program creates and see whether you are able to maintain access to the object.

Exploiting Race Conditions

Race conditions occur when the timing of certain events influences the outcome of a program. You should consider that an attacker can perform actions between each line of code in the program you are testing. For example, if an object is created and then secured later, an attacker can take advantage of the window of opportunity provided after the object is created but before it is secured.

Timing is important when an attacker attempts to exploit a race condition, and getting the timing just right often isn t as difficult as you might think. To increase the odds of exploiting a race condition flaw, the attacker might attack repeatedly and quickly. For example, in the case in which an object is created and then secured, an attacker could write a program that loops quickly and attempts to access the object until it succeeds. Following are some situations that could lead to a race condition issue:

  • A resource with weak ACLs intended to be temporary is created.

  • A resource is created in a container that has weak ACLs.

  • A resource is created in a container that was pre-created by a malicious user.

  • The resource itself is pre-created by the malicious user.

  • The resource is created and then the ACLs are set afterward.

  • The resource is created in one container and moved to another.

  • The permissions on the thread are momentarily elevated to accomplish a different task.

When a programmatic handle is created for a securable object, the Windows operating system determines the permission needed for the object at that time. If the permissions for a resource are changed while a handle is still open , an attacker with a previous handle to the object will continue to have access.

Another type of race condition that causes many security vulnerabilities is called a Time of Check Time of Use (TOCTOU) attack. The attack occurs when a program checks for a certain condition, and then performs an action based on that check. For example, suppose a program downloads updates in a file named Update.exe to an insecure location. To prevent tampering the program verifies the file is signed by the software s author, and then runs Update.exe. The signature check prevents squatting and tampering attacks before the check. However, the attacker could swap Update.exe with malicious code after the signature is verified but before Update.exe is run.

Note  

Sometimes a file s permissions allow an attacker access to a temporary file.However, the application that creates the temp file might have an exclusive lock that prevents an attacker from opening the file.The lock is released only when the application is terminated , and at that point the application deletes the temp file. Hard links, which are discussed in the next section, are an easy way for an attacker to gain access to the file. Because a copy of a file s contents is made when a hard link s destination is deleted, an attacker can make a link to the file that is exclusively locked and then obtain a copy when the locked file is deleted from the file system.

Changing the permissions on a securable object can be extremely painful because it is difficult to find whether any open handles are using the objects. You can use the techniques mentioned earlier in this chapter to determine whether your application creates the object first and then later changes the permissions. If it does, you can almost guarantee there is a race condition bug.

Testing for race conditions can get tricky. One of the most efficient ways to test for this type of vulnerability is to use a debugger and step through the code. With a debugger, you are able to see each line of code executed and have the opportunity to perform actions of your choice outside of the debugger before the next line is executed.

File Links

Whenever a file can be represented by more than one name, interesting canonicalization security tests should be performed, which the preceding chapter covers. Both the Windows file system (NTFS) and other various file systems support the notion of linked files. A file link is much like a pointer in C. The pointer, called a link, is a dummy file that points to its target. When file operations are performed on the link file, the operation actually takes place on the destination of the link. For example, suppose a link file named c:\temp\FileLink.txt points to c:\temp\OriginalFile.txt. If you open FileLink.txt in Notepad and change the contents, the contents of OriginalFile.txt will actually be changed. Maybe you are already starting to see the potential security problems.

Please note that a linked file is different from a Windows shortcut file (.lnk). A shortcut file always ends with the .lnk extension and is just an ini file that references the place it is pointing to. If the shortcut file is opened in Notepad, the contents of the shortcut file is in its ini format. You will not be editing the file the shortcut points to.

There are different types of file links ”symbolic links, junctions, and hard links. The following sections examine each.

Symbolic Links

Here are some important characteristics of symbolic links (also called soft links):

  • Symbolic links can link to files across file systems.

  • The destination of a symbolic link can be a file or directory.

  • All operations performed on the link file are actually performed on the file the link points to. Deleting the link removes the link file, but does not delete the destination of the link.

  • If a symbolic link s destination is removed, the link is broken. If the destination is re-created, the link will work again.

  • Creating a symbolic link requires no permissions to the link s destination.

  • A symbolic link can be made to a nonexistent file. If the target of a link is later created, the link will work.

Symbolic links are not fully supported in the Windows operating system; a subset of the symbolic link functionality is available and is called a junction. More information about junctions is provided in the following section.

On a UNIX-based systems (*NIX) creating a symbolic link is easy when you use the ln command.

Junctions

In the Windows operating system, symbolic links are not fully supported. However, it is possible to create a symbolic link to a directory. This link is called a junction . The following are the characteristics of a junction:

  • A junction is a symbolic link to a directory on a system that runs the Windows operating system. A junction cannot be made to a single file.

  • Links can be across file systems.

  • File operations performed on files inside the junction are actually performed on the files inside the directory the junction points to. Removing the junction directory only removes the link. The directory the junction points to is untouched.

  • If the junction s destination directory is removed, the junction is broken. If the destination is re-created, the junction will work again.

  • Creating a junction requires no permission on the link s destination.

  • A junction cannot be made to a nonexistent directory.

    A junction can be created by using the Sysinternals Junction tool ( http://www.sysinternals.com/utilities/junction.html ).

Hard Links

Hard links are similar to but also different from soft links. Following are hard link characteristics:

  • The hard link and the destination of the link must exist on the same file system.

  • The destination can only be a file. (Linking to a directory is not supported.)

  • Just like other links, all operations performed on the link are actually performed on the destination of the link. Deleting the link removes the link, but does not delete the destination of the link.

  • If the destination of a hard link is removed, the link isn t broken. The links pointing to the target will retain the contents of the file when it was deleted. If there is more than one file linking to the original destination of the link, these files will remained linked together.

  • Creating a hard link requires Read permission on *NIX and the Write Attributes (FILE_WRITE_ATTRIBUTES) permission in the Windows operating system.

  • Hard links cannot be made to nonexistent files.

Creating hard links on *NIX can be accomplished by using the ln command. Creating a hard link in the Windows operating system can be done by using Fsutil.exe, which is shipped with Windows XP and later. This utility will run, however, only if you are logged on as an administrator. The CreateHardLink API does not require the caller to be an administrator. When testing links, test as a low privileged account ”not as an admin. The Ln.exe tool included on book s companion Web site enables you to call the CreateHardLink API directly without being an administrator.

Security Concerns with File Links

File links provide some interesting cases for canonicalization testing. If a feature is attempting to block a file or directory based on its name, a link can be used to change the name used to access the file. This name change might allow for bypassing the security check.

In addition to the traditional canonicalization name differences, links provide a way to reference files or directories that exist on different parts of the disk. Programs often perform file operations on files located in specific locations. For example, suppose that when a document is being edited a word processor always creates or uses an existing temp file with a known filename. While the document is being edited, the word processor stores various temporary information in the temporary file. If the temporary file is actually a file link, the word processor might be modifying the contents of a file other than its temporary file.

For other security reasons, developers often write temporary files to locations that only the current user has access to write to. So, users who launch the word processor are only harming themselves if they precreates the temp file as a link file. However, sometimes programs run with elevated privileges that differ from the person invoking certain functionality in a program. Other times, files created by one user are used by another user.

A simple example of such a program that runs with privileges different from the user invoking its functionality is in a game called xbreaky ( http://xbreaky. sourceforge .net ) in all versions prior to 0.0.5. Xbreaky is installed on *NIX systems with the suid bit, which means that when the program is launched, the process runs under the privileges of the owner of the executable file, not the caller. In this case, xbreaky s owner is the root account, so the game would run as root even though it was executed by a user account. The xbreaky program would write high scores to a file named .breakyhighscores in the home directory of the user who launched the program, which seemed like a safe place to store that information: only the person who launches the program should have access to the file. However, because the program is running as root, not as the user who launches the game, the user launching the program can maliciously abuse the permissions the program is running under. Marco van Berkum found a way to abuse xbreaky. He found that if he created a symbolic link named .breakyhighscores in his home directory to an arbitrary file, the game would overwrite it with the contents of the name of the high-score user (which he could control when using the game). He could point the symbolic link at any file on the system and the game running as root would happily overwrite its contents with the high score user information. More information about this vulnerability is available at http://lists.grok.org.uk/pipermail/full-disclosure/2002-September/001302.html .

The Windows operating system has functionality similar to suid on *NIX called impersonation that enables a program to change who the program is running under. To identify which programs impersonate a user while the program is running, use a program from Sysinternals called Tokenmon ( http://www.sysinternals.com/utilities/tokenmon.html ). This program lists which processes are impersonating different users and the users that are being impersonated. Programs that run with privileges that are different from the person using the program (especially programs running with elevated privileges) should be security tested rigorously.



Hunting Security Bugs
Hunting Security Bugs
ISBN: 073562187X
EAN: 2147483647
Year: 2004
Pages: 156

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net