Asp.net| Security | security Vulnerabilities | troubleshooting | Virtual Host Description: The environment required in this article is 2003server+iis6.0+ms sql2000
Once very early on the Internet to see an article on the <asp.net virtual host of the major hidden dangers, at that time did not care, did the ASP virtual host friends may know, that is, each user set up a separate server users and a single directory operation rights, can basically solve the ASP's FSO problem.
Inadvertently found on the internet a Asp.net-webshell called WebAdmin, the test of their own server, let me surprise, incredibly to my Server C disk has Read permissions. and modify the entire hard drive to remove permissions. In this case, then my server is secure ...
In order to further confirm, I have in some well-known domestic virtual hosting providers have been tested, and I have the same problem.
It is necessary to introduce the cause of the loophole first.
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.
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. Need to know more friends can see <asp.net virtual host of the major hidden dangers, this article will not repeat. The security settings for the virtual host are only raised for this issue.
On the Internet, it is possible that the. NET framework1.1 mechanism has been reformed to set the System.IO Read permissions on the directory with Microsoft. NET Framework configration for this issue, after our long test failure.
Nonsense not to say. Let's talk about the solution: in IIS 6, the WEB application's worker process is set to run with the process identity "network Service." In IIS 5, out-of-process Web applications are set to run with the iwam_< server name > account, which is an ordinary local user account.
The network Service is a built-in account in Windows Server 2003. It is important to understand the difference between the local user account (IUSR and IWAM) on IIS 5 and this built-in account. All the accounts in the Windows operating system are assigned a SID (security identity, and the safety ID). The server identifies all accounts on the server based on the SID, not the name associated with the SID, and we interact with the user interface by using a name. The vast majority of the accounts created on the server are local accounts and have a unique SID that identifies the members of this account as belonging to the server user database. Because the SID is unique only relative to the server, it is not valid on any other system. Therefore, if you assign NTFS permissions for a file or folder to a local account, and then copy the file and its permissions to another computer, there is no user account on the target computer for the migrated SID, even if it has an account with the same name. This can cause problems with content replication that contains NTFS permissions.
A built-in account is a special type of account or group created by the operating system, such as the system account, the network Service, and the Everyone group. One of the important features of these objects is that they have an identical, well-known SID on all systems. When you copy a file that is assigned NTFS permissions to a built-in account, 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 specifically designed to provide applications with sufficient permissions to access the network, and in IIS 6, you can run WEB applications without elevated privileges. This is a very large message for IIS security because there is no buffer overflow, a malicious application cannot decipher the process identity, or an attack on an application cannot enter the System user environment. More importantly, it is no longer possible to form a "backdoor" for the System account, for example, to use applications loaded into Inetinfo again through InProcessIsapiApps metabase entries.
The network Service account was created with an application that was not only considered in IIS 6. It also has the most (not all) permissions of the process identity W3WP.exe. Just as the ASPNET user needs access to certain locations on the IIS 5 server in order to run the ASP.net application, the process identity W3WP.exe needs to have access to a similar location and requires some permissions that are not assigned to the built-in group by default.
For ease of administration, the IIS_WPG group (also known as the IIS Worker process group, IIS worker processes groups) was created at the time of installation of IIS 6 o'clock, and its members include the Local System (LocalSystem), the local Service (native services), N Etwork Service (network services) and IWAM accounts. IIS_WPG members have the appropriate NTFS permissions and the necessary user rights to act as process identities for worker processes in IIS 6.
Therefore, the network Service account provides access to the above location, has sufficient permissions to act as a process identity for the IIS 6 worker process, and has access to the network.
MSDN says: In Windows Server 2003, the user context is called the network SERVICE. These user accounts were created during the. NET Framework installation and have unique passwords that are not easily cracked and are granted limited permissions. The ASPNET or network SERVICE user can access only the specific folders needed to run the Web application, such as the bin directory where the Web application stores the compiled files.
To set the process identity to a specific user name in place of 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, ASP.net's System.IO can unrestricted access to the undefended server path. I don't know if this is a major loophole for Ms. And you simply cannot allow IIS to execute ASP.net programs with machine.config users. J
How to solve it? The answer is-application pools.
IIS 6.0 runs in two different operating modes known as application isolation mode (isolation mode): Worker process isolation mode and IIS 5.0 isolation mode. Both of these modes rely on HTTP.sys as Hypertext Transfer Protocol (HTTP) listeners, but their internal workings are very different.
Worker process isolation mode leverages the redesigned architecture of IIS 6.0 and uses the core components of the worker process. IIS 5.0 isolation mode is used for applications that rely on the specific features and behavior of IIS 5.0. The isolation mode is specified by the IIs5IsolationModeEnabled metabase property.
The IIS application isolation mode that you choose will have an impact on performance, reliability, security, and feature availability. Worker process isolation mode is the recommended mode for IIS 6.0 operations because it provides a more reliable platform for applications. Worker process isolation mode also provides a higher level of security because the default identification of an application running in a worker process is NetworkService.
The default identity for 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 features IIS 5.0 isolation mode Host/component worker process isolation mode Host/component worker process Management N/asvchost.exe/www service worker process N/A w3wp.exe/worker process run in process ISAPI Extended Inetinfo.exeW3wp.exe Run an out-of-process ISAPI extension dllhost.exen/a (all ISAPI extensions are in process) run the ISAPI filter Inetinfo.exeW3wp.exeHTTP.sys configuration The SVCHOST.EXE/WWW Service SVCHOST.EXE/WWW Service HTTP protocol supports the Windows kernel/http.syswindows kernel/ Http.sysiis Configuration Database Inetinfo.exeInetinfo.exeFTPInetinfo.exe INETINFO.EXENNTP Inetinfo.exeInetinfo.exeSMTPInetinfo.exeInetinfo.exe
This shows that we can only use worker process isolation mode to resolve. NET security issues.
By default, IIS 6.0 runs in worker process isolation mode, as shown in Figure five. In this mode, for each Web application, IIS 6.0 runs it with a separate w3wp.exe instance. W3wp.exe is also known as a worker process, or w3core.
Reliability and security. The improvement in reliability is due to the failure of a Web application that does not affect other Web applications and does not affect HTTP.sys, where each Web application monitors its health independently by W3SVC. Security is increased because applications are no longer running with the system account as in-process applications for IIS 5.0 and IIS 4.0, and by default all instances of W3wp.exe run under a limited network Service account, as shown in Figure six and, if necessary, You can also configure a worker process to run with a different user account.
Right, here, this is the core of our solution.
We assign each site a separate application pool and give different permissions. Can we solve this problem?
How to do it, I would like to set up a website to do a demonstration:
First, we create two users for the website (one is app_test_user, the password is appuser, one is Iis_test_user, the password is iisuser)
1. Open Computer Manager
2. Click Users in the console tree → Computer Management → system tools → local Users and groups → users
3. Click New User on the Action menu to enter the user name. App_test_user, password for appuser
4. Type the appropriate information in the dialog box.
5. Select the check box:
User Cannot change password
Password never expires
6. Click Create, and then click Close.
Follow this method to create a Iis_test_user account
Then add the App_test_user to the IIS_WPG group and add the Iis_test_user to the Guests group. Delete other groups.
Then, create the appropriate application pool.
Turn on Internet Information Services → local computer → application pool → new → application pool
Create a new application pool with the name test
Edit test application pool properties → logo → configuration → username → browse → change the username to the app_test_user we just created and enter the appropriate password
Second, establish the corresponding website.
Turn on Internet Information Services → local computer → site → new →test Web site, directory for d:\test→ edit test Site properties → home directory → application pool →app_test_user→ directory security → authentication and access control → edit, Select the Iis_test_user we just established and enter the appropriate password iisuser→ save and exit.
Finally, set the security of the server.
C: Only full control of the administrators and system rights, remove all other permissions, do not replace subdirectories
C:\Documents and settings inherit the parent and replace the subdirectory.
C:\Program Files inherits the parent, replaces the subdirectory, and deletes the C:\Program Files\Common Files\Microsoft shared inherited properties and copies the existing properties. Increase the Read access for users and replace subdirectories (this is to enable asp,asp.net to use databases such as access).
C:\windows deletes inheritance and copies existing attributes, giving only administrators,system Full Control and users read permissions and replacing subdirectories.
All remaining disks give full control to the administrators and system users, removing all other users and substituting subdirectories.
D:\test (User Site Directory) inherits existing attributes and increases App_test_user and Iis_test_user Full Control permissions and replaces subdirectories.
And so on each additional site later.
However, at this point, System.IO still read permissions on C:\Windows, (suspected network servers users belong to the Users group, but many services are to be performed using the Users group, so the C:\ Windwos Remove the Users group's read permissions) but must know the system path, there are two solutions.
1, reinstall the system when the use of unattended installation, replacement c:\windows default installation path, such as change to C:\testtest (to comply with DOS naming rules, can not exceed 8 characters). This is necessary.
2. The following locations have permissions assigned to IIS_WPG:
%windir%\help\iishelp\common– Read
%windir%\iis Temporary Compressed files– list, read, write
%windir%\system32\inetsrv\asp Compiled template– Read
Inetpub\Wwwroot (or content directory)-Read, execute
In addition, IIS_WPG has the following user rights:
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, the general use of the first scheme is very safe, after all, it is a webshell to guess 8-bit characters of the directory or it will take time. It's easy to detect and control using firewalls.
The second may be based on the installation of the software and the corresponding increase in the directory Read permissions, details to be determined by the software.
If the host user is more, this will be a considerable amount of labor, recommend the use of procedures to solve the problem, the following is an uncommon online code for IIS application pool operations and operation code for IIS virtual directories.
Manipulating IIS Application Pools
Using System;
Using System.DirectoryServices;
Using System.Reflection;
Namespace ADSI1
{
///
Small class containing methods to configure IIS.
///
Class Configiis
{
///
The main entry point is for the application.
///
[STAThread]
Main program entrance, can choose to use which, I for convenience, all functions are written up.
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 a way to manage an application pool with three start, Stop, recycle, and AppPoolName as the application pool name
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 ());
}
}
}
Examples of IIS6 operations
Using System;
Using System.DirectoryServices;
Using System.Collections;
Using System.Text.RegularExpressions;
Using System.Text;
Namespace Wuhy.toolbox
{
</summary>
public class Iisadminlib
{
Definition of #region Username,password,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 ("No good user name has been specified.") Please specify 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
The method of constructing entry based on the path of #region
<summary>
Determines whether a remote server is based on a user name.
And then construct a different DirectoryEntry.
</summary>
<param name= "Entpath" >directoryentry path </param>
The <returns> returns a 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
#region ways to add and remove Web sites
<summary>
Create a new Web site. Configure according to the information that is passed over
</summary>
<param name= "Siteinfo" stores information for the new Web site </param>
public static void Createnewwebsite (Newwebsiteinfo siteinfo)
{
if (! Ensurenewsiteenavaible (siteinfo.bindstring))
{
throw new Duplicatedwebsiteexception ("already has a website like this." "+ 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>
Deletes a web site. Delete according to site name.
</summary>
<param name= "SiteName" > site 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 the start and stop Web 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 confirm that the site is the same
<summary>
Make sure that a new site is not the same as the existing site.
This prevents the illegal data from being stored in IIS.
</summary>
<param name= "Bindstr" > website bonding information </param>
<returns> true to be created, false to be created </returns>
public static bool Ensurenewsiteenavaible (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
How to #region get a site number
<summary>
Gets the number of a Web site. According to the site's serverbindings or servercomment to determine the site number
</summary>
<param name= "SiteName" > </param>
<returns> return number of Web site </returns>
<exception cref= "Notfoundwebsiteexception" indicates that the site was not found </exception>
public static string Getwebsitenum (String siteName)
{
Regex 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 to child. Name;
}
}
if (child. properties["ServerComment"]. Value!= null)
{
TMPSTR = child. properties["ServerComment"]. Value.tostring ();
if (regex). Match (TMPSTR). Success)
{
Return to child. Name;
}
}
}
}
throw new Notfoundwebsiteexception ("did not find the site we want" + siteName);
}
#endregion
#region ways to get new site IDs
<summary>
Gets the smallest ID that can be used within the Web site system.
This is because each site needs to have a unique number, and the smaller the number the better.
There is no problem with the algorithm being tested.
</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; The website says. The site name for the Web site generally. such as "www.dns.com.cn"
private string commentofwebsite;//site comment. Typically also the site name for the site.
private string Webpath; The home directory of the Web site. such as "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
}
At this point, a relatively secure. NET host is built up, with the release of net2.0 more and more close, I hope that Ms can be a proper precaution against this problem.
We have briefly introduced the asp.net of the file IO system in the prevention of vulnerabilities, this method is a bit cumbersome, but it can fundamentally eliminate some loopholes, we discuss only a small part of more solutions to put the law need everyone to explore and learn.