Application security

The Basics of ASP.NET

Dejan Lukan
January 29, 2013 by
Dejan Lukan

Introduction

In this article we'll talk about unicode support in various elements of the HTTP protocol, but first let's say a few words about HTTP. We won't go into depth about what HTTP is, let's just remind the reader about the elements that comprise the whole protocol. First there is the URI scheme, which we use in everyday life for surfing the web. An example of the URI is http://www.google.com, but I guess you all know that. The second important things are requests and responses, where they both use HTTP headers to exchange additional information needed for the HTTP protocol to function the way it does. Normally, the URI and HTTP headers are written in ASCII, but actually any kind of character set can be used to present their values, including Unicode.

11 courses, 8+ hours of training

11 courses, 8+ hours of training

Learn cybersecurity from Ted Harrington, the #1 best-selling author of "Hackable: How to Do Application Security Right."

In the article that follows, we'll first install the IIS7.5 web server and deploy our first application to use. We'll do that because we can send unicode characters to the IIS7.5 web server, which are supported and are therefore parsed appropriately.

Deploying First ASP.NET Application

Here we'll show you how to deploy an ASP.NET web application on our own IIS web server. When developing an application, we're usually testing it in the Visual Studio web server, but instead we'll be testing the application with the IIS Express web server, which is a better web server compared to the one provided with the Visual Studio.

If we click the "Install now" button, we'll download the executable that will install a whole range of packets like the IIS 7.5 web server, SQL server, etc…, which we can use when deploying our application. After the installation, port 80 will be opened, but if we try to access it, we'll get a Bad Request (Invalid Hostname) error message, as can be seen on the picture below:

We can open Microsoft Visual Web Developer 2012 and start a new project as shown on the picture below:

After creating a new ASP.NET web application, we'll be presented with the Default.aspx application as seen below:

If we run the application now (by pressing the play button in the Visual Web Developer), the http://localhost:1437/Default.aspx URL will automatically open in our default browser to check out the current application: this is very useful when programming new applications as we can instantly see what we've changed. The default web application, as provided by the template, can be seen on the picture below:

As you can see, there isn't much there. However, we can confirm that the ASP.NET webpage is working and up and running. The project above can be stored anywhere on the disk with newer versions, but that didn't used to be the case; in older versions, we needed to store the project in the inetpubwwwroot directory. When we compiled the application, the whole code, resources and other files were joined together and put in the bin/ directory under document root. If we click on "Show all files" in the Solution Explorer, the bin/ and obj/ directories will become visible, as can be seen below:

Let's also check out the properties of the project, which we can access by clicking on Project > Properties. By default, the web projects has an additional tab named "Web", which is interesting when used with ASP.NET web applications. The web tab can be used to specify the web server that will be used to serve our application. Above, we saw that we're connected to a web server that's running on the port 1437, which is the built-in Visual Studio web server. Let's configure it to use the IIS server instead. We can do that by changing the settings accordingly, as can be seen on the picture below:

When we click save to save the settings and restart the application, our website will be opened on the localhost URI on port 80 and not 1437, as it before.

Also, the web server will be running under the IIS web server (process iisexpress.exe).

Ok, we've got our application running in the IIS web server as we wanted, but we don't really know what's happening behind the curtains now, do we? The first thing we should be aware of when penetration testing the ASP.NET application is that each .aspx web page has three files associated with it. The first file is obviously the name.aspx file that contains the html code template and two .cs files that contain the actual logic of that web page: these two are named name.aspx.cs and name.aspx.designer.cs, where the name can be an arbitrary name. We can see some of those names on the picture below:

Let's now write a "Hello world!" example in ASP.NET. First, we must mention that the aspx file can contain plain text html and it will work as well, but who uses only html nowadays; we need a dynamic web page to do advanced stuff, which is where asp.net comes into play. If we save the code to the aspx file, we're basically sending it through the asp.net runtime that compiles the file and returns the results to the web browser user.

The runtime asp.net needs to know in which language the aspx is written in, because it can be written in many languages, which is why we need to provide that information in the <%@ Page ... %> block at the start of the aspx file. The default contents of the Default.aspx file are the following:

[plain]

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"

CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>

[/plain]

We can see a number of directives used to inform the runtime about various configuration options. The Language directive tells the ASP.NET runtime that we'll be using C# as the default language for the page. The title directive specifies the string displayed in each tab to notify the user about the page. The MasterPageFile provides a relative path to the master page file that provides a consistent look and behavior for all the pages in the web application. There's also the CodeBehind declarative that specifies the .cs file acting as the code-behind. The Inherits option specifies the class from which the page inherits.

Ok, we're all set, let's add the 'hello world' label now. We can do that by adding a Label control, which is used to hold text. We should add the following to the Default.aspx:

[plain]

<p><asp:Label runat="server" id="hellolabel"></asp:Label></p>

[/plain]

Each control element has a runat attribute, which denotes the element as a web control element. But each element also has an id attribute so we can reference it in the code. Note that the above code only creates a placeholder that will be inserted in the actual ASP.NET page whenever necessary. So the whole Default.aspx web page can look something like this: note that the web page is the default as created by the Visual Studio, the only thing added is an additional label:

[plain]

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"

CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">

</asp:Content>

<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">

<h2>

Welcome to ASP.NET!

</h2>

<p>

To learn more about ASP.NET visit <a href="http://www.asp.net" title="ASP.NET Website">www.asp.net</a>.

</p>

<p><asp:Label runat="server" id="hellolabel"></asp:Label></p>

<p>

You can also find <a href="http://go.microsoft.com/fwlink/?LinkID=152368&amp;amp;clcid=0x409"

title="MSDN ASP.NET Docs">documentation on ASP.NET at MSDN</a>.

</p>

</asp:Content>

[/plain]

Since the Label is only a placeholder, if we run the page, there won't be anything displayed in the page (except for the default contents). This is where the Default.aspx.cs code behind comes into play. We can reference the added label in the code behind code with the hellolabel references (remember that this is the id of the added element). The code that adds the string "Hello World!" to the page in the code-behind Default.aspx.cs file can be seen below:

[plain]

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

namespace WebApplication1

{

public partial class _Default : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

hellolabel.Text = "Hello World!";

}

}

}

[/plain]

We can see that we're using the reference hellolabel to access the attribute Text and assigning the "Hello World!" text to it. If we save the file and rerun the web server, we can see that the updated web page now contains an additional "Hello World!" text inside it. We can see that on the picture below:

So, we've just seen a basic ASP.NET application in action.

ASP.NET Configuration Files

Each ASP.NET website has two configuration files: Machine.config and Web.config. Whenever we install .NET framework, the C:WINDOWSMicrosoft.NETFramework folder is created that contains each version of the installed .NET framework (on the picture below, the v4.0.30319 version is installed). Each of the framework version directories contains a Config folder as can be seen on the picture below:

The Config folder holds all the files presented on the picture below:

From the picture above, we can see that the folder contains both important configuration files: machine.config and web.config. There are also some other .config configuration files:

- enterprisesec.config

- legacy.web_hightrust.config

- legacy.web_lowtrust.config

- legacy.web_mediumtrust.config

- legacy.web_minimaltrust.config

- security.config

- web_hightrust.config

- web_lowtrust.config

- web_mediumtrust.config

- web_minimaltrust.config

We won't explore each and every .config file, but will look just at the machine.config and web.config.

First, we must be aware of the fact that every web application inherits settings from the machine.config file and web.config file. The machine.config configuration file is system specific, while the web.config configuration file is application specific.

In ASP.NET, there are many configuration files, some of them global and some local to the application itself: this is called a multilayer configuration system, because we can use different settings in different applications or even different subparts of the application. To start using this, we only need to put the configuration file inside the parent directory: in ASP.NET, the subdirectory uses the settings found in its parent directory.

Let's take an example where the author is looking at an example of a web request http://localhost/X/Y/Z/page.aspx, where X is the root directory of the application [1]. In that same example, multiple levels of settings are applied to every request. First the machine.config and web.config settings are applied; the ones that can be located in the C:WINDOWSMicrosoft.NETFramework<version>CONFIG directory. Afterwards, the config settings from the root X are applied (if there is such a config file), following by the config settings from the Y and Z directories. All in all, there can be an unlimited number of directories, each having a separate web.config configuration file, but the most important configuration files are the machine.config and web.config from the C:WINDOWSMicrosoft.NETFramework<version>CONFIG directory, because they hold the settings that cannot be overridden at an application root level, but are still needed for the application to function correctly.

The Configuration Options

In this subsection of the article, we'll describe the most relevant configuration tags that are often present in a web.config configuration file. Let's take a look at the default web.config configuration file from the default application created by Visual Studio:

[xml]
<?xml version="1.0"?>

<configuration>

<connectionStrings>

<add name="ApplicationServices"

connectionString="data source=.SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"

providerName="System.Data.SqlClient" />

</connectionStrings>

<system.web>
<compilation debug="true" targetFramework="4.0" />

<authentication mode="Forms">

<forms loginUrl="~/Account/Login.aspx" timeout="2880" />

</authentication>

<membership>

<providers>

<clear/>

<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices"

enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"

maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"

applicationName="/" />

</providers>

</membership>

<profile>

<providers>

<clear/>

<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/>

</providers>

</profile>

<roleManager enabled="false">

<providers>

<clear/>

<add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />

<add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />

</providers>

</roleManager>

</system.web>

<system.webServer>

<modules runAllManagedModulesForAllRequests="true"/>

</system.webServer>

</configuration>

[/xml]

We can see a number of configuration options, which we'll try to explain next. The first thing that we can observe is that everything is contained in the <configuration> tag. We can check out all of the configuration options on the web page: here.
The <system.web> configuration specifies the root element for the ASP.NET configuration sections, which control how applications behave. All of the tags that can be specified in <system.web> are listed here.

Conclusion

We've seen that the web.config is the main configuration file for the ASP.NET web application. It is in XML document format and holds information about the web application; it controls the way modules are loaded, it holds security configuration information and session state configuration and a whole lot of other stuff. We can see why this file is particularly important to the attacker, as if he gets his hands on it, he can wreak havoc on the server and application.

References:

[1] A Beginner's view : Web.config, accessible at http://www.dotnetfunda.com/articles/article854-a-beginners-view-webconfig.aspx.

Dejan Lukan
Dejan Lukan

Dejan Lukan is a security researcher for InfoSec Institute and penetration tester from Slovenia. He is very interested in finding new bugs in real world software products with source code analysis, fuzzing and reverse engineering. He also has a great passion for developing his own simple scripts for security related problems and learning about new hacking techniques. He knows a great deal about programming languages, as he can write in couple of dozen of them. His passion is also Antivirus bypassing techniques, malware research and operating systems, mainly Linux, Windows and BSD. He also has his own blog available here: http://www.proteansec.com/.