ASP. NET Virtual Host Security Vulnerability Solution

Source: Internet
Author: User
Tags asp net ntfs permissions
Note: The environment required in this article is 2003 SERVER + iis6.0 + MS SQL2000

I once saw an article on the Internet about <major risks of Asp.net virtual hosts> for a long time. At that time, I did not care about it. Anyone who has worked on ASP virtual hosts may know that, that is to say, setting an independent server user and operation permission for a single directory for each user can basically solve the FSO problem of ASP.

I accidentally discovered an Asp.net-webshell called WebAdmin on the Internet. When I tested my server, I was surprised that I had read permission on the C drive of my server. And modify and delete permissions for the entire hard disk. In this case, the security of my server ......

To further confirm that I have performed tests on some well-known virtual host providers in China, all of which share the same issues with me.

It is necessary to first introduce the cause of the vulnerability.

Commonly used standard component in ASP: FileSystemObject, which provides powerful file system access capabilities for ASP, you can read, write, delete, and rename any directories and files on the server's hard disk. The FSO object comes from the script running library scrrun. dll provided by Microsoft.

In ASP. NET, we found that this problem still exists and becomes more difficult to solve. This is because. net, and ASP. net has a new function, this component does not need to use regsvr32 for registration as ASP does, you just need to upload the DLL class library file to the bin directory to use it directly. This function is designed for ASP development. net brings a lot of convenience, but it makes the solution that we delete or rename this DLL in ASP useless, so it becomes more complicated to prevent this problem. For more information, see <major risks of Asp.net VM>. This issue only leads to the security settings of the VM.

In response to this problem, I used Microsoft. NET Framework configration to set the directory read permission for system. Io. After a long period of test, we failed. may be because the. NET framework1.1 mechanism has been reformed?

Don't talk nonsense. Let's talk about the solution: in IIS 6, the Web application's working process is set to run with the process ID "network service. In IIS 5, the off-process web application is set to run with the IWAM _ <Server Name> account, which is a common local user account.

Network Service is a built-in account in Windows Server 2003. It is important to know the difference between the local user account (IUSR and IWAM) on IIS 5 and the built-in account. In Windows, all accounts are assigned a SID (Security ID ). The server identifies all accounts on the server based on the SID rather than the SID-related name. When we interact with the user interface, the server uses the name for interaction. The vast majority of accounts created on the server are local accounts with a unique SID used to identify members of the user database of the server. Because the SID is unique relative to the server, it is not valid on any other system. Therefore, if you assign NTFS permissions for a file or folder to your local account, and then copy the file and its permissions to another computer, there is no user account for this Sid migration on the target computer, even if there is an account with the same name on it. This makes it possible to replicate the content containing the NTFS permission.

A built-in account is a special type of account or group created by the operating system, such as the system account, network service, and everyone group. One of the important features of these objects is that they have the same and well-known Sid on all systems. When a file with NTFS permissions is copied to a built-in account, the permissions are valid between servers because the SID of the built-in account is the same on all servers. The Network Service account in the Windows Server 2003 Service is specially designed to provide sufficient network access permissions for applications. In IIS 6, you can run Web applications without privilege escalation. This is an extremely large message for IIS security. Because there is no buffer overflow, malicious applications cannot decrypt the process ID, or attacks against applications cannot enter the system user environment. More importantly, you can no longer create "backdoors" for the system account. For example, you can no longer use the inprocessisapiapps metadatabase to use the applications loaded to inetinfo.

When creating a network service account, you not only consider applications in IIS 6. It also has most (not all) permissions for w3wp.exe. For example, to run an Asp.net application, an ASP net user must have access permissions at certain locations on the IIS 5 Server. The process identification w3wp.exe must also have access permissions at similar locations, in addition, some built-in groups are not assigned permissions by default.

For ease of management, the iis_wpg group (also known as IIS Worker Process Group, IIS Worker Process Group) was created when IIS 6 was installed, and its members include local system (local system) local service, network service, and IWAM account. Iis_wpg members have the appropriate NTFS permissions and necessary user permissions, and can act as the process ID of the Worker Process in IIS 6.

Therefore, the network service account provides the permissions to access the above locations, and has sufficient permissions to act as the process ID of the IIS 6 worker process, as well as the permissions to access the network.

In Windows Server 2003, the user context is called network service. These user accounts are created during. NET Framework installation. They have a unique password that is not easy to crack and are only granted limited permissions. ASPnet or network service users can only access specific folders required to run Web applications, such as the/bin directory where Web applications store compiled files.

To set the process identity as a specific user name to replace the ASPNET or network service user identity, the user name and password you provide must be stored in the machine. config file.

However, according to the actual situation, the system. Io of Asp.net can have unlimited access to the undefended server path. I don't know if this is a major Ms vulnerability. Moreover, IIS cannot execute the Asp.net program as a machine. config user. J

How can this problem be solved? The answer is-application pool.

IIS 6.0 runs in two different operating modes called Application Isolation Mode (Isolation Mode): Working Process Isolation Mode and IIS 5.0 Isolation Mode. Both modes depend on HTTP. sys as Hypertext Transfer Protocol (HTTP) listeners. However, their internal working principles are completely different.

The work process Isolation Mode utilizes the re-designed architecture of IIS 6.0 and uses the core components of the work process. IIS 5.0 isolation mode is used for applications that depend on specific functions and behaviors of IIS 5.0. This isolation mode is specified by the iis5isolationmodeenabled configuration database attribute.

The Isolation Mode of your selected IIS application affects performance, reliability, security, and functional availability. Working Process Isolation Mode is recommended for IIS 6.0 operations because it provides a more reliable platform for applications. The work process Isolation Mode also provides a higher level of security, because the application running in the work process is identified as NetworkService by default.

The default ID of an application running in IIS 5.0 Isolation Mode is LocalSystem, which allows access and has the ability to change almost all resources on the computer.

IIS Functions IIS 5.0 Isolation Mode host/component Worker Process Isolation Mode host/component
Workflow Management N/ Svchost.exe/WWW Service
Worker Process N/ W3wp.exe/Worker Process
ISAPI extension in the running process Inetinfo.exe W3wp.exe
External ISAPI extension for Running Processes Dllhost.exe N/A (all ISAPI extensions are in process)
Run ISAPI filter Inetinfo.exe W3wp.exe
Configure svchost.exe/WWW Service in HTTP. sys Svchost.exe/WWW Service
HTTP support Windows kernel/HTTP. sys Windows kernel/HTTP. sys
IIS configuration database Inetinfo.exe Inetinfo.exe
FTP Inetinfo.exe Inetinfo.exe
NNTP Inetinfo.exe Inetinfo.exe
SMTP Inetinfo.exe Inetinfo.exe

 
It can be seen that we can only use the Working Process Isolation Mode to solve. Net security problems.
By default, IIS 6.0 runs in work process isolation mode, as shown in Figure 5. In this mode, for each web application, IIS 6.0uses an independent w3wp.exe instance to run it. W3wp.exe is also called a worker process or w3core.

Reliability and security. The reliability is improved because the failure of a Web application does not affect other Web applications, nor does it affect HTTP. SYS. W3SVC independently monitors the health status of each web application. Security is improved because the application is no longer running in the way of IIS 5.0 and IIS 4.0. all instances of w3wp.exe run under a "Network Service" account with limited permissions, as shown in figure 6. If necessary, you can also configure a workflow to run with another user account.

Right. Here, this is the core of our solution.

Each website is assigned an independent application pool with different permissions. Can this problem be solved?

How to do this? I will demonstrate how to create a website:

First, we create two users for the website (one is app_test_user, the password is appuser, the other is iis_test_user, And the password is iisuser)

1. Open the Computer Manager

2. Choose user> Computer Management> System Tools> local users and groups> users in the console tree.

3. Click "new user" in the "operations" menu and enter the user name. App_test_user. The password is appuser.

4. type the appropriate information in the dialog box.

5. Select the check box:

The user cannot change the password.

Password Never Expires

6. Click create, and then click Close ".

Follow these steps to create an iis_test_user account

Then, app_test_user is added to the iis_wpg group and iis_test_user is added to the guests group. Delete other groups.

Then, create an application pool.

Choose Internet Information Service> Local Computer> application pool> New> application pool

Create an application pool named Test

Edit the properties of the test application pool → flag → configuration → user name → browse → change the user name to the app_test_user we just created and enter the corresponding Password

Create a website.

Choose Internet Information Service> Local Computer> website> New> test. The directory is D: /test → edit the properties of the test website → home directory → application pool → app_test_user → Directory Security → authentication and access control → edit, select the iis_test_user we just created, enter the password iisuser → save and exit.

Finally, set the server security.

C: only give administrators and systems full control of permissions. Delete all other permissions without replacing subdirectories.

C:/Documents and Settings inherit the parent item and replace the subdirectory.

C:/Program Files inherits the parent item, replaces the subdirectory, deletes the C:/program files/common files/Microsoft shared inheritance attribute, and copies the existing attribute, add the users read permission and replace the sub-directories (to enable ASP and Asp.net to use access and other databases ).

C:/Windows: Delete the inheritance and copy the existing attributes. Only the Administrator and system are given full control over the permissions to read users and replace the subdirectories.

All other disks only give full control permissions to Administrators and System users, delete all other users and replace subdirectories.

D:/test (user's website directory) inherits the existing attributes, adds the permissions fully controlled by app_test_user and iis_test_user, and replaces the subdirectories.

And so on for every website added later.

However, at this point, system. i/O still has read permissions on C:/Windows (it is suspected that the network servers user belongs to the users group, but many services must use the Users Group for execution, so C: /windwos removes the Users Group's read permission) but must know the system path. There are two solutions.

1. When installing the system again, use unattended installation and change the default installation path of C:/Windows, for example, to C:/testtest (to comply with DOS naming rules, cannot exceed 8 characters ). This is required

2. permissions assigned to iis_wpg are as follows:

% WINDIR %/help/IISHelp/common-read
% WINDIR %/IIS temporary compressed files-list, read, and write
% WINDIR %/system32/inetsrv/asp compiled template-read
Inetpub/wwwroot (or content directory)-read and execute

Iis_wpg also has the following User Permissions:

Ignore traversal check (sechangenotifyprivilege)

Log on as a batch job (SeBatchLogonRight)

Access this computer from the network (SeNetworkLogonRight)

Of course, the combination of the two methods is the safest solution. Generally, the first solution is safe, after all, it takes time to guess the 8-character directory using a webshell. Firewall can be easily detected and controlled.

The second possibility is to add the directory read permission based on the installed software. The details should be determined based on the software.

If there are many host users, this will be a considerable amount of labor. We recommend that you use a program to solve the problem, the following code is not common online operations on the IIS application pool and on the IIS virtual directory.

Operate the IIS application pool

Using system;
Using system. directoryservices;
Using system. reflection;

Namespace adsi1
{
///
/// Small class containing methods to configure IIS.
///
Class configiis
{
///
/// The main entry point for the application.
///
[Stathread]
// Main program portal, which can be used? I wrote all the functions for convenience.
Static void main (string [] ARGs)
{
String apppoolname = "myapppool ";
String newvdir1 = "myvdir ";
Directoryentry newvdir = createvdir (newvdir1 );

Createapppool (apppoolname );
Assignapppool (newvdir, apppoolname );

Configapppool ("stop", apppoolname );
}

// Create a virtual directory
Static directoryentry createvdir (string vdirname)
{
Directoryentry newvdir;
Directoryentry root = new directoryentry ("IIS: // localhost/w3svc/1/root ");
Newvdir = root. Children. Add (vdirname, "iiswebvirtualdir ");
Newvdir. properties ["path"] [0] = "C: // inetpub // wwwroot ";
Newvdir. properties ["accessscript"] [0] = true;
Newvdir. commitchanges ();
Return newvdir;
}

// Create a new application pool.
Static void createapppool (string apppoolname)
{
Directoryentry newpool;
Directoryentry apppools = new directoryentry ("IIS: // localhost/w3svc/apppools ");
Newpool = apppools. Children. Add (apppoolname, "iisapplicationpool ");
Newpool. commitchanges ();
}

Static void assignapppool (directoryentry newvdir, string apppoolname)
{
Object [] Param = {0, apppoolname, true };
Newvdir. Invoke ("appcreate3", Param );
}

// Method is the method used to manage the application pool. There are three methods: start, stop, and recycle, while apppoolname is the name of the application pool.
Static void configapppool (string method, string apppoolname)
{
Directoryentry apppool = new directoryentry ("IIS: // localhost/w3svc/apppools ");
Directoryentry findpool = apppool. Children. Find (apppoolname, iisapplicationpool ");
Findpool. Invoke (method, null );
Apppool. commitchanges ();
Apppool. Close ();
}

// List of application pools
Static void apppoollist ()
{
Directoryentry apppool = new directoryentry ("IIS: // localhost/w3svc/apppools ");
Foreach (directoryentry A in apppool. Children)
{
Console. writeline (A. Name );
}
}

Private void vdirtoapppool ()
{
Directroryentry Vd = new directoryentry ("IIS: // localhost/w3svc/1/root/CCC ");
Console. writeline (VD. properties ["apppoolid"]. value. tostring ());
}
}
}

IIS6 operation example

Using system;
Using system. directoryservices;
Using system. collections;
Using system. Text. regularexpressions;
Using system. text;

Namespace wuhy. toolbox
{
/// </Summary>

Public class iisadminlib
{
# Region username, password, and hostname
Public static string hostname
{
Get
{
Return hostname;
}
Set
{
Hostname = value;
}
}

Public static string Username
{
Get
{
Return username;
}
Set
{
Username = value;
}
}

Public static string Password
{
Get
{
Return password;
}
Set
{
If (username. Length <= 1)
{
Throw new argumentexception ("the user name has not been specified. Specify the user name first ");
}
Password = value;
}
}

Public static void remoteconfig (string hostname, string username, string password)
{
Hostname = hostname;
Username = username;
Password = password;
}

Private Static string hostname = "localhost ";
Private Static string username;
Private Static string password;
# Endregion

# Region method for constructing an entry based on the path

/// <Summary>
/// Determine whether the server is a remote server based on the user name.
/// Then construct different directoryentries
/// </Summary>
/// <Param name = "entpath"> directory of directoryentry </param>
/// <Returns> the returned value is the directoryentry instance. </returns>

Public static directoryentry getdirectoryentry (string entpath)
{
Directoryentry ent;
If (username = NULL)
{
Ent = new directoryentry (entpath );
}
Else
{
// Ent = new directoryentry (entpath, hostname + "//" + username, password, authenticationtypes. Secure );
Ent = new directoryentry (entpath, username, password, authenticationtypes. Secure );
}
Return ent;
}

# Endregion
# How to add and delete a website using region

/// <Summary>
/// Create a new website. Configure Based on the passed information
/// </Summary>
/// <Param name = "siteinfo"> stores information about the new website. </param>

Public static void createnewwebsite (newwebsiteinfo siteinfo)
{
If (! Ensurenewsiteenavaible (siteinfo. bindstring ))
{
Throw new duplicatedwebsiteexception ("You already have such a website. "+ Environment. newline + siteinfo. bindstring );
}
String entpath = string. Format ("IIS: // {0}/W3SVC", hostname );
Directoryentry rootentry = getdirectoryentry (entpath );
String newsitenum = getnewwebsiteid ();
Directoryentry newsiteentry = rootentry. Children. Add (newsitenum, "iiswebserver ");
Newsiteentry. commitchanges ();
Newsiteentry. properties ["serverbindings"]. value = siteinfo. bindstring;
Newsiteentry. properties ["servercomment"]. value = siteinfo. commentofwebsite;
Newsiteentry. commitchanges ();
Directoryentry vdentry = newsiteentry. Children. Add ("root", "iiswebvirtualdir ");
Vdentry. commitchanges ();
Vdentry. properties ["path"]. value = siteinfo. webpath;
Vdentry. commitchanges ();
}

/// <Summary>
/// Delete a website. Delete a Website Based on its name.
/// </Summary>
/// <Param name = "sitename"> website name </param>

Public static void deletewebsitebyname (string sitename)
{
String sitenum = getwebsitenum (sitename );
String siteentpath = string. Format ("IIS: // {0}/w3svc/{1}", hostname, sitenum );
Directoryentry siteentry = getdirectoryentry (siteentpath );
String rootpath = string. Format ("IIS: // {0}/W3SVC", hostname );
Directoryentry rootentry = getdirectoryentry (rootpath );
Rootentry. Children. Remove (siteentry );
Rootentry. commitchanges ();
}

# Endregion
# Region start and stop website Methods

Public static void startwebsite (string sitename)
{
String sitenum = getwebsitenum (sitename );
String siteentpath = string. Format ("IIS: // {0}/w3svc/{1}", hostname, sitenum );
Directoryentry siteentry = getdirectoryentry (siteentpath );
Siteentry. Invoke ("START", new object [] {});
}

Public static void stopwebsite (string sitename)
{
String sitenum = getwebsitenum (sitename );
String siteentpath = string. Format ("IIS: // {0}/w3svc/{1}", hostname, sitenum );
Directoryentry siteentry = getdirectoryentry (siteentpath );
Siteentry. Invoke ("stop", new object [] {});
}

# Endregion
# Region check whether the website is the same

/// <Summary>
/// Confirm that a new website is not the same as an existing one.
/// This prevents illegal data from being stored in IIS
/// </Summary>
/// <Param name = "bindstr"> website binding information </param>
/// <Returns> it can be created, but cannot be created if it is false. </returns>

Public static bool ensurenewsiteenavaile (string bindstr)
{
String entpath = string. Format ("IIS: // {0}/W3SVC", hostname );
Directoryentry ent = getdirectoryentry (entpath );
Foreach (directoryentry child in Ent. Children)
{
If (child. schemaclassname = "iiswebserver ")
{
If (child. properties ["serverbindings"]. value! = NULL)
{
If (child. properties ["serverbindings"]. value. tostring () = bindstr)
{
Return false;
}
}
}
}
Return true;
}

# Endregion
# Region How To Get A website number
/// <Summary>
/// Obtain the ID of a website. Determine the website number based on the serverbindings or servercomment of the website.
/// </Summary>
/// <Param name = "sitename"> </param>
/// <Returns> return website id </returns>
/// <Exception CREF = "notfoundwebsiteexception"> indicates that no website is found. </exception>

Public static string getwebsitenum (string sitename)
{
RegEx = new RegEx (sitename );
String tmpstr;
String entpath = string. Format ("IIS: // {0}/W3SVC", hostname );
Directoryentry ent = getdirectoryentry (entpath );
Foreach (directoryentry child in Ent. Children)
{
If (child. schemaclassname = "iiswebserver ")
{
If (child. properties ["serverbindings"]. value! = NULL)
{
Tmpstr = Child. properties ["serverbindings"]. value. tostring ();
If (RegEx. Match (tmpstr). Success)
{
Return child. Name;
}
}
If (child. properties ["servercomment"]. value! = NULL)
{
Tmpstr = Child. properties ["servercomment"]. value. tostring ();
If (RegEx. Match (tmpstr). Success)
{
Return child. Name;
}
}
}
}

Throw new notfoundwebsiteexception ("the site we want is not found" + sitename );
}

# Endregion
# Region method for obtaining the new website ID
/// <Summary>
/// Obtain the smallest ID that can be used in the website system.
/// This is because each website requires a unique ID, and the smaller the number, the better.
/// The above algorithms have been tested and there is no problem.
/// </Summary>
/// <Returns> Minimum id </returns>

Public static string getnewwebsiteid ()
{
Arraylist list = new arraylist ();
String tmpstr;
String entpath = string. Format ("IIS: // {0}/W3SVC", hostname );
Directoryentry ent = getdirectoryentry (entpath );
Foreach (directoryentry child in Ent. Children)
{
If (child. schemaclassname = "iiswebserver ")
{
Tmpstr = Child. Name. tostring ();
List. Add (convert. toint32 (tmpstr ));
}
}
List. Sort ();
Int I = 1;
Foreach (Int J in List)
{
If (I = J)
{
I ++;
}
}
Return I. tostring ();
}
# Endregion
}

# Region new website information structure

Public struct newwebsiteinfo
{
Private string hostip; // The hosts IP Address
Private string portnum; // The new web sites port. Generally is "80"
Private string descofwebsite; // indicates the website. Generally, it is the website name. For example, "www.dns.com.cn"
Private string commentofwebsite; // website comment. It is also the website name of the website.
Private string webpath; // The Home Directory of the website. For example, "E:/tmp"
Public newwebsiteinfo (string hostip, string portnum, string descofwebsite, string commentofwebsite, string webpath)
{
This. hostip = hostip;
This. portnum = portnum;
This. descofwebsite = descofwebsite;
This. commentofwebsite = commentofwebsite;
This. webpath = webpath;
}
Public String bindstring
{
Get
{
Return string. Format ("{0 }:{ 1 }:{ 2}", hostip, portnum, descofwebsite );
}
}
Public String commentofwebsite
{
Get
{
Return commentofwebsite;
}
}
Public String webpath
{
Get
{
Return webpath;
}
}
}
# Endregion
}

So far, a relatively secure. Net host has been established. With the release of. net2.0 approaching, it is hoped that Ms can properly prevent this problem.

We have briefly introduced ASP. this method is cumbersome in the prevention and control of file I/O system vulnerabilities in. net, but it can fundamentally eliminate some vulnerabilities. We only discuss a few of them, more solutions should be explored and learned together.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.