Creating the “Util – AspNet Control Encodings (Raw Format).h2″ script
Here is the sequence that created the script described in Consuming ASP.NET Control Encoding mappings and visualizing them – Part 1 which visualizes the html based ASP.NET control encodings into an serializable C# class.
The ultimate objective is to create a complete/comprehensive ASP.NET Web Controls XSS Mappings object, and this is just the first step on that direction
Fetching Url contents, save as local file and show in IE
var sourceFile = "http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-08-91-89-96/asp.net_5F00_control_5F00_encoding.htm";
var htmlContents = sourceFile.uri().getHtml();
var tempFile = htmlContents.saveAs( "".tempDir().pathCombine("asp.net_control_encodings.htm"));
//var topPanel = O2Gui.open<Panel>("{name}",700,400);
var topPanel = panel.clear().add_Panel();
var ie = topPanel.add_IE_with_NavigationBar().silent(false);
ie.open(tempFile);
return tempFile;
//O2File:WatiN_IE_ExtensionMethods.cs
//using O2.XRules.Database.Utils.O2
//O2Ref:WatiN.Core.1x.dll
the url contents was saved to C:\O2\_tempDir\11-8-2011\asp.net_control_encodings.htm
Viewing saved file
//var topPanel = O2Gui.open<Panel>("{name}",700,400);
var tempFile = @"C:\O2\_tempDir\11-8-2011\asp.net_control_encodings.htm";
var topPanel = panel.clear().add_Panel();
var ie = topPanel.add_IE_with_NavigationBar().silent(false);
ie.open(tempFile);
return tempFile;
//O2File:WatiN_IE_ExtensionMethods.cs
//using O2.XRules.Database.Utils.O2
//O2Ref:WatiN.Core.1x.dll
looking at the Html Elements of the IE Object
//var topPanel = O2Gui.open<Panel>("{name}",700,400);
var tempFile = @"C:\O2\_tempDir\11-8-2011\asp.net_control_encodings.htm";
var topPanel = panel.clear().add_Panel();
var ie = topPanel.add_IE_with_NavigationBar().silent(false);
ie.open(tempFile);
ie.showElementsInTreeView();
return "ok";
//O2File:WatiN_IE_ExtensionMethods.cs
//using O2.XRules.Database.Utils.O2
//O2Ref:WatiN.Core.1x.dll
Getting all rows (TR Element) – slow mode
//var topPanel = O2Gui.open<Panel>("{name}",700,400);
var tempFile = @"C:\O2\_tempDir\11-8-2011\asp.net_control_encodings.htm";
var topPanel = panel.clear().add_Panel();
var ie = topPanel.add_IE_with_NavigationBar().silent(false);
ie.open(tempFile);
return ie.elements("TR");
return "ok";
//O2File:WatiN_IE_ExtensionMethods.cs
//using O2.XRules.Database.Utils.O2
//O2Ref:WatiN.Core.1x.dll
Getting the first row – slow mode
//var topPanel = O2Gui.open<Panel>("{name}",700,400);
var tempFile = @"C:\O2\_tempDir\11-8-2011\asp.net_control_encodings.htm";
var topPanel = panel.clear().add_Panel();
var ie = topPanel.add_IE_with_NavigationBar().silent(false);
ie.open(tempFile);
ie.details();
var rows= ie.elements("TR");
return rows[0];
//O2File:WatiN_IE_ExtensionMethods.cs
//using O2.XRules.Database.Utils.O2
//O2Ref:WatiN.Core.1x.dll
Getting all rows – faster method
//var topPanel = O2Gui.open<Panel>("{name}",700,400);
var tempFile = @"C:\O2\_tempDir\11-8-2011\asp.net_control_encodings.htm";
var topPanel = panel.clear().add_Panel();
var ie = topPanel.add_IE_with_NavigationBar().silent(false);
ie.open(tempFile);
ie.details();
return ie.IE.TableRows;
//O2File:WatiN_IE_ExtensionMethods.cs
//using O2.XRules.Database.Utils.O2
//O2Ref:WatiN.Core.1x.dll
show rows data in treeView
//var topPanel = O2Gui.open<Panel>("{name}",700,400);
var tempFile = @"C:\O2\_tempDir\11-8-2011\asp.net_control_encodings.htm";
var topPanel = panel.clear().add_Panel();
var ie = topPanel.add_IE_with_NavigationBar().silent(false);
ie.open(tempFile);
var rowsText = new List<string>();
foreach(var row in ie.IE.TableRows)
rowsText.add(row.str());
var treeView = topPanel.insert_Left()
.add_TreeView()
.add_Nodes(rowsText);
return "ok";
//O2File:WatiN_IE_ExtensionMethods.cs
//using O2.XRules.Database.Utils.O2
//O2Ref:WatiN.Core.1x.dll
show rows data as a strongly type object in a table view:
//var topPanel = O2Gui.open<Panel>("{name}",700,400);
var tempFile = @"C:\O2\_tempDir\11-8-2011\asp.net_control_encodings.htm";
var topPanel = panel.clear().add_Panel();
var ie = topPanel.add_IE_with_NavigationBar().silent(false);
ie.open(tempFile);
var mappedData = (from row in ie.IE.TableRows
select new {
type = row.TableCells[0].str(),
propertyName = row.TableCells[1].str(),
attributeName_Script = row.TableCells[2].str(),
htmlEncode_scriptEncode = row.TableCells[3].str(),
urlEncode = row.TableCells[4].str()
}).toList();
topPanel.insert_Left()
.add_TableList()
.show(mappedData);
return mappedData.save();
//using WatiN.Core
//O2File:WatiN_IE_ExtensionMethods.cs
//using O2.XRules.Database.Utils.O2
//O2Ref:WatiN.Core.1x.dll
Create a Dynamic type (won’t work due to serialization issues)
var dynamicTypeBuilder = "AspNetControlEncodings".dynamicType();
dynamicTypeBuilder.add_Properties<string>("type" , "propertyName", "attributeName_Script", "htmlEncode_scriptEncode","urlEncode");
var AspNetControlEncodings = dynamicTypeBuilder.create();
var encodingsList = AspNetControlEncodings.ctor().wrapOnList();
Populate data in a class that can be serialized
In the file AspNetControlEncodings.cs Create the class:
namespace O2.XRules.Database.Utils
{
public class AspNetControlEncodings_Raw : List<AspNetControlEncoding_Raw>
{
}
public class AspNetControlEncoding_Raw
{
[XmlAttribute] public string @Type { get; set;}
[XmlAttribute] public string PropertyName { get; set;}
[XmlAttribute] public string AttributeName_Script { get; set;}
[XmlAttribute] public string HtmlEncode_scriptEncode { get; set;}
[XmlAttribute] public string UrlEncode { get; set;}
}
}
The AspNetControlEncodings.cs is now used/consumed by this script
//var topPanel = O2Gui.open<Panel>("{name}",700,400);
var tempFile = @"C:\O2\_tempDir\11-8-2011\asp.net_control_encodings.htm";
var topPanel = panel.clear().add_Panel();
var ie = topPanel.add_IE_with_NavigationBar().silent(false);
ie.open(tempFile);
var mappedData = (from row in ie.IE.TableRows
select new AspNetControlEncoding_Raw {
@Type = row.TableCells[0].str(),
PropertyName = row.TableCells[1].str(),
AttributeName_Script = row.TableCells[2].str(),
HtmlEncode_scriptEncode = row.TableCells[3].str(),
UrlEncode = row.TableCells[4].str()
}).toList();
topPanel.insert_Left()
.add_TableList()
.show(mappedData);
return mappedData.save();
return "ok";
//using WatiN.Core
//O2File:WatiN_IE_ExtensionMethods.cs
//O2File:AspNetControlEncodings.cs
//using O2.XRules.Database.Utils.O2
//O2Ref:WatiN.Core.1x.dll
The data will be shown in a table list and a temp file will be created. In this case C:\O2\_tempDir\11-9-2011\tmp3A1F.tmp.xml (which will be save as AspNetControlEncodings_Raw.xml in the O2 Scripts folder)
show data in TableList directly (must faster)
var topPanel = panel.clear().add_Panel(); var tempFile = @"C:\O2\_tempDir\11-9-2011\tmp3A1F.tmp.xml"; var mappedData = tempFile.load<AspNetControlEncodings_Raw>(); topPanel.add_TableList() .show(mappedData); return mappedData.save(); //using WatiN.Core //O2File:WatiN_IE_ExtensionMethods.cs //O2File:AspNetControlEncodings.cs //using O2.XRules.Database.Utils.O2 //O2Ref:WatiN.Core.1x.dll
Show data in popup form
var topPanel = O2Gui.open<Panel>("Util - AspNet ControlEncodings (Raw Format) ",700,400);
var mappedData = "AspNetControlEncodings_Raw.xml".local().load<AspNetControlEncodings_Raw>();
topPanel.add_TableList()
.show(mappedData);
//O2File:AspNetControlEncodings.cs
FinalScript:
ColorCoding data in popupForm (this is the Final version of the Script)
//var topPanel = panel.clear().add_Panel();
var topPanel = O2Gui.open<Panel>("Util - AspNet ControlEncodings (Raw Format)",700,400);
var mappedData = "AspNetControlEncodings_Raw.xml".local().load<AspNetControlEncodings_Raw>();
var tableList = topPanel.add_TableList()
.show(mappedData);
tableList.add_Column("vuln");
tableList.visible(false);
foreach(var row in tableList.rows())
{
var values = row.values();
if (values[2] == "na")
row.textColor(Color.Black);
else if (values[3].toBool() && values[4].toBool())
row.textColor(Color.DarkGreen);
else if (values[3].toBool() || values[4].toBool())
row.textColor(Color.DarkOrange);
else
{
row.textColor(Color.Red);
row.SubItems[1].Text = "* " + values[1];
}
}
tableList.visible(true);
return "ok";
//O2File:AspNetControlEncodings.cs
Consuming ASP.NET Control Encoding mappings and visualizing them – Part 1
Trying to find out the exact behaviour of the default ASP.NET Controls enconding behaviour is not simple, and surprisingly there are no good sources out there that clearly show what happens.
The best I could find is the table from Sasha Faust Which ASP.NET Controls Automatically Encodes? blog post . Look in the attached asp.net_control_encoding.htm file, which looks like this:

The problem with that file is that is it not in a consumable format (it is in an html table).
So the first thing we need to do is to extract this data into a serializable .NET C# class which can be further analyzed.
To do that I wrote this script Util – AspNet ControlEncodings (Raw Format).h2 which looks like this when executed:

What is nice from that table is that due to the color coding and small change on the PropertyName value, we can now see:
all mappings that do no Encoding:

the mappings that have at least one of Encodings Enabled (either HtmlEncode or HtmlEncode):

the mappings that have both encodings enabled:

the mappings that don’t have a AttributeName defined:

Data stored in XML
These views are created from a serialized xml object (on AspNetControlEncodings.cs) which is stored in serialized format as an XML file:

Source Code
Here is the source code of this script:
//var topPanel = panel.clear().add_Panel();
var topPanel = O2Gui.open<Panel>("Util - AspNet ControlEncodings (Raw Format)",700,400);
var mappedData = "AspNetControlEncodings_Raw.xml".local().load<AspNetControlEncodings_Raw>();
var tableList = topPanel.add_TableList()
.show(mappedData);
tableList.add_Column("vuln");
tableList.visible(false);
foreach(var row in tableList.rows())
{
var values = row.values();
if (values[2] == "na")
row.textColor(Color.Black);
else if (values[3].toBool() && values[4].toBool())
row.textColor(Color.DarkGreen);
else if (values[3].toBool() || values[4].toBool())
row.textColor(Color.DarkOrange);
else
{
row.textColor(Color.Red);
row.SubItems[1].Text = "* " + values[1];
}
}
tableList.visible(true);
return "ok";
//O2File:AspNetControlEncodings.cs
How the AspNetControlEncodings_Raw.xml file was created
To see how this script was created and how the original html table was transformed into the xml file, see this blog post: Creating the “Util – AspNet Control Encodings (Raw Format).h2″ script
Checking if .NET’s HtmlAnchor Href property is vulnerable to XSS
I was reviewing an app’s code and it looked like there was an XSS injection vector into the .NET’s built in HtmlAnchor Href property.
To make sure this happened, I quickly wrote the following script which allowed me to confirm that YES that property is vulnerable to XSS:
var stringWriter = new System.IO.StringWriter(); var htmlTextWriter = new HtmlTextWriter(stringWriter); var htmlAnchor = new System.Web.UI.HtmlControls.HtmlAnchor(); htmlAnchor.Title ="title"; htmlAnchor.HRef ="sadfasdf'<>\">aaa"; htmlAnchor.RenderControl(htmlTextWriter); //htmlAnchor.details(); return stringWriter.str(); //using System.Web.UI;
On the screenshot below you can see that none of the chars were encoded:

So the result in the ‘Output’ window shows the value put on the htmlAnchor.HRef ( the payload “sadfasdf’<>\”>aaa”), it is not encoded.
To really test this, lets try it on web page.
This next script will put the payload on an IE object:
var topPanel = panel.clear().add_Panel();
var ie = topPanel.add_IE().silent(true);
var stringWriter = new System.IO.StringWriter();
var htmlTextWriter = new HtmlTextWriter(stringWriter);
var htmlAnchor = new System.Web.UI.HtmlControls.HtmlAnchor();
htmlAnchor.Title ="title";
htmlAnchor.HRef ="<a href="http://www.google.com'%3c%3e/%22%3Eaaa">http://www.google.com'<>\">aaa</a>";
htmlAnchor.RenderControl(htmlTextWriter);
ie.open("about:blank");
var html = "<html><body><h1>XSS on HtmlAnchor Href tag</h1>" +
"before anchor<br/>" +
stringWriter.str() +
"<br/>after anchor</body></html>";
ie.html(html);
//using System.Web.UI;
//using O2.XRules.Database.Utils.O2
//O2File:WatiN_IE_ExtensionMethods.cs
//O2Ref:WatiN.Core.1x.dll
//O2Ref:Microsoft.mshtml.dll
which looks like this:

Note how the payload in the html achor breaks the html element and is shown on the page.
To really check if this is a problem let try this on a real ASP.NET page .
For that, open the Util – Aspx PoC Builder.h2 script ,which you can find here:

… and looks like this when opened:

This control will fire up a local webserver on (the directory specified on the left) and will give us a quick way to write ASP.NET Pocs
For this example lets create file called AnchorTag.aspx in an ASP.NET Controls folder

… and use the content from http://www.w3schools.com/aspnet/showasp.asp?filename=demo_htmlanchor with a small modification: On line 4 add ?value=” + Request(“payload”) to the Href value (so that we can put a payload via the Querystring or POST request)
link1.HRef="<a href="http://www.w3schools.com/?value">http://www.w3schools.com/?value</a>=" + Request("payload")

This is what it looks like when executed:

We can now add a variable called payload to the QueryString :

… which if containing a “ and a > will break the Html Anchor Element

Since when we are inside Html attribute the “ (and an =) is all we need to put in an XSS payload, we can popup an alert using ” onmouseover=”alert(12)

Bypassing ASP.NET Validation
What is interresting (and dangerous) and this exploit vector is that it bypasses ASP.NET validation.
For example if we use a payload that has a valid Html tag (payload=“aaaa”> <h1>XSS</h1>) we will get this error:


