Thursday, May 6, 2010 At 1:59PM
In a previous post, I went through the process of parsing GWT RPC requests to determine the method and parameter values sent. In this post I will discuss, GwtParse, a tool that I wrote to automate this process in order to easily determine the values within a GWT RPC payload that can actually be manipulated. GwtParse can be downloaded here but I recommend you continue reading…
Why use this tool?
Fuzzing every delimited value in GWT RPC requests is not practical and produces a lot of unnecessary output. GWT client side code is heavily obfuscated, which makes it difficult to identify all the fuzzable values passed in the request by reviewing the JavaScript. Additionally, there could be values passed in the request that do not necessarily originate from user input. For example, assume there is a custom “User” object which contains a numeric property that indicates a user’s role membership. Manipulation of this value could result in unauthorized access to data or privileged functionality. The tool I wrote gwtparse.py will help identifying the meaningful values in a GWT RPC request so that you can more easily identify security bugs in GWT applications during a Black Box assessment.
gwtparse.py
A command line tool that parses a GWT RPC payload and creates a new payload value with all fuzzable values identified. This new payload value can then be plugged into the web application fuzzer of your choice. The tool has currently only been tested using GWT version 2.0.
The following types can be parsed:
- Primitive Java Types and Object (ie. Integer, Double, Byte, etc )
- Strings
- Arraylist, Vector, LinkedList
- Arrays
- Custom Objects ( to a limited extent )
Parsing of custom objects cannot be guaranteed to work correctly in all scenarios as they can be very complex. I created a number of test cases with custom objects, but there is bound to be cases that the current version of my tool cannot handle. I just want to point out a couple key points:
- Parsing a GWT RPC request is as simple as follows:
$ python gwtparse.py -i "5|0|12|http://127.0.0.1:8888/gwt_test/|4E7583E4BED25F58DDD5F1A1D675522A|
com.gwttest.client.GreetingService|greetServer|java.util.ArrayList/3821976829|
com.gwttest.client.CustomObj/427743781|com.gwttest.client.Person/2847577871|
PersonName|java.lang.Integer/3438268394|CustomObjParam1|CustomObjParam2|
CustomObjParam3|1|2|3|4|2|5|6|5|2|7|200|8|7|200|8|6|9|200|10|11|12|10|"
Output from above command:
GWT RPC Payload Fuzz String
5|0|12|http://127.0.0.1:8888/gwt_test/|4E7583E4BED25F58DDD5F1A1D675522A|
com.gwttest.client.GreetingService|greetServer|java.util.ArrayList/3821976829|
com.gwttest.client.CustomObj/427743781|com.gwttest.client.Person/2847577871|
%s|java.lang.Integer/3438268394|%s|%s|%s|1|2|3|4|2|5|6|5|2|7|
%d|8|7|%d|8|6|9|%d|10|11|12|10|
The default output of the script replaces the fuzzable string values with a %s and numeric values with a %d. This is incredibly useful since Java is a strong typed language and will throw an exception if a string value is passed anywhere the application is expecting an Integer.
- Tool output can be customized so that the fuzzable values are easily recognized by your favorite fuzzer. This is done with the “-s” option, which surrounds the values with the string/character of your choice.
- For Burp Suite users, there is the “-b” switch to surround the values using the Burp Intruder Position Value (Section Sign). Note that the Section Sign character is only output to the command-line when run within a terminal that can output UTF-8 values (i.e. Linux, Cygwin). Windows users can add the “-w” or “-a” switches to write or append the output to a text file.
- Lastly, there is the “-p” switch that displays the request in a human readable format. This can be especially useful in identifying the values which belong to a custom object. I have included an example of this at the end of my post.
The gwtparse.py program simply calls functionality available within my GWTParser object. The GWTParser object can be easily reused by testers within their own python fuzzers or tools. Hopefully, application testers will find the tool useful when tackling a GWT application assessment.
If you find GWT RPC payload strings which are not properly handled by my tool (which I am sure there will be), send an email to rgutierrez at gdssecurity.com and I will work on incorporating a fix for the next version. GwtParse can be downloaded here
Sample output when using the –p Switch to Display GWT RPC Requests in Human Readable Format
Serialized Object:
5|0|12|http://127.0.0.1:8888/gwt_test/|4E7583E4BED25F58DDD5F1A1D675522A|
com.gwttest.client.GreetingService|greetServer|java.util.ArrayList/3821976829|
com.gwttest.client.CustomObj/427743781|com.gwttest.client.Person/2847577871|
PersonName|java.lang.Integer/3438268394|CustomObjParam1|CustomObjParam2|
CustomObjParam3|1|2|3|4|2|5|6|5|2|7|200|8|7|200|8|6|9|200|10|11|12|10|
Stream Version: 5
Flags: 0
Column Numbers: 12
Host: http://127.0.0.1:8888/gwt_test/
Hash: 4E7583E4BED25F58DDD5F1A1D675522A
Class Name: com.gwttest.client.GreetingService
Method: greetServer
# of Params: 2
Parameters:
{'flag': False,
'is_array': False,
'is_custom_obj': True,
'is_list': True,
'subtype': 'com.gwttest.client.Person',
'typename': 'java.util.ArrayList/3821976829',
'values': [<Parameter.Parameter object at 0x7fee4a4c>,
<Parameter.Parameter object at 0x7fee4a6c>]}
{ 'flag': False,
'is_array': False,
'is_custom_obj': True,
'is_list': False,
'typename': 'com.gwttest.client.Person/2847577871',
'values': [200, 'PersonName']}
{ 'flag': False,
'is_array': False,
'is_custom_obj': True,
'is_list': False,
'typename': 'com.gwttest.client.Person/2847577871',
'values': [200, 'PersonName']}
{'flag': False,
'is_array': False,
'is_custom_obj': True,
'is_list': False,
'typename': 'com.gwttest.client.CustomObj/427743781',
'values': [200,
'CustomObjParam1',
'CustomObjParam2',
'CustomObjParam3',
'CustomObjParam1']}
The above “pretty” output shows that the RPC call has two parameters. The first parameter is an ArrayList of Person Objects with two member variables and the second parameter is another object called CustomObj which has five member variables.
Author: Ron Gutierrez
©Aon plc 2023