owasp webscarab uncovering the hidden treasures. overview webscarab aims to facilitate the review of...
TRANSCRIPT
OWASP WebScarab
Uncovering the hidden treasures
Overview
• WebScarab aims to facilitate the review of web applications
• Functional operations
• Security Operations
• It was written by a techie for personal use
• Not always intuitive
• Hidden keystrokes
• Lack of examples
Objectives
• Show participants how some of the less obvious features work
• Using the spider
• Request Transforms
• Using the Fuzzer
• Comparing Responses
• Searching WebScarab history
Objectives
• Show participants how some of the less obvious features work
• Exploring the Beanshell
• Writing Proxy Intercept scripts
• Writing Script Manager Scripts
• Writing other scripts
WebScarab Spider
Huh - Shared Cookies?
Request Transforms
Using the Fuzzer
• You can hand craft a request, one parameter at a time
Using the Fuzzer
• Or you can use an existing request as a template!
Fuzzer – Parameter fields
• Location = Where the parameter can be found
• Path, Fragment do not work
• Name = Obvious
• Type = Meaningless (I can’t remember why I added it!)
• Value = default value when not being fuzzed
• Priority = drives the permutations.
• Same priority = lockstep, different = cross product
Fuzzer – Fuzz sources
• From a file (1 per line)
• From a regex
Fuzzer – Reviewing results
Fuzzer – Reviewing results
Searching in TextAreas
• Press Ctrl-F in the TextArea to show the Search Bar
• Or click in the TextArea, then click Find
Searching in TextAreas
• Search string is actually a regex.
• WebScarab highlights any groups specified
• This means you need to escape regex special characters!
Comparing responses
Comparing responses
• You can also view the changes in a single window, rather than side by side
• Pressing Ctrl-L in the compare window. This is a toggle key.
Searching history
Searching history
• Search expression is a BeanShell snippet
• BeanShell is just interpreted Java, with some leniencies
• Two predefined variables, request and response
• If the expression returns true, the conversation is shown
• Exceptions are counted as “false”
• Very powerful, but not terribly friendly
Request and Response API
• String getMethod()
• void setMethod(String method)
• HttpUrl getURL()
• void setURL(HttpUrl url)
• void setURL(String url) throws MalformedURLException
• String getVersion()
• void setVersion(String version)
• String getVersion()
• void setVersion(String version)
• String getStatus()
• void getStatus(String status)
• String getMessage()
• void setMessage(String message)
• String getStatusLine()
Message API
• String[] getHeaderNames()
• String getHeader(String name)
• void setHeader(String name, String value)
• void addHeader(String name, String value)
• void deleteHeader(String name)
• NamedValue[] getHeaders()
• void setheaders(NamedValue[] headers)
• byte[] getContent()
• void setContent(byte[] content)
Search expression examples
• response.toString().indexOf("alert") > -1
• new String(response.content).indexOf(“alert”) > -1
• request.getHeader(“Content-Type”).startsWith(“application”)
• request.getMethod().equals(“POST”)
• new String(response.content).matches("(?s).*\tat .*") // stack traces
• request.getURL().toString().startsWith("https://") && response.getHeader("Set-Cookie").indexOf(“secure”) == -1
Exploring the BeanShell
Proxy -> BeanShell
• Allows scripted modifications to proxied conversations
• Useful for things like Ajax apps, or thick clients (think timeouts!)
• Scripts must follow a very simple template:
import … <whatever classes you use>
public Response fetchResponse(HTTPClient nextPlugin, Request request) throws IOException { response = nextPlugin.fetchResponse(request); return response;}
Proxy -> BeanShell
• Probably the most useful “general” example:
import org.owasp.webscarab.model.Request;import org.owasp.webscarab.model.Response;import org.owasp.webscarab.httpclient.HTTPClient;import java.io.IOException;import org.owasp.webscarab.plugin.proxy.swing.ManualEditFrame;public Response fetchResponse(HTTPClient nextPlugin, Request request) throws IOException { ManualEditFrame mef = new ManualEditFrame(); if (false) request = mef.editRequest(request); response = nextPlugin.fetchResponse(request); if (false) response = mef.editResponse(request, response); return response;}
Proxy->BeanShell
• Other simple examples:
request.deleteHeader("HeaderName");response = fetchResponse(request);
request.deleteHeader("HeaderName");response = fetchResponse(request);response.addheader("X-MyMarker", "I deleted HeaderName");
request.setHeader(“Cookie”, “JSESSIONID=somevalue”);
Script Manager
• An alternative way of executing scripts
• Script structure is somewhat different
• See the explanation for details
• E.g. Intercept RequestCalled when a new request has been submitted by the browseruse connection.getRequest() and connection.setRequest(request) to perform changes
request = connection.getRequest();request.setHeader(“Cookie”, “JSESSIONID=somevalue”);connection.setRequest(request);
Script Manager
• Big difference is that you can load multiple scripts per hook
• Can be enabled and disabled independently
Script Manager caveat
• Watch out for declaring objects with the same names in multiple scripts, though.
• If you use formal declarations, BeanShell will error out and tell you that the object already exists.
Response response = connection.getResponse();
• I hope to fix this at some stage.
BeanShell persistence
• It is possible to persist values across script invocations
import org.owasp.webscarab.model.*;Request r = connection.getRequest();Integer i = bsf.lookupBean("count");if (i == null) i = new Integer(0);if (i.intValue() %2 == 0) { // do something}i = new Integer(i.intValue()++);bsf.registerBean("count", i);connection.setRequest(r);
Scripted plugin
• Intended to replace “cat request | nc target 80 | grep . . . “
• Allows for multi-threaded execution of requests (4 threads hardcoded)
• Object-oriented processing of results
getConversationCount()getConversationAt(int)getRequest(int)getRequest(ConversationID)getResponse(int)getResponse(ConversationID)getConversationProperty(int, String)getConversationProperty(ConversationID, String)getChildCount(String) // == an URLgetChildAt(String, int) // == an URLgetUrlProperty(String, String)
fetchResponse(Request)
hasAsyncCapacity()submitAsyncRequest(Request)hasAsyncResponse()getAsyncResponse()isAsyncBusy()
addConversation(Response)
Scripted plugin
• Complex example