Archive for the 'Application Security' Category

Aug 10 2010

Constricting the Web: The GDS Burp API

Published by Marcin Wielgoszewski under Application Security

Last week, I presented “Constricting the Web: Offensive Python for Web Hackers” at Black Hat USA 2010 and DEF CON 18 with Nathan Hamiel. In this talk, we presented methods and techniques for using Python in custom tools to allow testers to be more effective at finding flaws in web applications. One of the tools I demo’d during our talk was the GDS Burp API.

Introducing the GDS Burp API

At GDS, of the many web application security testing tools available, we often use PortSwigger’s Burp Suite. We found Burp to fit well with our testing methodology, partly because it seems the target audience is penetration testers like us. One of the features I like most is the ability to record requests/responses that were intercepted by its proxy. After a thorough crawl of the application (having visited every page, and submitted every form), this proxy log contains a treasure trove of data. Because of my lack of desire to write extensions in Java and current limitations of the Burp Extender API, I wrote a toolkit in Python which I call the GDS Burp API.

What is it?

The GDS Burp API exposes a Python object interface to requests/responses recorded by Burp (whether Proxy/Spider/Repeater, etc). The API is used to parse Burp logs, creating a list of “Burp objects” that contain the request / response data and related meta-data. To help visualize this, imagine a request and its associated response within your Burp history now available to you as a single Python object outside of Burp and free of Extender limitations.

One of the main reasons for doing this is because web application scanners usually do not provide enough context into the actual requests they send and the responses they receive. I like to have a full understanding into the underlying scanner implementation, so that I know in what scenarios a scanner will be effective versus where I will have to resort to manual/semi-automated methods.

How do I use it?

Using the GDS Burp API is relatively simple, and takes only a beginner level understanding to Python to take advantage of. After you’ve performed a thorough crawl, logging each request/response, you use the gds.pub.burp.parse() method to parse the proxy log into a list of Burp objects.

>>> import gds.pub.burp
>>> proxylog = gds.pub.burp.parse("my_application_proxy.log")
>>> proxylog
[<Burp 1>, <Burp 2>, <Burp 3>, <Burp 4>, <Burp 5>]

Within each Burp object there are several properties, as seen in an example object below:

>>> pprint(proxylog[2].__dict__)
{'host': 'http://demo.blah:80',
 'index': 3,
 'ip_address': '65.61.137.117',
 'parameters': {'query': {'txtSearch': 'hello'}},
 'request': {'body': '',
                  'headers': {'Cookie': 'ASP=a0iq3c550j1xtyqbjajmymi4;',
                              'User-Agent': 'Mozilla/5.0 (X11; U; Linux x86_64; },
             'method': 'GET',
             'path': '/search.aspx?txtSearch=hello',
             'version': 'HTTP/1.1'},
 'response': {'body': '\\r\\n\\r\\n<!DOCTYPE html PUBLIC ..snip..',
              'headers': {'Content-Length': '7275',
                          'Content-Type': 'text/html; charset=utf-8',
                          'Server': 'Microsoft-IIS/6.0',
                          'X-Aspnet-Version': '2.0.50727',},
              'reason': 'OK',
              'status': 200,
              'version': 'HTTP/1.1'},
 'time': '1:56:38 PM',
 'url': ParseResult(scheme='http', netloc='demo.blah:80', path='/search.aspx', params='', query='txtSearch=hello', fragment='')}

You can access these object members directly or via object API methods such as get_request_header("User-Agent"), get_request_path(), get_response_body(), get_response_status(), etc. The full generated API documentation for the GDS Burp API can be accessed online or within the docs folder included in the zip file.

What can I do with it?

The purpose of this API is to simply provide a Python object interface to the request/response data that was recorded by Burp. I did not want to implement any fuzzing or analyses capabilities in the API, because I felt that that would detract people from writing their own. I do not want to limit anyone by including a scanner, since someone else’s requirements may and very likely will be different than my own.

A couple ideas to get you started that I have done on my own are the following:

  • Replaying individual requests as-is
  • Replaying sequences of requests (such as a login or a checkout operation)
  • Comparing two proxy logs, returning a diff output of the URLs and parameters submitted
  • Fuzzing requests (creating a Burp object) and appending them to the original’s replayed list
  • Comparing response bodies and headers of fuzzed requests against their original
  • Using difflib module in Python standard library to return a diff-formatted HTML output of two response bodies

Download Constricting the Web: Offensive Python for Web Hackers.

Visit GDS Burp API on GitHub.

No responses yet

Jul 20 2010

GWTEnum: Enumerating GWT-RPC Method Calls

Published by Ron Gutierrez under Application Security

Google Web Toolkit (GWT) applications do not provide a straight forward way to enumerate all services and method calls. By default, GWT obfuscates client-side Javascript code which, as a tester, prevents one from being able to easily enumerate GWT-RPC method calls. Most pen testers typically limit testing to only the method calls that can be captured while crawling the application.

Using a technique described by Sripathi Krishnan, one can programmatically de-obfuscate GWT’s Javascript files in order to enumerate all of the exposed method calls. This typically leads to the discovery of vulnerable un-used or administrative methods that may not normally be seen during normal application use. It is worth noting that this technique can usually be performed anonymously, potentially leaving a GWT application open to attack if authentication and authorization checks are not properly performed. What follows is a short walkthrough of Krishnan’s enumeration technique along with a tool that I wrote to automate the process.

De-obfuscating the Javascript
First, it is worth noting that not all GWT applications you will encounter will be obfuscated. GWT applications can be compiled in one of the following three modes:

Obfuscated: Javascript is obfuscated and minified to reduce the size of the generated files. This is the default compilation mode for GWT applications.

Pretty: Generated Javascript is human readable

Detailed: Javascript code contains even more detail, such as verbose variable names.

When a GWT application first loads in the browser, the main entry page will typically call a Javascript file with the “.nocache.js” suffix. This file is responsible in detecting the browser type and loading the correct browser-specific Javascript code for the GWT application. Most of the core GWT client logic is kept inside files with the “.cache.html” suffix. These are ultimately the files we are most interested in since they also contain the logic responsible for invoking GWT-RPC calls.

Before we dive into the de-obfuscation logic, let’s start by analyzing the similarities between Javascript created when the GWT application is compiled in “obfuscated mode” versus “pretty mode” to see how RPC calls are performed. Below is the “pretty” version a generic “greetServer” method call which accepts one string parameter.

Pretty Mode

function $greetServer(this$static, arr, callback){
    var $e0, payload, requestId, streamWriter, clientSerializationStreamWriter;
    requestId = requestId_0++;
    !!$stats && $stats({moduleName:$moduleName, sessionId:$sessionId,
          subSystem:'rpc', evtGroup:requestId,
          method:'GreetingService_Proxy.greetServer', millis:(new Date).getTime(), type:'begin'});
    try {
        append(streamWriter.encodeBuffer, '' + $addString(streamWriter, 'com.gwttest.client.GreetingService'));
        append(streamWriter.encodeBuffer, '' + $addString(streamWriter, 'greetServer'));
        append(streamWriter.encodeBuffer, '1');
        append(streamWriter.encodeBuffer, '' + $addString(streamWriter, '[Ljava.lang.String;/2600011424'));
        $writeObject(streamWriter, arr);
        payload = $toString_3(streamWriter);
        $doInvoke(this$static, ($clinit_187() , 'GreetingService_Proxy.greetServer'), requestId, payload, callback);

By analyzing this method call, we see a hash table is assigning the “method” key a string value containing the GWT-RPC service and method name ( ‘GreetingService_Proxy.greetServer’ ). Within a try block we also see the building of a GWT-RPC Payload string which contains how many parameters the method expects (One Parameter)

append(streamWriter.encodeBuffer, '1');

and the data type it is expecting (String)

append(streamWriter.encodeBuffer, '' + $addString(streamWriter, '[Ljava.lang.String;/2600011424'));

Now, search through the obfuscated version of the same GWT application using the following regular expression:

"^function \w+\(.*method\:([A-Za-z0-9_\$]+),.*$"

You should eventually encounter a matching method. Below is an example of the obfuscated version of the same method (code expanded for readability)

Obfuscated Mode

function aH(b,c,d){
      var a,f,g,h,i;
      g=Ky++;
      !!$stats&&$stats({moduleName:$moduleName,sessionId:$sessionId,subSystem:AQ,evtGroup:g,
        method:kS,millis:(new Date).getTime(),type:lS});
      h=(i=yy(new vy,b.b,b.e),i.e=0,lK(i.f),lK(i.g),mM(i.h),i.b=DJ(new AJ),iy(i,i.c),iy(i,i.d),i);
      try{
              Ey(h.b,KO+fy(h,mS));
              Ey(h.b,KO+fy(h,nS));
              Ey(h.b,oS);
              Ey(h.b,KO+fy(h,pS));
              hy(h,c);
              f=Cy(h);
              !!$stats&&$stats({moduleName:$moduleName,sessionId:
                      $sessionId,subSystem:AQ,evtGroup:g,
                      method:kS,millis:(new Date).getTime(),type:qS});
              Py(b,(oz(),kS),g,f,d)
..snip..

The highlighted areas of the obfuscated code above are the parts we are most interested in. The service and method name is once again assigned to the “method” element of the hash table. The value of the variable “kS” is assigned towards the end of the same Javascript file.

kS='GreetingService_Proxy.greetServer

Within the “try” block, you’ll see several “Ey” method calls which correspond to the “append” method we previously saw in the “pretty” version. Looking at the second parameter of the 3rd append call we see that the variable “oS” is passed.

Ey(h.b,oS);

By searching the Javascript code for the assigned value of “oS” we see that it is the expected value of “1”.

oS='1'

Moving onto the next append method call

Ey(h.b,KO+fy(h,pS));

the “fy” method call is called, which corresponds to the “$addString” method call seen in the “pretty” version. The value assigned to the second parameter of the “fy” method will provide us the data type the GWT-RPC method is expecting.

pS='[Ljava.lang.String;/2600011424'

As you can see, the process of performing de-obfuscation manually is time consuming and tedious due to the amount of variable tracing involved. For this reason I created GWTEnum, a python tool that automates the process of enumerating GWT-RPC method calls for any GWT application compiled in obfuscated mode.

The Tool
GWTEnum works by analyzing the “nocache.js” file, which contains references to the underlying “cache.html” files where the actual method calls lie. Simply point GWTEnum to the “nocache.js” file and the tool will take care of the rest. A good example of how the tool works can be seen in the following example, where GWTEnum was run against the Whirled.com virtual world website. This site was chosen for this example since it is accessible to the public and uses GWT compiled in obfuscated mode.


>python gwtenum.py –u "http://www.whirled.com/gwt/frame/frame.nocache.js"

Analyzing http://www.whirled.com/gwt/frame/02DA50B7EB86809D55630981FE1D7F1A.cach
e.html

===========================
Enumerated Methods
===========================

FacebookService_Proxy.getStoryFields(com.threerings.msoy.facebook.gwt.FacebookService$StoryKey/2584007011 )
FacebookService_Proxy.trackPageRequest( I,java.lang.String/2004016611 )
FacebookService_Proxy.trackStoryPosted(com.threerings.msoy.facebook.gwt.FacebookService$StoryKey/2584007011,java.lang.String/2004016611,java.lang.String/2004016611 )
WebMemberService_Proxy.escapeTheme( )
WebMemberService_Proxy.getInvitation( java.lang.String/2004016611,Z )
WebMemberService_Proxy.getMemberCard( I )
WebMemberService_Proxy.isThemeManager( I )
WebMemberService_Proxy.noteNewVisitor(com.threerings.msoy.data.all.VisitorInfo/3279131818,java.lang.String/2004016611,Z )
WebMemberService_Proxy.trackTestAction( java.lang.String/2004016611,java.lang.String/2004016611,com.threerings.msoy.data.all.VisitorInfo/3279131818 )
WebUserService_Proxy.getApp( I )
WebUserService_Proxy.getConnectConfig( )
WebUserService_Proxy.loadLaunchConfig( I )
WebUserService_Proxy.validateSession( java.lang.String/2004016611,java.lang.String/2004016611,I,I )


As shown above, we now have a complete list of all accessible RPC methods. Once the available methods have been enumerated, there are several ways to invoke RPC calls to these methods.

The simplest method of invocation would be for cases where you have already encountered another method (through normal site use) that accepts the same number and type of parameters. In this case, you can intercept the original method call with an intercepting proxy like Burp and change the method name in order to execute the new method. There will likely be cases, however, where the new method accepts a unique combination of different parameters than the methods you have already encountered. For these cases, you can use a tool such as GWT SyncProxy in order to invoke GWT-RPC calls using Java.

In summary, GWTEnum aims to eliminate the complexities posed by obfuscated GWT code that normally make testing these applications more difficult. Hopefully application testers out there find this tool and enumeration technique helpful when encountering an obfuscated GWT application. If you encounter any issue while using the tool, feel free to send an email to rgutierrez at gdssecurity.com

GWTEnum can be downloaded here

No responses yet

May 17 2010

ISSD Conference

Published by AndrewN under Application Security

The very first International Secure Systems Development Conference (ISSD) is being held this week in London, and GDS is very happy to be supporting it from the start as both speakers and conference sponsors. Event details are as follows:

The International Secure Systems Development Conference
London 20-21st May 2010, Westminster Conference Centre
Getting Started in Building Security In

If you are planning on attending, Justin and Matt both speak on Friday (Day 2):

Be sure to stop by the GDS booth, as Justin will be signing and giving away a few free copies of his latest book “SQL Injection Attacks and  Defense”.

No responses yet

Next »