Author: Qin Haipeng from: yesky
Description: All procedures in this article are compiled on Windows 2000 Server Chinese Edition SP2: .NET Framework 1.0 Version 1.0.3705 1. A significant hidden dangers in the ASP.NET virtual host I have applied for WWW.BRINSTER.com A free ASP.NET space, uploaded two programs, one of the programs that view directory and files prove that my judgment: A security issue in the ASP shared space server, still exists in the ASP shared space server and becomes more It is difficult to prevent! Through this program I can browse all users' ASP programs, you can view the system log of the server ..., of course, if I want to delete something, there will be no problem. In order to let everyone know more about this problem, we must briefly introduce this problem that already exists in the ASP. Standard components commonly used in ASP: FILESYSTEMOBJECT, this component provides powerful file system access capabilities for ASP, read and write, delete, renamed any permissions on the server hard disk. The FSO object comes from the Script Runtuance Scrrun.dll provided by Microsoft. With the following code, you can create an FSO object in the ASP: SET FSO = CREATEOBJECT ("Scripting.FileSystemObject") We use the FSO objects that include properties and methods, such as Drive, Drives, Folder, File, Files, etc. Disk, directory, and files read, write, delete, etc. This powerful file system access capabilities bring serious security issues to the ASP shared space providers, and many ASP space administrators delete this component or rename this component to avoid users using this standard component. Deleting components or component renons are indeed a simple way and is also very effective, but the majority of users cannot use its powerful features. There is also a beautiful program that allows users to use the FileSystemObject component without affecting the security of the server, that is, set an independent server user and a single directory for each user. But this method is problematic. Because the problems in this regard in ASP and ASP.NET are very similar, we will add in accordance with the corresponding solutions of ASP.NET. In ASP.NET we found this problem, it is more difficult to solve. This is because .NET's functionality about the system IO operation becomes more powerful, which makes this problem more seriously a new feature of ASP.NET, which requires the components that must be used as Regsvr32 like ASP. Register, you can use it directly to use the DLL class library file to the bin directory. This feature does have a great convenience to developing ASP.NET, but let us lose this DLL to delete or change the solution in ASP, and prevent this issue more complicated. Before discussing the solution, let's take a look at how to achieve the above hazardous features. Second, the file system operation example is necessary before we write the code, it is necessary to understand the major classes we need to use. These classes are under System.io Namespaces, and the System.io namespace contains classes that allow synchronization and asynchronous read and write on data streams and files. At the beginning of the entire application, we need to understand the system information of the server, which requires the System.Environment class that provides information about the current environment and platforms and how they operate. We can get the current directory and system directory of the system via the System.Environment class, which makes us discover a few key directories faster; we can also help us understand the ASP.NET program by getting the username running the current process. Users used to further set user rights to avoid this security problem.
We also have to use the other classes in System.io namespaces: system.io.directory: Provide class system.io.file for creating, moving, and enumerating static methods through directory and subdirectory: Class SYSTEM.IO.FILEINFO: Copy, delete, move, and open files: Provide class system.io.streamReader for instance methods for creating, copying, deleting, moving, and opening files: implementing a TextReader to make it Specific encodings read characters from byte streams. Specific use of the properties and methods of each of the classes we use. We will explain in the program in the way in the code annotation. In the Mscorlib.dll provided by .NET Framework, you need to reference this DLL to this item before using VS.NET programming. The programs we have written have used the codebehind mode, that is, each ASPX program has a corresponding ASPX.CS program, and the ASPX program is just written with the page display related code, all logical implementation code is placed in the corresponding ASPX. In the CS file, this can be more appropriate to display the separation of logic. Since our purpose is not to discuss CodeBehind technology, it will not be discussed. In this article, we only introduce several major classes and their key methods, please check the included source code. Program 1: Programs that display the current information of the server and the name of the full logical drive 1: We use the getSysInf () method to get the server's current environment and platform information // to get system information, this method is Public void getsysInf () {// get operating system type qdrives = environment.osverth.systemDIR = Environment.SystemDirectory.tostring (); / * Get mapping to The physical memory of the process, through this memory, you can understand how much physical memory is required at runtime, which helps better plan our entire application because physical memory is by Byte. Therefore, in addition to 1024, we can get the physical memory of KB * / qmo = (Environment.workingSet / 1024) .tostring (); // Get the current directory (that is, the process started from the process) Full limit path qcurdir = environment.currentdirectory.tostring (); // Get the network domain name qDomname = Environment.UserDomainName.tostring (); // Get the number of milliseconds after the system startup qtick = Environment.tickcount; // Calculate The number of minutes after the system is started QTICK / = 60000; // Get the machine name qmachine = Environment.Machinename; // Get the username Qusen = Environment.userName; / * Retrieve this computer is "
System information does not need to operate, we simply use ASP: Label to show them. The number of logical drives is not unclear on different servers, so the name of the logical drive is saved in different servers, and the name of the logical drive is also the foundation of our next browsing directory and file, so we use the data grid DataGrid. Display and process it. Display and handle the DataGrid code of the logical drive name (code at listdrivers.aspx file):
The first two BoundColumn is a display serial number and the actual logical drive name. It is necessary to explain that the third column is the file that needs to pass the selected logical drive to the display directory before entering each logical drive display directory and file. Go, so you need a special hyperlink row HyperLinkColumn, we set DataNaviGateURLField to the field where you want to bind to the hyperlink URL in HyperLinkColumn, that is, the logical drive name. Then when the DataNavigateURLFORMATSTRING is set to the field of the URL data to bind to the data source, the URL of the hyperlink in this hyperlinkColumn is the next level processing page to which you want to link, which is listdir.aspx? DIR = {User click on the logical drive name}
Create a data source (code in the listdrivers.aspx.cs file):
// Returns a collection of data views in a collection of data view DataViewicollection createDataSource () {// Defines data table DataTableDataTable DT = new data () DataTableDataBLEDATABLE DT = New DataTable (); // Defines a line of data in DataTable DataRowDataRowDataRowDataRowDataRowDataRowDataRowDataRowDataRowDataRowDataRowDataRowDataRowDataRowDataRowDataRowDataRowDataRowDataRowDataRowdTarow DR; / * Added to DataTable A column, format: Datacolumn ("Column", type) Column is the name of the data column, TYPE is the data type of data column * / dt.columns.add (New Datacolumn ("ID", Typeof (INT32))); DT .Columns.add (New Datacolumn ("Drivers", TypeOf (String))); DT.COLUMNS.ADD (New DataColumn ("Detail", TypeOf (String)))); // Use the for loop to use the for loop to use the name of the logical drive to Add to Data Table DataTable in FOR (INT i = 0; i Data binding code (code in listdrivers.aspx.cs): / * Set DataGrid data source DataSource for our data view DataView * / DriversGrid.DataSource = CreateDataSource (); // to bind DRIVERSGRID.DATABIND (); //. Through several main methods described above, we implemented system information and display all logical drive names, and can enter the next display directory and file name by the corresponding link ListDir.aspx Display all the logical drives Directory and files. Procedure 2: There are two forms of subdirectories and files in the program listDir.aspx directory in the display directory, and must be treated separately. We call this program itself to list the subdirectory, and the file we need to call the showfile.aspx program to display the properties and content of the file. And both have different deletion methods, so we set up two DataGrid, two DataTable, two DataView, handle and display directory and files, respectively. Display and process the DataGrid code of the directory and file (code in listdir.aspx file): Display the number of serial numbers and names of the directory or file similar to the corresponding code in the listdrivers.aspx program, which is no longer repeated here. For subdirectory and files have their own processing pages, they need to navigate to two different pages. For subdirectories, we continue to list subdirectory and files under ListDir.aspx program: We used a deleted button column in two DataGrid: Due to the addition, update, delete function columns are DataGrid's default template columns, you can automatically add this column to the property generator through the DataGrid in VS.NET. Get the code for the parameters passed by the previous page: Since the parameters passing by the previous page are required to determine the name of the directory and file in the method of generating a data source below, the following code is used in the page_load method of the page: STRDIR2LIST = Request.QueryString ["DIR"]; String strDir2list is the directory name or file name. Because we used two Dategrids, we need two data bindings, there are two ways to generate data sources. Method for generating a directory data grid (Dirgrid) data source: // Returns a collection of data view DataView in the form of a collection of DataGridicollection CreateDataSourceDir () {DTDIR = New DataSourceDir () {DTDIR = New DataTable (); DATAROW DR; / / Add new data columns to DataTable, four columns DTDIR .Columns.add (New Datacolumn ("Dirid", TypeOf (INT32))); DTDIR.COLUMNS.ADD (New Datacolumn ("DirName", TypeOf (String))); DTDIR.COLUMNS.ADD (New Datacolumn ("Deldir ", TypeOf (String)); DTDIR.COLUMNS.ADD (New Datacolumn (" DIRDETAIL ", TypeOf (String))); // According to the incoming parameter (directory name), get the character in this directory all sub-directory names String array string [] Direntries = Directory.getDirectories (strDir2list); // Using the Foreach loop to traverse the array of unknown lengths for the array of unknown Foreach (String DirName in Direntries) {DR = DTDIR.NEWROW (); DR [0] = i ; // Serial number DR [1] = DIRNAME; // folder name DR [3] = "Delete"; DR [3] = "View Details"; DTDIR.ROWS.ADD (DR); i ;} DataView DVDIR = NEW DATAVIEW (DTDIR); // Returns the obtained data view Return DVDIR;} Method for generating a file data grid: // Returns a collection of data view DataView in a collection of data to initialize the DataGridicolction of the file. CreateDataSourceFile () {dtFile = new DataTable (); DataRow dr; dtFile.Columns.Add (new DataColumn ( "FileID", typeof (Int32))); dtFile.Columns.Add (new DataColumn ( "FileName", typeof (string )))))); DTFILE.COLUMNS.ADD ( New Datacolumn ("Delfile", TypeOf (String)); DTFile.Columns.Add (New Datacolumn ("FileDetail", TypeOf (String))))); // According to the incoming parameter (directory name), get all this directory all File name strings array string [] filentries = Directory.getFiles (strDir2list); forward (string filename in filentries) {DR = DTFILE.NEWROW (); DR [0] = i; dr [1] = filename; DR [ 2] = "Delete"; DR [3] = "View Details"; DTFile.Rows.Add (DR); i ;} DVFile = New DataView (DTFile); Return DVFile;} We have a programming to implement two DataSource only The data binding of the two DataGrid can be displayed on the dataGrid of the ASPX page in the page_load method of the page. Data binding code: / / The subdirectory data list DirGrid is data source definition and data binding Dirgrid.DataSource = createDataSourceDir (); Dirgrid.Database (); // Data source definition and data binding filegrid.DataSource = CreateDataSource definition (); Filegrid.database (); Through the main methods introduced by us, we implements a list of all subdirectories and files in a logical drive or directory, and can further browse the subdirectory according to the display result. Or view the properties and content of the file. The browsing subdirectory is still through the list of listdir.aspx, without any subdirectories, without directory depth restrictions. Delete subdirectory and file main methods and code: When deleting subdirectory, we need to use the Directory.Delete (String, Bool) method, this method has two: 1. Public Static Void Delete (String); Delete the empty directory from the specified path. 2. Public Static Void Delete (String, Boolean); Delete the specified directory and delete any subdirectories in the directory, if you set the Boolean to true, remove all subdirectories and files in this directory, otherwise set Boolean to false. Here we use the second method. If you choose to delete, you will delete all subdirectories and files in this directory. Note: All methods of the Directory class are static, so there is no need to have an instance of directory Directory. / * Implement the method of deleting subdirectory, this method is automatically added for VS.NET, pay attention to DataGridCommandEventArgs E for the ButtonColumn of CommandName = "Delete" in Dirgrid, through this event, we can get the ButtonColumn button column of that line is clicked. Furthermore, we need to delete the name of the subdirectory * / private void Dirrid_DeleteCommand (Object Source, System.Web.ui.WebControls.DataGridCommandEventArgs E) {/ * Defines a cell, E.Item is all the rows of this event. Project, E.Item.cells [1] is the content of the second cell of the entire row, in this dataGrid, name * / Tablecell Itemcell = E.Item.cells [1]; // Get this String Item = itemcell.text; // delete this subdirectory directory.delete (item, true); // Delete data binding to update data list Dirgrid.DataBind () When you delete a file, we need to use file.delete (String Path); Note: All methods of the FILE class are static, so there is no need to be called without the instance of the directory. private void FileGrid_DeleteCommand (object source, System.Web.UI.WebControls.DataGridCommandEventArgs e) {TableCell ItemCell = e.Item.Cells [1]; // This file name string to the string of item = ItemCell.Text; // Delete This file file.delete (item); / / After deleting, data binding to update data list Dirgrid.Database (); Through the main method of the upper, we implements a function of deleting a subdirectory or file on the page. This feature requires careful use when testing, and once the deletion cannot be recovered through a regular method. Other methods such as directory or file rename, modification, and other methods can be added based on this program, and the implementation method is also very simple. Dear lovers can expand into a web-based server file management system by adding a corresponding function. We can also see the hazard of this program, a file system that does not have a server that takes preventive measures to prevent measures in front of the user who uses this procedure. Procedure 3: Display file properties and contents of the program showfile.aspx need to use two major classes that need to be used when displaying properties and content: System.io.fileinfo: Provides an instance method for creating, copying, deleting, moving, and opening files and helping to create a FileStream object. System.io.StreamReader: Implement a TextReader to read characters from the byte stream in a specific code. Unless otherwise specified, StreamReader's default code is UTF-8 instead of the ANSI code page of the current system. UTF-8 can properly handle the Unicode character and provide consistent results on the localized version of the operating system. Showfile.aspx page main code: We just display the properties and part of the files on this label. So there is no other complex code. Getting the main code for file information and content is in the page_load method (the code is in the showfile.aspx.cs file): / / Receive the incoming parameters, determine the file name that needs to be operated Strfile2Show = Request.QueryString ["file"]; Name: "; FileDetail.Text = Strfile2Show " Through these three simple programs, I think everyone can clearly understand the harm of this vulnerability. If we don't prevent prevention, other users' programs can be viewed, deleted, servers System logs, system files are not available. Solution The method of fso components and delete or renamers will not explain too much, and there are many articles on the network on this class. There is also a corresponding solution for the FSO component vulnerability of ASP, ie, according to user settings. In IIS, you can set an anonymous access to each site, default is IUSR_ HostName, the principle of this method is to set a Windows account for each shared host user, such as IUSR_HOSTNAME1, IUSR_ Hostname 2, then Each user is restricted in its respective web directory. We carefully study this solution and find that this program cannot really achieve safety. Because the system runs the ASP, it is not used for the IUSR_ HostName account, but the iWam_ HostName account, just like the user ASPNET used in ASP.NET. That is to say, the permissions owned by each ASP program are not permissions of IUSR_ HostName, but the permissions of IWAM_HOSTNAME users. Such methods cannot really limit the file system access rights of each shared host user in their virtual sites, each user can still access the code of others. So this method is unable to truly implement security between users in ASP.NET. The account number of the corresponding ASP.NET program in ASP.NET is ASPNET, and the solution in the ASP mentioned above is similar, we can only limit this user to access other directories such as system directory, but cannot prevent users from accessing other sharing. The program code of the host users cannot fundamentally eliminate this problem. So, there is no real solution? Have! This is the new feature of .NET Framework - Code Access Security For better understanding of this problem, we need to introduce the security mechanism of the .NET Framework. Then combine our practical problems to discuss solutions. In order to solve security issues, .NET Framework provides a security mechanism called code access security. The code access security allows the code to set the code to a different level of trust code based on the identity of the source and code of the code, and also define the trust of different levels of code in detail, so that the code sets respective permissions to the code ratio. Assign the maximum authority to all the code. Using code access security, you can reduce the possibility of severe system security issues that malicious code or various erroneous code. You can set a set of operations that allow code execution, which can also set a set of operations that will never be permitted. The basis of implementing code access security is JIT (runtime compilation) and IL (middle code). So all managed codes that run libraries in public language are benefited from code access security. The non-hosting code cannot fully use the code access security. Below we will introduce various functions implemented by code access security: Code Access security is a mechanism for controlling access to protected resources and operations. In .NET Framework, code access security performs the following features: • Define permissions and permissions sets, indicating access to various system resources. · Enable administrators to configure security policies by associating the permissions set to the code group. · Enable code to request running the required permissions and other useful permissions, and specify which privileges can definitely have. • Grant permissions to the loaded assembly based on the permissions of the code request and the security policy allowed. · Make the code to require its caller with specific permissions. · Make the code to require its caller to have a digital signature, thereby only allowing a particular organization or a caller of a particular site to call the protected code. · By comparing the permissions granted to each caller on the calling stack and the permissions that the caller must have, the runtime limit is enhanced. In order to determine if the permissions of the code have been granted, the security system of the .NET runtime will traverse the entire call stack, compare the permissions granted by each caller with the current requirements. If no required permissions in the calling stack, security exceptions will be triggered and access and corresponding operations will be rejected. Stack steps are intended to prevent attacked attacks; in this attack, the credible code calls highly trusted code and performs unauthorized operations using highly trusted code. All caller is required to have permissions, but it is important to prevent code from attacking attacks. To optimize performance, you can perform less stack steps; however, you must ensure that security defects are not exposed during any time. There are also common purposes for another code access security, that is, the application downloads the control from the network Web site to the client. The code security of this method is also set in the client, according to the signature and other data rights certificates. To determine whether you can allow the downloaded control to run. This approach is similar to the security settings of ActiveX, but is more detailed and powerful to set permissions. Compared with the Java Applet's sandbox safety mechanism, .NET client control can access various resources of the client after local simply set. Since this is not our focus, we will not discuss its use and its implementation principles here. Below we talk about how to apply this security feature to solve system security vulnerabilities in ASP.NET. Since the system we introduce is a shared host, there is a particularity, that is, the system administrator cannot give appropriate permissions to all the code in advance, because each user may have various authority requirements, and these requirements for special power It may be in use, so there are various requirements at any time on permission management. Therefore, in terms of permission settings, it is not only administrator settings, but also includes permission requests for each shared host user, which is also an important part of the security code mechanism. Request Permissions are how you let the run library know the code to perform what operational permissions. Request permissions for the assembly by placing attributes (declared syntax) to code. As requested the built-in permission code: // The attribute is placed on the assemin level.Using system.semblying.Permissions; [Assembly: permissions); Place this code in the start of the program (before the Namespace declaration), the requested permissions are stored in the assembly list when compiling. When loading, run the library check the permission request, and apply the security policy rule to determine which permissions granted to the assembly. Although most of the code we have written has no permission, in fact, whether it is a shared host form or a stand-alone server form should request permissions, because request permissions help ensure that only the privileges required by the code will be granted. If you do not grant code extra permissions, even if some malicious code wants to use your code to make security damage, it will not operate additional system resources that have not been assigned to your own code. You should only request those permissions required for code, and more permissions should not be requested. After the code requests permissions, the system administrator can use the "Permissions View" tool (PermView.exe, located in the bin directory of your .NET Framework) to check your assembly and set the security policy according to other conditions to determine if Give your code corresponding to the corresponding permissions. If you don't explicitly request permissions required by the application in your code, then administrators will be difficult to manage your application. On the strict host of authority, you will not be able to implement the functions required for your code. Request permissions notify the running library application which permissions are required, or which privileges do not need to be required. In the default state after .NET Framework installation, all code is FullTrust. At this time, there is no need to apply for any permissions, but once the administrator has modified code security, the disk access we use will be limited, this is the need to apply for a corresponding authority. The file management code introduced on us needs to have the ability to read and write local hard drives, and the application must have FileiOpermission. If the code does not request FileiOpermission, the application does not allow the application to have this permissions on this permission, which will cause security anomalies when the application attempts to disk operation. Even if the application can handle this exception, it will not allow it to operate the disk. Of course, if your code does not access protected resources or perform protected operations, no permissions are requested. For example, if the code calculates the result according to the input to it, it is not necessary to request permissions. If your code accesses protected resources but does not request the necessary permissions, it may still be performed, but if it tries to access some resource, it is not necessary, it may fail during the execution process. After obtaining the user's permission application, the system can consider whether to give the user according to the permissions according to the situation, here let's take a look at the specific method of the corresponding code authority setting. After we installed successfully .NET Framework, two administrative tools in Windows 2000 Server management tools: Microsoft .NET Framework Configration and Microsoft .NET Framework Wizards. These two management tools are similar, but Microsoft .NET Framework Wizards are set through the Wizard, if you are not familiar with the security operation of .NET FrameWRK, you can use the wizard to set by step according to the system prompts. Related permissions. Microsoft .NET Framework Wizards interface Microsoft .NET Framework Wizards interface Use Microsoft .NET Framework Wizards to set the permissions of .NET Framework. But in order to better manage the permissions of each code, use Microsoft .NET Framework Configuration to set the permissions we need. (Microsoft .NET Framework Configuration Main Interface) You can set all properties about the .NET Framework in Microsoft .NET Framework Configuration. Click on my computer to open the drop-down menu, we can see that the program cache, configured assembly, remote processing service, running security policy, application and other five. Running Security Policy Settings is the focus of our article. We can first check the assembly cache, here we can see all global assembly cache, and store the assembly that specifies several applications shared by the computer in the global assembly cache. Here we can find all the assemblies we can use, while you can also add and remove certain assemblies. For details, see the .NET Framework SDK documentation. What we are hereby discussed here is the runtime security policy. In this strategy, it is divided into four levels from the hierarchy, namely: business, computer, user, application. At the time of calculation permission, the runtime starts from the top of the hierarchy and then calculates down. The lower policy level cannot be increased on the permissions granted on higher levels, but the permissions can be reduced. This means that if we set the computer policy to a smaller permission, you can make the set permissions to take effect, that is, the order of the permission check is from low level to high, only at low levels The existing settings check the settings of the previous level. By default, user policies and application domain policies are less restrictive than computer policies and enterprise strategies. Most default strategies are shown on the computer level. So we need to modify the permissions of the default installed host on the computer level, and the modified content is set according to the host, and the other unknown code of the host application is set. If we discuss the shared host, try to set the permissions at the computer level, to avoid the file system security issues we discussed, you must pay attention to local disk access in the permissions. We open computer policy settings to find several default code groups, permission sets, and policy assemblies. We can add code groups and custom permission sets as needed. When you add a code group, you can choose several conditions, the main condition type: The default is all Code, application directory, hash, strong name, author, site, etc. For the shared host we have to discuss, we need to change the permissions of all code under My_Computer_ZONE to unable to read and write, before the changes, we need to define a permission set first. The role of this limit is to click on the right set, right click to select New, and a window that creates a power limit will appear. Here you need to name our new permissions set. The next step is to assign a single permission to the right set. As shown below.
"; FileDetail.Text =" File Size "; // Get the size of the file, then the transform unit is kbfiledail.text = (FI.LENGTH / 1024). TOSTRING () "k
"; FileDetail.Text = "Create a file time:"; // Get the date of the file FileDetail.Text = FI.CRETIONTIME.TOSTRING (); FileDetail.Text = " Secondary access time: "; // obtain the last access date of the file FileDetail.Text = FI.lastaccesstime.toString () "
"; FileDetail.Text =" last write time: "; // Get the last write date FileDetail.Text = FI.lastwrittime.tostring () "
"; // instantiate a StreamReader object, for reading this fileInfo, StreamReader FileReader = FI.OpenText ); // Define a character array of length 1000 as a buffer char [] thebuffer = new char [1000]; / * readblock method: read the maximum number of characters from the current stream and starting the data from the index Buffer. Parameters: Char [] Buffer: When the method returns, the specified character array int index: buffer is started to write in the INT Count: the number of characters read, * / int Nread = fileReader.Readblock (Thebuffer, 0, 1000) FileDetail.Text = New string (thebuffer, 0, nread); // Close this streamReader and release all system resources with it FileReader.close (); to now, we implemented a simple web page server Disk management applications, you can view, delete directories and files. If you need to modify files, new files, and folders, you can add the corresponding code to the corresponding code. Since we simply explain the security risks existing in the server through this program, these features are no longer implemented here.