Canonical Filename Issues

Canonical Filename Issues

I know you know this, but let me make sure we're on the same page. Many applications make security decisions based on filenames, but the problem is that a file can have multiple names. Let's look at some past mistakes to see what I mean.

Bypassing Napster Name Filtering

Bypassing the Napster filters is my favorite canonicalization bug because it's so nontechnical. Unless you were living under a rock in early 2001, you'll know that Napster was a music-swapping service that was taken to court by the Recording Industry Association of America (RIAA), which viewed the service as piracy. A U.S. federal judge ordered Napster to block access to certain songs, which Napster did. However, this song-blocking was based on the name of the song, and it wasn't long before people realized how to bypass the Napster filters: simply by giving the song a name that resembles the song title but that is not picked up by the filters. For example, using the music of Siouxsie and the Banshees as an example, I might rename Candyman as AndymanCay (the pig latin version), 92 degrees as 92 degree$, and Deepest Chill as Deepest Chi11. This is a disclosure vulnerability because it gives access to files to users who should not have access. In this case, Napster's lack of a secure canonicalization method for filenames made it difficult to enforce a court-mandated security policy.

You can read more about this issue at http://news.cnet.com/news/0-1005-200-5042145.html.

Vulnerability in Apple Mac OS X and Apache

The version of the Apache Web server that shipped with the first release of Apple's Mac OS X operating system contains a security flaw when Apple's Hierarchical File System Plus (HFS+) is used. HFS+ is a case-insensitive file system, and this foils Apache's directory-protection mechanisms, which use text-based configuration files to determine which data to protect and how to protect it.

For example, the administrator might decide to protect a directory named scripts with the following configuration file to prevent scripts from being accessed by anyone:

<Location /scripts> order deny, allow deny from all </Location> 

A normal user attempting to access http://www.northwindtraders.com/scripts/index.html will be disallowed access. However, an attacker can enter http://www.northwindtraders.com/SCRIPTS/index.html, and access to Index.html will be allowed.

The vulnerability exists because HFS+ is case-insensitive, but the version of Apache shipped with Mac OS X is case-sensitive. So, to Apache, SCRIPTS is not the same as scripts, and the configuration script has no effect. But to HFS+, SCRIPTS is the same as scripts, so the protected index.html file is fetched and sent to the attacker.

You can read more about this security flaw at http://www.securityfocus.com/archive/1/190036.

DOS Device Names Vulnerability

As you might know, some filenames in MS-DOS spilled over into Windows for backward-compatibility reasons. These items are not really files; rather, they are devices. Examples include the default serial port (aux) and printer (lpt1 and prn). In this vulnerability, the attacker forces Windows 95 and Windows 98 to access the device. When Windows attempts to interpret the device name as a file resource, it performs an illegal resource access that usually results in a crash.

You can learn more about this vulnerability at http://www.microsoft.com/technet/security/bulletin/MS00-017.asp.

Sun Microsystems StarOffice /tmp Directory Symbolic-Link Vulnerability

I added this vulnerability because symbolic-link vulnerabilities are extremely common in UNIX and Linux. A symbolic link (symlink) is a file that only points to another file; therefore, it can be considered another name for a file. UNIX also has the hard-link file type, which is a file that is semantically equivalent to the one it points to. Hard links share access rights with the file they point to, whereas symlinks do not share those rights.

NOTE
You can create hard links in Windows 2000 by using the CreateHardLink function.

For example, /tmp/frodo, a symlink in the temporary directory, might point to the UNIX password file /etc/passwd or to some other sensitive file.

On startup, Sun's StarOffice creates an object named /tmp/soffice.tmp. This object can be used by anyone for nearly any purpose. In UNIX parlance, the access mask is 0777, which is just as bad as Everyone (Full Control). An attacker can create a symlink from /tmp/soffice.tmp to a user's file. When that user then runs StarOffice, StarOffice blindly changes the permission settings on that file (because setting permissions on a symlink sets the permissions of the target, if the process has permission to make that change). Once this is done, the attacker can read the file.

If the attacker linked /tmp/soffice.tmp to /etc/passwd and someone ran StarOffice as the UNIX administrator, the permissions on /etc/passwd would get changed. Learn more about this bug at http://www.securityfocus.com/bid/1922.

Almost all of the canonicalization bugs I've discussed occur when user input is passed between multiple components in a system. If the first component to receive user input does not fully canonicalize the input before passing the data to the second component, the system is at risk.

IMPORTANT
All canonicalization issues exist because an application, having determining that a request for a resource did not match a known pattern, defaulted to an insecure mode.

IMPORTANT
If you make security decisions based on the name of a file, you will get it wrong!

Common Windows Canonical Filename Mistakes

Windows can represent filenames in many ways, due in part to extensibility capabilities and backward compatibility. If you accept a filename and use it for any security decision, it is crucial that you read this section.

8.3 Representation of Long Filenames

As you are no doubt aware, the legacy FAT file system, which first appeared in MS-DOS, requires that files have names of eight characters and a three-character extension. File systems such as FAT32 and NTFS allow for long filenames for example, an NTFS file can be 255 Unicode characters in length. For backward-compatibility purposes, NTFS and FAT32 by default autogenerate an 8.3 format filename that allows an application based on MS-DOS or 16-bit Windows to access the same file.

NOTE
The format of the auto-generated 8.3 filename is the first six characters of the long filename, followed by a tilde (~) and an incrementing digit, followed by the first three characters of the extension. For example, My Secret File.2001.Aug.doc might become MYSECR~1.DOC. All illegal characters and spaces are removed from the filename first.

An attacker might slip through your code if your code makes checks against the long filename and the attacker uses the short filename instead. For example, your application might deny access to Fiscal02Budget.xls to users on the 172.30.x.x subnet, but a user on the subnet using the file's short filename would circumvent your checks because the file system accesses the same file, just through its 8.3 filename. Hence, Fiscal02Budget.xls might be the same file as Fiscal~1.xls.

The following pseudocode highlights the vulnerability:

String SensitiveFiles[] = {"Fiscal02Budget.xls", "ProductPlans.Doc"}; IPAddress RestrictedIP[] = {172.30.0.0, 192.168.200.0}; BOOL AllowAccessToFile(FileName, IPAddress) { If (FileName In SensitiveFiles[] && IPAddress In RestrictedIP[]) Return FALSE; Else Return TRUE; } BOOL fAllow = FALSE; //This will deny access. fAllow = AllowAccessToFile("Fiscal02Budget.xls", "172.30.43.12"); //This will allow access. Ouch! fAllow = AllowAccessToFile("FISCAL~1.XLS", "172.30.43.1 2");

NOTE
Conventional wisdom would dictate that secure systems do not include MS-DOS or 16-bit Windows applications, and hence 8.3 filename support should be disabled. More on this later.

An interesting potential side effect of the 8.3 filename generation is that some processes can be attacked if and only if the requested file has no spaces in its name. Guess what? 8.3 filenames do not have spaces! I'll leave the last part of the attack equation to you!

NTFS Alternate Data Streams

I will discuss this canonicalization mistake in detail later in this chapter, but for the moment all you need to know is this: be wary if your code makes decisions based on the filename extension. For example, IIS looked for an .asp extension and routed the request for the file to Asp.dll. When the attacker requested a file with the .asp::$DATA extension, IIS failed to see that the request was a request for the default NTFS data stream and the ASP source code was returned to the user.

NOTE
You can detect streams in your files by using tools such as Streams.exe from Sysinternals (http://www.sysinternals.com), Crucial ADS from Crucial Security (http://www.crucialsecurity.com), or Security Expressions from Pedestal Software (http://www.pedestalsoftware.com).

In addition, if your application uses alternate data streams, you need to make sure that the code correctly parses the filename to read or write to the correct stream. More on this later. As an aside, streams do not have a separate access control list (ACL) they use the same ACL as the file in question.

Trailing Characters

I've seen a couple of vulnerabilities in which a trailing dot (.) or backslash (\) appended to a filename caused the application parsing the filename to get the name wrong. Adding a dot is very much a Win32 issue because the file system determines that the trailing dot should not be there and strips it from the filename before accessing the file. The trailing backslash is usually a Web issue, which I'll discuss in Chapter 17, Protecting Against Denial of Service Attacks. Take a look at the following code to see what I mean by the trailing dot:

#include <strsafe.h> char b[20]; StringcbCopy(b, sizeof(b), "Hello!"); HANDLE h = CreateFile("c:\\somefile.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (h != INVALID_HANDLE_VALUE) { DWORD dwNum = 0; WriteFile(h, b, lstrlen(b), &dwNum, NULL); CloseHandle(h); } h = CreateFile("c:\\somefile.txt.", //Trailing dot GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (h != INVALID_HANDLE_VALUE) { char b[20]; DWORD dwNum =0; ReadFile(h, b, sizeof b, &dwNum, NULL); CloseHandle(h); }

You can also find this example code in the companion content in the folder Secureco2\Chapter11\TrailingDot. See the difference in the filenames? The second call to access somefile.txt has a trailing dot, yet somefile.txt is opened and read correctly when you run this code. This is because the file system removes the invalid character for you! As you can see, somefile.txt. is the same as somefile.txt, regardless of the trailing dot.

\\?\ Format

Normally, a filename is limited to MAX_PATH (260) ANSI characters. The Unicode versions of numerous file-manipulation functions allow you to extend this to 32,000 Unicode characters by prepending \\?\ to the filename. The \\?\ tells the function to turn off path parsing. However, each component in the path cannot be more than MAX_PATH characters long. So, in summary, \\?\c:\temp\myfile.txt is the same as c:\temp\myfile.txt.

NOTE
No known exploit for the \\?\ filename format exists; I've included the format for completeness.

Directory Traversal and Using Parent Paths (..)

The vulnerabilities in this section are extremely common in Web and FTP servers, but they're potential problems in any system. The first vulnerability lies in allowing attackers to walk out of your tightly controlled directory structure and wander around the entire hard disk. The second issue relates to two or more names for a file.

Walking out of the current directory

Let's say your application contains data files in c:\datafiles. In theory, users should not be able to access any other files from anywhere else in the system. The fun starts when attackers attempt to access ..\boot.ini to access the boot configuration file in the root of the boot drive or, better yet, ..\winnt\repair\sam to get a copy of the local Security Account Manager (SAM) database file, which contains the usernames and password hashes for all the local user accounts. (In Windows 2000 and later, domain accounts are stored in Active Directory, not in the SAM.) Now the attacker can run a password-cracking tool such as L0phtCrack (available at http://www.atstake.com) to determine the passwords by brute-force means. This is why strong passwords are crucial!

NOTE
In Windows 2000 and later, the SAM file is encrypted using SysKey by default, which makes this attack somewhat more complex to achieve. Read Knowledge Base article Q143475, Windows NT System Key Permits Strong Encryption of the SAM at http://support.microsoft.com/support/kb/articles/Q143/4/75.asp for more information regarding SysKey.

Will the real filename please stand up?

If we assume a directory structure of c:\dir\foo\files\secret, the file c:\dir\foo\myfile.txt is the same as c:\dir\foo\files\secret\..\..\myfile.txt, as is c:\dir\foo\files\..\myfile.txt, as is c:\dir\..\dir\foo\files\..\myfile.txt! Oh my!

Absolute vs. Relative Filenames

If the user gives you a filename to open with no directory name, where do you look for the file? In the current directory? In a folder specified in the PATH environment variable? Your application might not know and might load the wrong file. For example, if a user requests that your application open File.exe, does your application load File.exe from the current directory or from a folder specified in PATH?

Case-Insensitive Filenames

There have been no vulnerabilities that I know of in Windows concerning the case of a filename. The NTFS file system is case-preserving but case-insensitive. Opening MyFile.txt is the same as opening myfile.txt. The only time this is not the case is when your application is running in the Portable Operating System Interface for UNIX (POSIX) subsystem. However, if your application does perform case-sensitive filename comparisons, you might be vulnerable in the same way as the Apple Mac OS X and Apache Web server, as described earlier in this chapter.

UNC Shares

Files can be accessed through Universal Naming Convention (UNC) shares. A UNC share is used to access file and printer resources in Windows and is treated as a file system by the operating system. Using UNC, you can map a new disk drive letter that points to a local server or a remote server. For example, let's assume you have a computer named BlakeLaptop, which has a share named Files that shares documents held in the c:\My Documents\Files directory. You can map z: onto this share by using net use z: \\BlakeLaptop\Files, and then z:\myfile.txt and c:\My Documents\Files\myfile.txt will point to the same file.

You can access a file directly by using its UNC name rather than by mapping to a drive first. For example, \\BlakeLaptop\Files\myfile.txt is the same as z:\myfile.txt. Also, you can combine UNC with a variation of the \\?\ format for example, \\?\UNC\BlakeLaptop\Files is the same as \\BlakeLaptop\Files.

Be aware that Windows XP includes a Web-based Distributed Authoring and Versioning (WebDAV) redirector, which allows the user to map a Web-based virtual directory to a local drive by using the Add Network Place Wizard. This means that redirected network drives can reside on a Web server, not just on a file server.

When Is a File Not a File? Mailslots and Named Pipes

APIs such as CreateFile can open not just files but named pipes and mailslots too. A named pipe is a named, one- or two-way communication channel for communication between the pipe server and one or more pipe clients. A mailslot is a fire-and-forget one-way interprocess communication protocol. Once a client connects to a pipe or mailslot server, assuming the access checks succeed, the handle returned by the operating system is treated like a file handle. The syntax for a pipe is \\servername\pipe\pipename, and a mailslot name is of the form \\servername\mailslot\mailslotname, where servername could be a dot representing the local machine.

When Is a File Not a File? Device Names and Reserved Names

Many operating systems, including Windows, have support for naming devices and access to the devices from the console. For example, COM1 is the first serial port, AUX is the default serial port, LPT2 is the second printer port, and so on. The following reserved words cannot be used as the name of a file: CON, PRN, AUX, CLOCK$, NUL, COM1 COM9, and LPT1 LPT9. Also, reserved words followed by an extension for example, NUL.txt are valid device names. But wait, there's more: each of these devices exists in every directory. For example, c:\Program Files\COM1 is the first serial port, as is d:\NorthWindTraders\COM1.

If a user passes a filename to you and you blindly open the file, you will have problems if the file is a device and not a real file. For example, imagine you have one worker thread that accepts a user request containing a filename. Now an attacker requests \documents\com1, and your application opens the file for read access. The thread is blocked until the serial port times out! Luckily, there's a way to determine what the file type is, and I'll cover that shortly.

Device Name Issues on Other Operating Systems

Canonicalization issues are not, of course, unique to Windows. For example, on Linux it is possible to lock certain applications by attempting to open devices rather than files. Examples include /dev/mouse, /dev/console, /dev/tty0, /dev/zero, and many others.

A test using Mandrake Linux 7.1 and Netscape 4.73 showed that attempting to open file:///dev/mouse locked the mouse and necessitated a reboot of the computer to get control of the mouse. Opening file:///dev/zero freezed the browser. These vulnerabilities are quite serious because an attacker can create a Web site that has image tags such as <IMG SRC=file:///dev/mouse>, which would lock the user's mouse.

You should become familiar with device names if you plan to build applications on many operating systems.

As you can see, there are many ways to name files, and if your code makes security decisions based on the name of a file, the chances are slim you'll get it right. Now let's move on to the other main realm of naming things the Web.



Writing Secure Code
Writing Secure Code, Second Edition
ISBN: 0735617228
EAN: 2147483647
Year: 2001
Pages: 286

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