Asp.net| safety | Hidden Danger | Virtual Host
Description: All programs in this article are compiled and run correctly on Windows Server Chinese + SP2
Development environment:. Net Framework 1.0 Version 1.0.3705
First, ASP. NET virtual host exists the significant hidden danger
I once applied for a free asp.net space in WWW.BRINKSTER.COM, uploaded two programs, one of which looked at the directory and file of the program to prove my judgment: ASP shared space server exists a security problem in asp+ A shared space server still exists and becomes more difficult to prevent! Through this program I can browse all the user's asp+ program, can view the server's system log ..., of course, if I want to delete anything, there is no problem. In order to get a clearer picture of the problem, it is necessary to briefly introduce the problem that already exists in ASP.
Standard components commonly used in asp: FileSystemObject, this component provides a powerful file system access to the ASP, you can read, write, delete, rename, and so on any directory and file with permissions on the server hard disk. The FSO object is from the Script Runtime library provided by Microsoft Scrrun.dll.
Use the following code to create an FSO object in asp:
Set fso = CreateObject ("Scripting.FileSystemObject")
We use the FSO object contains the properties and methods, such as drive, drives, Folder, floders, File, files, etc. to the server's disk, directories and files to read, write, delete and other operations. This powerful file system access capability poses a serious security problem for ASP space providers, and many of the administrators of ASP spaces Delete This component or rename it to avoid users using this standard component. Deleting a component or component renaming is indeed a simple and effective method, but it makes it impossible for the vast majority of users to use its powerful features. There is also a seemingly beautiful scenario on the Web that allows users to use the FileSystemObject component without affecting the security of the server, which means that each user is set to operate on a separate server user and a single directory. But there is a problem with this approach. Because the problems in this area are very similar between ASP and ASP.net, we will elaborate on the corresponding solutions in asp.net.
In asp.net we find that this problem still exists and becomes more difficult to solve. This is because. NET has become more powerful in the function of system IO operations, what makes this problem more serious is that ASP.net has a new function, this component does not need to use the regsvr32 as the ASP to register, just upload DLL class library file to the Bin directory can be used directly. This feature does bring great convenience to development asp.net, but it makes it more complicated to prevent this problem from being eliminated or renamed in ASP. Before we discuss the solution, let's take a look at how to implement the dangerous functionality described above.
Ii. examples of file system operations
Before we write the code, it's important to understand a few of the major classes we need to use. These classes are all under the System.IO namespace, and the System.IO namespace contains classes that allow synchronous and asynchronous reads and writes on data streams and files.
At the beginning of the entire application we need to know the server's system information, which requires the System.Environment class, which provides information about the current environment and platform and how to manipulate them. We can get the current directory and system directory of the system through the System.Environment class, which enables us to discover several key directories faster; We can also help us understand the users who run the ASP.net program by getting the username that runs the current process, and further set user permissions to avoid this security issue.
Several other classes that we also want to use the System.IO namespace are:
System.IO.Directory: Provides classes for creating, moving, and enumerating static methods through directories and subdirectories
System.IO.File: A class that provides static methods for creating, copying, deleting, moving, and opening files
System.IO.FileInfo: Classes that provide instance methods for creating, copying, deleting, moving, and opening files
System.IO.StreamReader: Implements a TextReader that reads characters from a byte stream in a specific encoding.
The specific usage of the properties and methods of each class we use will be explained in code comments in the program.
System.IO Namespaces in the mscorlib.dll provided by the. NET Framework, you need to reference this DLL to this project before you use Vs.net programming.
The programs we write use the codebehind approach, That is, each ASPX program has a corresponding Aspx.cs program, ASPX program only write and page display related code, all the logic to implement the code is placed in the corresponding Aspx.cs file, so that you can better display and logical separation. Since our aim is not to discuss codebehind technology, we are not discussing it any more.
In this article, we'll just introduce the use of several major classes and their key methods, and see the accompanying source code for detailed procedures.
Program One: Displays the current information of the server and the names of all logical drives listdrivers.aspx
Main Method 1: We use the Getsysinf () method to get the server's current environment and platform information
The method for obtaining system information, which is in the Listdrivers.aspx.cs file
public void Getsysinf () {
Get operating system type
Qdrives = Environment.OSVersion.ToString ();
Get system Folder
Qsystemdir = Environment.SystemDirectory.ToString ();
/* Gets the amount of physical memory mapped to the process context, through which you can understand how much of the ASP.net program needs to run at the same time, to better plan our entire application, because the physical amount of memory is in bytes, so we divide this number by 1024, Can get the amount of physical memory per unit KB.
Qmo = (environment.workingset/1024). ToString ();
Gets the fully qualified path of the current directory (that is, the directory from which the process starts)
Qcurdir = Environment.CurrentDirectory.ToString ();
Get the network domain name of the host
Qdomname = Environment.UserDomainName.ToString ();
Gets the number of milliseconds elapsed since the system started
Qtick = Environment.tickcount;
Calculates the number of minutes elapsed since the system started
Qtick/= 60000;
Get Machine Name
Qmachine = Environment.MachineName;
Gets the user name that is running the current process
Quser = Environment.username;
/* Retrieves the name of the logical drive with the format "drive letter >:\" On this computer and returns an array of strings, which is the key to next steps.
Achdrives = Directory.getlogicaldrives ();
Gets the number of dimensions for this string array, determining how many logical drives
Nnumofdrives = Achdrives.length;
}
System information does not need to be operated, we simply use Asp:label to show them out on the line. The number of logical drives is variable on different servers, so the name of the logical drive is saved with an indefinite array, and the name of the logical drive is the basis for our next browsing of directories and files, so we use a DataGrid in the data grid to display and process it.
Display and process the code for the DataGrid of the logical drive name (code in listdrivers.aspx file):
headertext= "More Information"
Datanavigateurlfield= "Drivers" datanavigateurlformatstring= "listdir.aspx?dir={0}"
Datatextfield= "Detail"
target= "_new"/>
The first two BoundColumn columns are displayed with ordinal and actual logical drive names, and the third column requires that we pass the name of the selected logical drive to the file that displays the directory before entering the various logical drives to display the directories and files. So you need a special hyperlink row HyperLinkColumn, we set the Datanavigateurlfield to the field in the data source that you want to bind to the URL of the hyperlink in HyperLinkColumn, which is the logical drive name. Datanavigateurlformatstring is then set to display the URL of the hyperlink in this hyperlinkcolumn when the URL data is bound to a field in the data source, that is, the next level of processing page to link to. Click the logical drive name of the row for the listdir.aspx?dir={user here}
To create the code for the data source (the code is in the Listdrivers.aspx.cs file):
Returns a data view of a collection form by this method DataView
ICollection CreateDataSource () {
To define a DataTable in an in-memory datasheet
DataTable dt = new DataTable ();
Defines a row of data in a DataTable DataRow
DataRow Dr;
/* Add a column to the DataTable, format: DataColumn ("Column", type)
column is the name of the data column and type is the data type of the 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 add the name of the logical drive as a row to the datasheet DataTable
for (int i = 0; I nnumofdrives i++) {
Define New Line
Dr = dt. NewRow ();
Assign values to each column in the row, and note that you want to correspond to the rows of the DataTable defined above
Dr[0] = i; Number of loops generated
DR[1] = achdrives[i]. ToString (); The name of the logical drive
DR[2] = "View Details";
Adding rows to the DataTable
Dt. Rows.Add (DR);
}
Generate custom views based on the resulting DataTable DataView
DataView dv = new DataView (DT);
Returns the resulting view DataView
return DV;
}
In this way we get a Data view DataView that contains all the data we need, and we just need to bind this data view to the DataGrid on the Page_Load method of this ASPX page.
Data binding code (code in Listdrivers.aspx.cs file):
/* Set the DataGrid data source DataSource for the Data view we obtained from the CreateDataSource () method DataView * *
Driversgrid.datasource = CreateDataSource ();
Data binding for this DataGrid
Driversgrid.databind ();
Through the main methods described above we have achieved the ability to get system information and display all logical drive names, and we can go to the next program that displays directories and file names through the appropriate links listdir.aspx displays all directories and files under that logical drive.
Program Two: Shows the program for all subdirectories and files in the directory listdir.aspx
There are two forms of subdirectories and files under the directory, which must be treated separately. We call this program itself for a list of subdirectories to display, and the file we need to call the Showfile.aspx program to display the properties and contents of the file. And there are different ways to remove them, so we've set up two DataGrid, two DataTable, two DataView to handle and display the directories and files separately.
code for displaying and processing the DataGrid of directories and files (code in listdir.aspx file):
A data column that displays the ordinal and name of a directory or file is similar to the code in the Listdrivers.aspx program and is not repeated here. There are separate processing pages for subdirectories and files, so you need to navigate to two different pages, and for subdirectories, we continue to use the Listdir.aspx program to list the subdirectories and files under them:
datanavigateurlformatstring= "Listdir.aspx?dir={0}"
Datatextfield= "Dirdetail"
headertext= "More Information"
target= "_new"
/>
For files, we use the Showfile.aspx program to display their properties and contents:
datanavigateurlformatstring= "Showfile.aspx?file={0}"
Datatextfield= "Filedetail"
headertext= "More Information"
target= "_new"
/>
In two DataGrid (Dirgrid,filegrid) We set up two separate HyperLinkColumn columns to navigate to different processing pages.
We all used a deleted button column in two datagrid:
text= "Delete"
Commandname= "Delete"
/>
Because the Add, update, delete feature columns are the default template columns for the DataGrid, you can add this column automatically through the DataGrid's Property Builder in Vs.net.
Gets the code for the parameter passed by the previous page:
The following code is used in the Page_Load method of the page, because you need to use the parameters passed over from the previous page to determine the directory and file name in the method that produces the data source below:
Strdir2list = request.querystring["dir"];
The string strdir2list the name of the directory or file name that is passed over.
Because we use two dategrid, we need two data bindings, there are two different ways to generate data sources.
How to generate a directory data grid (Dirgrid) data source:
This method returns a collection-form data View DataView, which initializes the DataGrid of the subdirectory
ICollection Createdatasourcedir () {
Dtdir = new DataTable ();
DataRow Dr;
Add a new data column to the DataTable, a total of 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));
A string array of all subdirectory names in this directory, based on the parameters passed in (directory name)
string [] direntries = Directory.getdirectories (strdir2list);
Use a Foreach loop to iterate through an array of unknown lengths
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 resulting Data view
return dvdir;
}
How to generate a file data grid (Filegrid) data source:
This method returns a collection-form data View DataView, which initializes the DataGrid for the file
ICollection 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));
A string array of all the file names in this directory, based on the parameters passed in (directory name)
string [] fileentries = Directory.GetFiles (strdir2list);
foreach (String FileName in Fileentries) {
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 programmed two DataSource to display the data in the resulting DataTable to the DataGrid on the ASPX page by only data binding to two DataGrid in the Page_Load method of the page.
Data binding Code:
Dirgrid data source definition and data binding for subdirectory data list
Dirgrid.datasource = Createdatasourcedir ();
Dirgrid.databind ();
Data source definition and data binding for file data list Filegrid
Filegrid.datasource = Createdatasourcefile ();
Filegrid.databind ();
Through the main methods described above, we have implemented a list of all subdirectories and files in a logical drive or directory, and can further browse subdirectories or view the properties and content feeds of a file based on the results displayed. Browsing subdirectories is still done by listdir.aspx this program, without any subdirectory level requirements, no directory depth restrictions.
The primary method and code for deleting subdirectories and files:
When we delete subdirectories, we need to use the Directory.delete (String,bool) method, which has two kinds of methods:
1. public static void Delete (string);
Deletes an empty directory from the specified path.
2. public static void Delete (String, Boolean);
Deletes the specified directory and, if indicated, deletes any subdirectories in the directory, and if Boolean is set to True, deletes all subdirectories and files under this directory, or sets the Boolean to False.
Here we use the second method, and if you choose to delete it, all subdirectories and files in this directory will be deleted.
Note: All of the methods of the directory class are static and can be invoked without having an instance of directory directory.
/* Implement the method of deleting subdirectories, this method is automatically added to vs.net, note that DataGridCommandEventArgs E is the ButtonColumn event for Commandname= "Delete" in Dirgrid, through this event, We can get the name of the ButtonColumn button column that is clicked, and then determine what subdirectory we need to delete.
private void Dirgrid_deletecommand (object source, System.Web.UI.WebControls.DataGridCommandEventArgs e) {
/* Define a cell, e.item all items that occur for this event, E.item.cells[1] as the contents of the second cell of the entire row, in this DataGrid the name of the subdirectory
*/
TableCell Itemcell = e.item.cells[1];
A string that gets the name of this subdirectory
string item = Itemcell.text;
Delete this subdirectory
Directory.delete (item,true);
Data binding to update the list of data after deletion
Dirgrid.databind ();
}
When we delete the file, we need to use File.delete (string path);
Note: All methods of the File class are static and can be invoked without having an instance of the directory.
private void Filegrid_deletecommand (object source,
System.Web.UI.WebControls.DataGridCommandEventArgs e) {
TableCell Itemcell = e.item.cells[1];
A string that gets the name of this file
string item = Itemcell.text;
Delete this file
File.delete (item);
Data binding to update the list of data after deletion
Dirgrid.databind ();
}
Through the main method above we implemented a deletion of a subdirectory or file on the page function, this feature needs to be used carefully in testing, once the deletion can not be restored through the normal method. Other methods such as directory or file renaming, modify content, etc. can be added to the program based on the corresponding functions, the implementation method is also very simple. Enthusiasts can expand to a web-based server file management system by adding the appropriate functionality. We can also see the dangers of this program, and a file system for a server that does not take precautions against this security risk is exposed to users who use this program.
Program Three: Programs that display file properties and content showfile.aspx
Two main classes that need to be used when displaying properties and content:
System.IO.FileInfo: Provides instance methods for creating, copying, deleting, moving, and opening files, and helps create FileStream objects.
System.IO.StreamReader: Implements a TextReader that reads characters from a byte stream in a specific encoding. Unless otherwise specified, the default encoding for StreamReader is UTF-8, not the ANSI code page for the current system. UTF-8 can correctly handle Unicode characters and provide consistent results on localized versions of the operating system.
Showfile.aspx page main code:
We just display the file's property information and some of the content on this label. So there's no other complicated code.
The main code for obtaining file information and content is in the Page_Load method (the code is in the Showfile.aspx.cs file):
Receive incoming arguments to determine the name of the file that needs to be manipulated
Strfile2show = request.querystring["file"];
Instantiate a FileInfo object based on the filename
FileInfo fi = new FileInfo (strfile2show);
Filedetail.text = "FileName:";
Filedetail.text + + strfile2show+ "<br>";
Filedetail.text + = "File Size";
Gets the size of the file, and then transforms the unit to KB
Filedetail.text + = (fi. length/1024). ToString () + "K <br>";
Filedetail.text + = "Create file time:";
Get the date the file was created
Filedetail.text + = fi. Creationtime.tostring ();
Filedetail.text + = "Last accessed time:";
Get last accessed date of file
Filedetail.text + = fi. Lastaccesstime.tostring () + "<br>";
Filedetail.text + = "Last Write time:";
Get the last write date of a file
Filedetail.text + = fi. Lastwritetime.tostring () + "<br>";
Instantiates a StreamReader object to read the contents of this FileInfo
StreamReader FileReader = fi. OpenText ();
Defines a character array of length 1000 as a buffer
char[] Thebuffer = new char[1000];
/*readblock method: Reads the maximum number of characters from the current stream and writes the data to the buffer starting at the index.
Parameters:
char[] Buffer: When method returns, contains the specified array of characters
Where to begin writing in int index:buffer
int count: The maximum 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 associated with it
Filereader.close ();
So far, we have implemented a simple Web page Server Disk Management application that can view, delete directories and files. If you need to modify the files, new files and folders, and so on, just a little change, add the appropriate code on it. Since we are only using this program to describe the security risks that exist in the server, these features are no longer implemented here.
Through these three simple programs, I think we have been able to clearly understand the harm of this loophole, if we do not take precautions, other users of the program can be malicious use of this feature users to view, delete, the server's system log, system files, there is no security to speak of.