File-Based or Directory-Based Attacks


If user input is used as the basis for a file or directory name to open a file, an attacker could manipulate the input to open the file from an unintended location. Suppose you create the following Public function in a server application to save user settings to the file. Your intent is to save the file to the same location as the application by using the Application.StartupPath function.

Public Sub SaveSettings(ByVal UserName As String, _
ByVal Settings As String)
Dim hFile As Integer = FreeFile()
Dim Filename As String = Application.StartupPath & "\" & _
UserName
FileOpen(hFile, Filename, OpenMode.Output)
PrintLine(hFile, Settings)
FileClose(hFile)
End Sub

Tip

In the case of ASP.NET Web applications, use Server.MapPath(Request.ApplicationPath) in place of Application.StartupPath.

If an attacker can call this function by passing in unexpected directory paths such as a path containing two dots representing the parent directory (..), the attacker can cause the SaveSettings function to create a file anywhere on the current disk drive, overwriting any file with the same name. For example, if the attacker passes a user name value such as ..\..\..\..\..\..\Windows\NotePad.Exe, the SaveSettings method will overwrite Notepad—that is, assuming the operating system is installed on the same drive as the application, Windows is installed to a directory named Windows off of the root directory, and that the attacker has supplied enough parent directory paths (..) commands to refer to the root of the disk drive. The attacker is aided by the fact that the operating system treats an overabundance of parent (..) directory specifiers as a path reference to the root directory. The attacker can simply provide an overabundance of parent (..) directory specifiers to ensure a path reference to the root directory followed by the name of the Windows directory. In the example just given, the attacker by passing ..\..\..\..\..\.. as part of the user name value assumes that the application is nested no more than six directories deep under the root directory.

Imagine further that instead of Notepad.Exe the attacker supplied the name of a critical operating system file or a personal file (located in any other directory), and that too was overwritten with the contents of the settings string. Moreover, what if your application unintentionally gives the attacker the ability to not only save the file wherever he wants, but to determine the contents of the file as well? The attacker could overwrite an .EXE such as NOTEPAD.EXE with his own file called NOTEPAD.EXE containing his own custom executable code—for example, code that calls FORMAT.COM to erase the contents of one of your hard disk drives. The changes the attacker made to NOTEPAD.EXE would lay dormant until another user (perhaps you) comes along and executes it—and poof! All the data on one of your hard drives is erased. This should make you think twice about allowing user input to be used as the basis for a filename and its content.

Defensive Technique for File-Based or Directory-Based Attacks

The following defensive technique can be used to foil a file-based or directory- based attack.

Enforce Canonical Filenames

A canonical file or directory name is a name that fits a standard definition. For example, the full path and filename of the form “C:\PROGRAM FILES\WINDOWS NT\ACCESSORIES\WORDPAD.EXE” is considered to be the canonical representation of the WORDPAD.EXE file name. However, there are many other ways to represent WORDPAD.EXE, as shown in Table 6-3, that are considered to be the noncanonical or nonstandard form of the same name.

Table 6-3: Examples of Noncanonical Filenames

Noncanonical Filenames

Notes

C:\PROGRAM FILES\..\PROGRAM FILES\ WINDOWS NT\ACCESSORIES\WORDPAD.EXE

Use the parent directory specifier (..) to navigate up and back to the same directory location.

\PROGRAM FILES\WINDOWS NT\ ACCESSORIES\WORDPAD.EXE

PATH relative to the root directory, such as C:\.

C:\PROGRAM FILES\WINDOWS NT\ ACCESSORIES\WORDPAD.EXE.

Period after the filename meaning no (additional) extension name.

C:\\PROGRAM FILES\\\\WINDOWS NT
\\\\ACCESSORIES\\\WORDPAD.EXE

Overuse of backslashes—the operating system simply ignores unnecessary backslashes.

WORDPAD.EXE

Relative filename, which assumes the current drive and directory contain WORDPAD.EXE.

Your code is vulnerable to file or directory attacks if your code does not check for file canonicalization errors. For example, if you have code that checks to see whether the first part of a passed-in filename matches the location of your application, assuming your application is in the C:\MyApplication directory, your code will not see anything wrong with a directory path such as C:\ MyApplication\..\Windows\System32. However, this could be a big problem if the calling code has full access to the C:\WINDOWS\SYSTEM32 directory because the caller might be able to browse, rename, or delete any important system file.

To address this problem, you should convert the file and directory name to a standard or canonical format. By changing the file and directory names to a canonical form, you allow for an apples-to-apples comparison of the location of two files or directories. If you were to first change the directory name C:\ MyApplication\..\Windows\System32 to a canonical form, the resulting directory name is C:\Windows\System32, which you compare to the name of the directory that your application expects to use; clearly C:\Windows\System32 is not the C:\MyApplication directory that the application intends to use.

A useful Visual Basic .NET function for changing file names into canonical form is the Path.GetFullPath method, which returns the absolute path to the given file. If, for example, you want to ensure that data files you write are placed in the same location as the application, you can call the Path.GetFullPath method (passing in the filename you intend to save), pass the result of the Path.GetFullPath method to the Path.GetDirectoryName method to get the directory location of the file, and compare the result to the path returned by Application.StartupPath (for Windows applications) or Server.MapPath(Request.ApplicationPath) (for Web applications). If the two match, you can be assured that the file will be saved in the same location as the application.

The following code demonstrates how you can implement a function named IsValidPath to verify that a filename and path you assemble from one or more strings refer to your application directory:

Private Function IsValidPath(ByVal strFilename As String) _
As Boolean
’TODO: Include Imports System.IO at the top of the code
’ module
Dim strCanonicalFilename As String = _
Path.GetFullPath(strFilename)
If Path.GetDirectoryName(strCanonicalFilename).ToLower = _
Application.StartupPath.ToLower Then
Return True
End If
Return False
End Function

As an added measure, in addition to verifying the path name you could also verify that the UserName value does not contain invalid characters by using the regular expression Regex class to check the contents of the user name against a set of valid characters. Note that in this hypothetical case—assume that you restrict user names to alphabetic characters only—you should restrict the set of valid characters to not include special filename symbols such as the period, backslash, or dollar sign. For example, you could use a regular expression such as ^[A-Za-z]+$ to ensure that the user name contained only letters and no symbols, spaces, or other characters that could lead to problems if used as part of a filename. If a user name, as defined by your application, can contain numbers or punctuation, the regular expression suggested earlier will be too restrictive. The point is that you need to add the required logic—regular expressions or other forms of string checking—that checks whether the user name contains only the set of characters it is allowed to contain and no more. If you’re new to regular expressions, Chapter 7 provides more in-depth coverage of the syntax. Finally, you should check that the user name is of reasonable length to avoid a DoS attack.

Note

If, in the example shown previously, the user name matches a device name such as AUX, CLOCK$, COM1-COM9, CON, LPT1- LPT9, NUL, or PRN, any attempt to open a file having the same name will fail with an exception. The reason is that the operating system reserves these special device names and treats the device names as being part of the file system. Fortunately, the Visual Basic .NET file I/O functions prevent you from opening a device. The file I/O functions throw an exception instead. Although the file I/O functions detect when you attempt to open a device, you should add code to explicitly check to make sure that the user name does not match—using a non–case sensitive comparison—a device name. This is an example of using a defense-in-depth approach to further protect your application.

Error checking should be added to the SaveSettings method as follows:

Public Sub SaveSettings(ByVal UserName As String, _
ByVal Settings As String)
Const MAX_USERNAME_LENGTH As Integer = 15
Dim hFile As Integer = FreeFile()
Dim Filename As String = Application.StartupPath & "\" & _
UserName
If UserName.Length <= MAX_USERNAME_LENGTH AndAlso _
IsValidPath(Filename) Then
FileOpen(hFile, Filename, OpenMode.Output)
PrintLine(hFile, Settings)
FileClose(hFile)
Else
Throw New ArgumentException("Invalid settings filename")
End If
End Sub




Security for Microsoft Visual Basic  .NET
Security for Microsoft Visual Basic .NET
ISBN: 735619190
EAN: N/A
Year: 2003
Pages: 168

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