OWASP O2 Platform Blog

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

November 16, 2011 Posted by | .NET, ASP.NET Controls, Fixing Code | 1 Comment

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

November 16, 2011 Posted by | .NET, ASP.NET Controls | 1 Comment

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:

November 6, 2011 Posted by | .NET, ASP.NET Controls, IE Automation, Vulnerabilities, XSS | Leave a comment