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

O2 Script: AntiXSS – Test multiple Encodings

On the topic of AntiXSS here is a script I wrote ages ago called “AntiXSS – Test multiple Encodings.h2” which shows quickly the different behaviours of the different .NET encoding APIs:

Here is the source of this script:

var topPanel = O2Gui.open<Panel>("AntiXSS and HttpUtility encodings", 600,300); 
var result = topPanel.add_TextArea();
Action<string> showEncodings =
    (textToEncode)=>{
                        result.set_Text("");
                        result.append_Line("AntiXss.HtmlEncode -> {0}".format(AntiXss.HtmlEncode(textToEncode)));
                        result.append_Line("------------------------");
                        result.append_Line("AntiXss.UrlEncode -> {0}".format(AntiXss.UrlEncode(textToEncode)));
                        result.append_Line("------------------------");
                        result.append_Line("AntiXss.JavascriptEncode -> {0}".format(AntiXss.JavaScriptEncode(textToEncode)));
                        result.append_Line("------------------------");
                        result.append_Line("System.Web.HttpUtility.HtmlEncode -> {0}".format(System.Web.HttpUtility.HtmlEncode(textToEncode)));
                        result.append_Line("------------------------");
                        result.append_Line("System.Web.HttpUtility.UrlEncode -> {0}".format(System.Web.HttpUtility.UrlEncode(textToEncode)));
                        result.append_Line("------------------------");
                        result.append_Line("Original string (unencoded) -> {0}".format(textToEncode));
                        result.append_Line("------------------------");
                    };

var testPayload = "abc 123 \" ' < > \n :   ;   ".line() + "After an Enter";                    
result.insert_Above<Panel>(20)
      .add_LabelAndTextAndButton("Payload", testPayload, "convert", showEncodings);

showEncodings(testPayload);

//return AntiXss.HtmlEncode(payload);
//return "AntiXSSLibrary.dll".assembly().methods();
//using Microsoft.Security.Application
//O2Ref:AntiXSSLibrary.dll

November 16, 2011 Posted by | .NET, AntiXss | 2 Comments

O2 Script with Web Encoder and Decoder (with AntiXss Support)

A couple days ago I needed to do a number of Encodings/Decodings  in sequence (Encoded Text -> UrlDecode -> UrlDecode-> HtmlDecode), and since there was no easy way to do that automatically with other tools, I wrote the “Util – Web Encoder (with AntiXss Support).h2” script which looks like this:

Here is the method that runs the transformation (and show what is currently supported)

Func<string,string, string> applyTransformation =
    (type, text)=>{
                    if (type.valid() && text.valid() )
                    {
                        switch(type)
                        {
                            case "none":                                break;
                            case "HtmlDecode":                            return text.htmlDecode();
                            case "HtmlEncode":                            return text.htmlEncode();
                            case "UrlDecode":                            return text.urlDecode();
                            case "UrlEncode":                            return text.urlEncode();       
                           
                            case "AntiXss.HtmlEncode":                     return Encoder.HtmlEncode(text);
                            case "AntiXss.UrlEncode":                     return Encoder.UrlEncode(text);
                            case "AntiXss.JavaScriptEncode":             return Encoder.JavaScriptEncode(text);   
                            case "AntiXss.CssEncode":                     return Encoder.CssEncode(text);   
                            case "AntiXss.HtmlAttributeEncode":         return Encoder.HtmlAttributeEncode(text);   
                            case "AntiXss.HtmlFormUrlEncode":             return Encoder.HtmlFormUrlEncode(text);   
                            case "AntiXss.XmlAttributeEncode":             return Encoder.XmlAttributeEncode(text);   
                            case "AntiXss.XmlEncode":                     return Encoder.XmlEncode(text);   
                            case "AntiXss.VisualBasicScriptEncode":     return Encoder.VisualBasicScriptEncode(text);   
                            case "AntiXss.LdapDistinguishedNameEncode": return Encoder.LdapDistinguishedNameEncode(text);   
                            case "AntiXss.LdapFilterEncode":             return Encoder.LdapFilterEncode(text);   
                           
                            case "Sanitizer.GetSafeHtml":                return Sanitizer.GetSafeHtml(text);
                            case "Sanitizer.GetSafeHtmlFragment":        return Sanitizer.GetSafeHtmlFragment(text);
                           
                            default:
                                return text + "  not supported: {0}".format(type);
                        }                   
                    }
                    return text;
                  };

This uses the latest version of the AntiXSS library, including the new HtmlSanitizationLibrary.dll which has the GetSafeHtml* methods and looks really powerful.

Here is the entire code of this script:


var topPanel = O2Gui.open<Panel>("Util - Web Encoder (with AntiXss Support)",1000,400);
//var topPanel = panel.clear().add_Panel();
var configPanel = topPanel.insert_Above(40,"Config");
var sourceText = topPanel.add_GroupBox("Source Text").add_SourceCodeViewer(); 
var transformedText = topPanel.insert_Right("Transformed Text").add_SourceCodeViewer();
 
var transformationsAvailable = new List<string> { "none",
                                                  "HtmlDecode",    "HtmlEncode","UrlDecode", "UrlEncode",
                                                  "AntiXss.HtmlEncode",              "AntiXss.UrlEncode",                      "AntiXss.JavaScriptEncode",      "AntiXss.CssEncode",
                                                  "AntiXss.HtmlAttributeEncode",    "AntiXss.HtmlFormUrlEncode",             "AntiXss.XmlAttributeEncode",    "AntiXss.XmlEncode",
                                                  "AntiXss.VisualBasicScriptEncode","AntiXss.LdapDistinguishedNameEncode",    "AntiXss.LdapFilterEncode",
                                                  "Sanitizer.GetSafeHtml",             "Sanitizer.GetSafeHtmlFragment"};
var transformMode_1 = "";
var transformMode_2 = "";
var transformMode_3 = "";
Func<string,string, string> applyTransformation =
    (type, text)=>{
                    if (type.valid() && text.valid() )
                    {
                        switch(type)
                        {
                            case "none":                                break;
                            case "HtmlDecode":                            return text.htmlDecode();
                            case "HtmlEncode":                            return text.htmlEncode();
                            case "UrlDecode":                            return text.urlDecode();
                            case "UrlEncode":                            return text.urlEncode();       
                           
                            case "AntiXss.HtmlEncode":                     return Encoder.HtmlEncode(text);
                            case "AntiXss.UrlEncode":                     return Encoder.UrlEncode(text);
                            case "AntiXss.JavaScriptEncode":             return Encoder.JavaScriptEncode(text);   
                            case "AntiXss.CssEncode":                     return Encoder.CssEncode(text);   
                            case "AntiXss.HtmlAttributeEncode":         return Encoder.HtmlAttributeEncode(text);   
                            case "AntiXss.HtmlFormUrlEncode":             return Encoder.HtmlFormUrlEncode(text);   
                            case "AntiXss.XmlAttributeEncode":             return Encoder.XmlAttributeEncode(text);   
                            case "AntiXss.XmlEncode":                     return Encoder.XmlEncode(text);   
                            case "AntiXss.VisualBasicScriptEncode":     return Encoder.VisualBasicScriptEncode(text);   
                            case "AntiXss.LdapDistinguishedNameEncode": return Encoder.LdapDistinguishedNameEncode(text);   
                            case "AntiXss.LdapFilterEncode":             return Encoder.LdapFilterEncode(text);   
                           
                            case "Sanitizer.GetSafeHtml":                return Sanitizer.GetSafeHtml(text);
                            case "Sanitizer.GetSafeHtmlFragment":        return Sanitizer.GetSafeHtmlFragment(text);
                           
                            default:
                                return text + "  not supported: {0}".format(type);
                        }                   
                    }
                    return text;
                  };
                 
                 
Action applyTransformations =
    ()=>{
            var originalText = sourceText.get_Text();
            var result = applyTransformation(transformMode_1,originalText);
            result = applyTransformation(transformMode_2, result);
            result = applyTransformation(transformMode_3, result);
            transformedText.set_Text(result);            
        };

sourceText.onTextChange(
    (text)=>{    
                applyTransformations();
            }); 
 
configPanel.add_Label("Color Code the text as").top(3)
           .append_Control<ComboBox>().dropDownList().top(0)
                                         .add_Items(".xml",".html",",cs")                                        
                                         .onSelection((value)=> {
                                                                     transformedText.editor().setDocumentHighlightingStrategy(value.str());
                                                                     sourceText.editor().setDocumentHighlightingStrategy(value.str());
                                                                 })
                                         .selectFirst()
                                        
            .append_Label("Transform using:").top(3).autoSize() 
            .append_Control<ComboBox>().dropDownList().top(0).width(170).comboBoxHeight(250)
                                         .add_Items(transformationsAvailable)
                                         .onSelection<string>((value)=> { transformMode_1 = value; applyTransformations(); } )
                                         .selectFirst()
                                        
            .append_Label("and:").top(3).autoSize()
            .append_Control<ComboBox>().dropDownList().top(0).width(170).comboBoxHeight(250)
                                         .add_Items(transformationsAvailable)
                                         .onSelection<string>((value)=> { transformMode_2 = value; applyTransformations(); } )
                                        
            .append_Label("and:").top(3).autoSize() 
            .append_Control<ComboBox>().dropDownList().top(0).width(170).comboBoxHeight(250)
                                         .add_Items(transformationsAvailable)
                                         .onSelection<string>((value)=> { transformMode_3 = value; applyTransformations(); } )
                                         ;
 
sourceText.set_Text("this is a <b> test </b>");

return "done";
//using Microsoft.Security.Application
//O2Ref:AntiXSSLibrary.dll
//O2Ref:HtmlSanitizationLibrary.dll

November 16, 2011 Posted by | .NET, AntiXss, Fixing Code | Leave a comment

Consuming NMAP XML files and taking screenshots of web ports

Here is an O2 Script that consumes NMap saved XML files and takes screenshots of ports 80 and 443 ( both ip and hostnames)

The script is called Tool – Take Screenshots of NMap Web Ports.h2 and this is what it looks like when executed:

You can drag and drop NMap files into the left-most TreeView. This should trigger the file load and display the resolved URLS in that TreeView.

You can click on each entry on the Urls TreeView to take a screenshot for that page, or click on the ‘take screenshots of all pages’ link to process all links

Here is the result of dropping a nmap xml from a quick scan to owasp.org (the www.google.com entry was added for testing):

If you select an node from the Screenshots treeview, you will see the actual screenshot taken (note how in the picture above the browser is now showing a local file )

How was this script/tool created?

Here is how this script evolved:

start with a saved nmap results file:

var nmapSavedFile = @"o2platform.com.xml".local(); 

create xsd file (schema)

var targetDir = @"C:\O2\O2Scripts_Database\_Scripts\3rdParty_Tools\NMap";
var xsdFile = targetDir.pathCombine("nmap.xsd");
var nmapSavedFile = @"o2platform.com.xml".local();  
return nmapSavedFile.xmlCreateXSD().saveAs(xsdFile);

Since that worked, create CSharp file and copy to the correct location

var nmapSavedFile = @"o2platform.com.xml".local();  
var createdFile = nmapSavedFile.xmlCreateCSharpFile_Patched();
var targetDir = @"C:\O2\O2Scripts_Database\_Scripts\3rdParty_Tools\NMap";

var csFile = targetDir.pathCombine("nmap.cs");
Files.MoveFile(createdFile, csFile);
var xsdFile = targetDir.pathCombine("nmap.xsd");
Files.MoveFile(nmapSavedFile + ".xsd", xsdFile);Creaate

view created nmap.cs file in source code viewer:

var nmapSavedFile = @"nmap.cs".local();  
nmapSavedFile.showInCodeViewer();

load saved nmap xml file and view its contents:

var nmapSavedFile = @"o2platform.com.xml".local();  
var nmap = nmaprun.Load(nmapSavedFile);
nmap.details();
return nmap;

show results in table list

var topPanel = panel.clear().add_Panel();
var nmapSavedFile = @"o2platform.com.xml".local();  
var nmap = nmaprun.Load(nmapSavedFile);
var tableList = topPanel.add_TableList()
                        .add_Columns("Host", "Port", "Type", "State");
                       
                       
foreach(var host in nmap.host)
    foreach(var hostPort in host.ports)
        foreach(var port in hostPort.port)
            tableList.add_Row(host.address[0].addr.str(), 
                             port.portid.str(),
                             port.service[0].name.str(),
                             port.state[0].state.str());
tableList.setWidthToContent();

calculate the urls of the web ports

var webHosts = new List<string>();
foreach(var host in nmap.host)   
    foreach(var hostPort in host.ports)
        foreach(var port in hostPort.port)
            if (port.portid == "80" || port.portid == "443")
            {
                foreach(var address in host.address)       
                    webHosts.add("<a href="http://{0}:{1}&quot;.format(address.addr">http://{0}:{1}".format(address.addr</a>, port.portid));
                foreach(var hostHostname in host.hostnames)
                    foreach(var hostname in hostHostname.hostname)                           
                            webHosts.add("<a href="http://{0}:{1}&quot;.format(hostname.name">http://{0}:{1}".format(hostname.name</a>, port.portid));
            }
 
return webHosts;  

move web mapping into a Lambda method

Func<string, List<string>> resolveWebHosts =
    (nmapSavedFile) =>{
                        var nmap = nmaprun.Load(nmapSavedFile);
                        var webHosts = new List<string>();
                        foreach(var host in nmap.host)   
                            foreach(var hostPort in host.ports)
                                foreach(var port in hostPort.port)
                                    if (port.portid == "80" || port.portid == "443")
                                    {
                                        foreach(var address in host.address)       
                                            webHosts.add("<a href="http://{0}:{1}&quot;.format(address.addr">http://{0}:{1}".format(address.addr</a>, port.portid));
                                        foreach(var hostHostname in host.hostnames)
                                            foreach(var hostname in hostHostname.hostname)                           
                                                    webHosts.add("<a href="http://{0}:{1}&quot;.format(hostname.name">http://{0}:{1}".format(hostname.name</a>, port.portid));
                                    }
                        return webHosts;
                        };
 
var testFile = @"o2platform.com.xml".local();  
var urls = resolveWebHosts(testFile);
return urls;

showing urls in treeview, adding a WebBrowser control and opening selectect url in browser

//var topPanel = O2Gui.open<Panel>("{name}",700,400);
var topPanel = panel.clear().add_Panel();
Func<string, List<string>> resolveWebHosts =
    (nmapSavedFile) =>{
                        var nmap = nmaprun.Load(nmapSavedFile);                       
                        var webHosts = new List<string>();
                        foreach(var host in nmap.host)   
                            foreach(var hostPort in host.ports)
                                foreach(var port in hostPort.port)
                                    if (port.portid == "80" || port.portid == "443")
                                    {
                                        foreach(var address in host.address)       
                                            webHosts.add("<a href="http://{0}:{1}&quot;.format(address.addr">http://{0}:{1}".format(address.addr</a>, port.portid));
                                        foreach(var hostHostname in host.hostnames)
                                            foreach(var hostname in hostHostname.hostname)                           
                                                    webHosts.add("<a href="http://{0}:{1}&quot;.format(hostname.name">http://{0}:{1}".format(hostname.name</a>, port.portid));
                                    }
                        return webHosts;
                        };
 
var testFile = @"o2platform.com.xml".local();  
var urls = resolveWebHosts(testFile);

var treeView = topPanel.insert_Left(400,"Urls").add_TreeView();
var webBrowser = topPanel.add_WebBrowser_Control();
treeView.afterSelect<string>(
    (url)=> {                               
                webBrowser.open(url);               
            });

treeView.add_Nodes(urls)
        .selectFirst();
           
//O2File:nmap.cs
//O2Ref:O2_Misc_Microsoft_MPL_Libs.dll

using O2’s IE/Watin Object instead

var testFile = @"o2platform.com.xml".local();  
var urls = resolveWebHosts(testFile);
var treeView = topPanel.insert_Left(400,"Urls").add_TreeView();
var ie = topPanel.add_IE();
treeView.afterSelect<string>(
    (url)=> {                               
                ie.open_ASync(url);                               
            });

treeView.add_Nodes(urls)
        .selectFirst();
           
//O2File:nmap.cs
//O2File:WatiN_IE_ExtensionMethods.cs
//O2Ref:O2_Misc_Microsoft_MPL_Libs.dll
//O2Ref:WatiN.Core.1x.dll

Finally …

…here is the complete source code of this script

var topPanel = O2Gui.open<Panel>("Tool - Take Screenshots of NMap Web Ports",1200,400);
topPanel.insert_LogViewer();
//var topPanel = panel.clear().add_Panel();
var actionsPanel = topPanel.insert_Above(40,"Actions");
Func<string, List<string>> resolveWebHosts =
    (nmapSavedFile) =>{
                        var nmap = nmaprun.Load(nmapSavedFile);                       
                        var webHosts = new List<string>();
                        foreach(var host in nmap.host)   
                            foreach(var hostPort in host.ports)
                                foreach(var port in hostPort.port)
                                    if (port.portid == "80" || port.portid == "443")
                                    {
                                        var type = (port.portid == "80") ? "http" : "https";
                                        foreach(var address in host.address)       
                                            webHosts.add("{0}://{1}:{2}".format(type, address.addr, port.portid));
                                        foreach(var hostHostname in host.hostnames)
                                            foreach(var hostname in hostHostname.hostname)                            
                                                    webHosts.add("{0}://{1}:{2}".format(type,hostname.name, port.portid));
                                    }
                        return webHosts;
                        };
 

var targetFolder = "_nmapScreenshots".tempDir(false);
var urls = new List<string>();
var urls_TreeView = topPanel.insert_Left(400,"Urls (click to take screenshot)").add_TreeView();
var screenshots_TreeView = topPanel.insert_Left(400, "Screenshots").add_TreeView();
var ie = topPanel.add_IE_with_NavigationBar();//.silent(true);
var alertsHandler = ie.getAlertsHandler();     // auto closes popup-windows
var stopExecution = false;

Action<string> takeScreenshotOfWebPage =
    (url)=>{
                "taking screenshot of page: {0}".debug(url);
                ie.open(url);
                var screenshot = topPanel.screenshot();
                var screenshotFile     = targetFolder.pathCombine("{0}.jpg".format(url.safeFileName()));               
                screenshot.save(screenshotFile);
                screenshots_TreeView.add_Node(url, screenshotFile);
           };
Action takeScreenShotsOfAllPages =
    ()=>{
            screenshots_TreeView.clear();
            stopExecution = false;
            foreach(var url in urls)
                if(stopExecution.isFalse())
                    takeScreenshotOfWebPage(url);           
        };
       
screenshots_TreeView.afterSelect<string>(
    (bitmapFile)=>{
                    "here".info();
                    ie.open_ASync(bitmapFile);
                   });
                  
urls_TreeView.afterSelect<string>(
    (url)=> {
                screenshots_TreeView.pink();
                O2Thread.mtaThread(
                    ()=>{
                            takeScreenshotOfWebPage(url);
                            screenshots_TreeView.white();
                        });
            });

Action<string> loadNmapXmlFile=
    (file)=>{           
                urls_TreeView.clear();
                urls = resolveWebHosts(file);
                urls.add("<a href="http://www.google.com/">http://www.google.com</a>");
                urls_TreeView.add_Nodes(urls)
                              .selectFirst();
            };

urls_TreeView.onDrop(loadNmapXmlFile);       
actionsPanel.add_Link("take screnshots of all pages", takeScreenShotsOfAllPages)
            .append_Link("stop execution", ()=> stopExecution = true)
            .append_Link("View Folder with Screenshots", ()=> targetFolder.startProcess());

            
loadNmapXmlFile(@"o2platform.com.xml".local());    
return "ok";           
//O2File:nmap.cs
//O2File:API_Cropper.cs
//O2File:WatiN_IE_ExtensionMethods.cs
//O2Ref:O2_Misc_Microsoft_MPL_Libs.dll
//O2Ref:WatiN.Core.1x.dll

Previous approach that is not working

Here are a couple scripts that document an aproach to load the nmap xml files using the DFT provided on nmap website site (which didn’t work)

download DTD from Nmap website

//var nmapDtd = "http://nmap.org/svn/docs/nmap.dtd".uri().download</a>();

Creating nmap.cs fil

var dtdFile = "nmap.xsd".local();
return dtdFile.xsdCreateCSharpFile();

Creating an empty nmap objec

var nmap = new nmaprun();
return nmap;
//using tempuri.org.nmap
//O2File:nmap.cs
//O2Ref:O2_Misc_Microsoft_MPL_Libs.dll

loading saved nmap file

var nmapSavedFile = @"o2platform.com.xml".local(); 
var nmap = nmapSavedFile.load<nmaprun>();
return nmap;

show xml in sourcecode viewer and nmap object in property grid

var nmapSavedFile = @"o2platform.com.xml".local();  
var nmap = nmapSavedFile.load<nmaprun>();
topPanel.add_SourceCodeViewer()
        .set_Text(nmapSavedFile.fileContents().xmlFormat(),".xml");
topPanel.insert_Left(400,"loaded nmap file")
        .add_PropertyGrid()
        .show(nmap);

the problem with this approach is that it is not working as expected (the xml data is not being correctly loaded into the nmap object and nmaprun.Load(..file..) throws an exception)

November 16, 2011 Posted by | NMap, O2 Scripting, Tools | Leave a comment