Attacking Google Web Toolkit
Attacking Google Web Toolkit
Attacking Google Web Toolkit (GWT) Ron Gutierrez Gotham Digital Science
Introduction
Purpose of Presentation
Why is black-boxing GWT apps hard? Discuss tools and techniques for testing GWT apps This presentation is not about finding flaws in GWT but rather finding flaws in the underlying application built using GWT
Motivation
Googles new web application bug bounty Pays $500 $3,133.70 for bugs Google uses GWT to create some of their web applications (Adwords, Wave, etc ) http://googleonlinesecurity.blogspot.com/2010/ 11/rewarding-web-application-security.html
Agenda
The Attack What common web app vulnerabilities apply? GWT RPC parsing and fuzzing
THE OVERVIEW
Open source Java framework used to create Rich Internet Applications Both server and front-end are written in Java Java-to-Javascript compiler
http://google-web-toolkit-doc-1-5.googlecode.com/files/diagram.png
Benefits
Code re-use between server and client Provides Remote Procedure Call (RPC) mechanism for client-server communication Complex and visually appealing front-ends without the cross-browser headaches Lots of widgets and extensions freely available No browser plugin required
Bootstrap Sequence
http://www.gwt-app.com/app/
app.nocache.js
Browser Detection EDE39CE15AF13C74473DA6EBD45DB656.cache.html
In Expression Languages (i.e. JSF or Struts), presentation logic is run on the server With GWT, all front-end logic is compiled into a Javascript equivalent All client-side code is downloaded to the users browser
The obfuscation is one of the obstacles we hope to solve during this presentation
GWT-RPC
Built-in Remote Procedure Call (RPC) framework Uses a serialization protocol to call remote methods and also send Java data types and objects as parameters from client to server. GWT RPC methods return values serialized using JSON
GWT-RPC Diagram
Browser
Calls greetingService.greetserver(Ron) Client-side code serializes objects and generates RPC request payload RPC Request is sent to the server
POST /sample HTTP/1.1 ..snip.. 5|0|6|http://gwtsite/sample/|29F 4EA1240F157649C12466F01 F46F60|com.test.client.Greetin gService|greetServer|java.lang .String|myInput|1|2|3|4|1|5|6|
GWT Service
GWT-RPC Diagram
Browser
HTTP/1.1 200 OK ..snip.. //OK[1,["Hello, Ron!<br><br>I am running jetty-6.1.x.<br><br>It looks like you are using:<br> Chrome/6.0.472.63"],0,5]
Parses and deserializes the request payload Executes the greetingServer method Sends JSON serialized response to the client
GWT Service
Testing Obstacles
Client-side code is obfuscated by default RPC request payloads are serialized in a custom format Dynamic web app scanners do not correctly test GWT-RPC requests
Testing Obstacles
5|0|8|http://tester:8888/testapp/|9E4C B3D5635C548906BFB576DD18C710|com.test. app.client.GreetingService|greetServer |[Ljava.lang.String;/2600011424|hi|the re|blah|1|2|3|4|1|5|5|3|6|7|8|%26ping% 20-n%2020%20127.0.0.1%26
Testing Obstacles
Security assessments must be finished within a short time frame Researching GWT and overcoming its obstacles is time lost in actual SECURITY TESTING
THE RECONNAISSANCE
Enumerating all GWT-RPCs available on the client We want full application coverage (All Services, Methods and Parameter Values)
Unlocking hidden/restricted functionality available in the UI De-obfuscating the Javascript in order to find potentially interesting data and/or logic
Obfuscated: Javascript is obfuscated and minified to reduce the size of generated files. (Default Option) Pretty: Generated Javascript is human readable Detailed: Javascript contains even more detail, such as verbose variable names
Obfuscated Javascript
Functions and variable names are renamed White space removed Functions re-ordered based on size String values are stored as global variables towards the end of the file
GWTEnum
Python script that automates the GWT-RPC enumeration Downloads a {HEX}.cache.html file and uses regular expressions to enumerate all methods Download at http://www.gdssecurity.com/l/t/
GWTEnum
Usage: gwtenum.py [options] A tool for enumerating GWT RPC methods Options: --version show program's version number and exit -h, --help show this help message and exit -p PROXY, --proxy=PROXY Proxy Host and Port (ie. -p "http://proxy.internet.net:8080") -b, --basicauth User Basic Authentication ( Will be prompted for creds ) -k COOKIES, --cookies=COOKIES Cookies to use when requesting the GWT Javascript Files (ie. -c "JSESSIONID=AAAAAA") -u URL, --url=URL Required: GWT Application Entrypoint Javascript File (ie. *.nocache.js )
GWTEnum
What do we look for in the results? Admin methods Un-called methods Unauthenticated access to methods
GWTEnum
Are the {HEX}.cache.html files accessible by unauthenticated users? Is the login functionality implemented using GWT RPC? If yes, the {HEX}.cache.html file will be leaking out information to unauthenticated users!
GWTENUM DEMO
SyncProxy by gdevelop Can invoke GWT Service methods from pure Java http://code.google.com/p/gwt-syncproxy/
Cookie support is lacking Use SyncProxy to generate the RPC request and then you can capture the request through a proxy
SyncProxy
private static GreetingService rpcService = SyncProxy.newProxyInstance(GreetingService.class , http://example.com/helloApp, greet);
Unlocking UI Features
ALL client-side code is compiled and loaded by the browser Similar to Adobe Flash and MS Silverlight What if the front-end displays different functionality based on a users role?
Unlocking UI Features
Pay close attention to HTTP responses to see if the client is reading a users role or admin flag Roles can be manipulated in order to trick the client into displaying additional functionality Authorization testing is much easier when all application functionality readily available in the UI
THE ATTACK
GWT RPC services are vulnerable to the same type of server-side vulnerabilities as typical web apps. Ex. SQL Injection, Path Manipulation, etc
How about vulnerabilities that affect the browser like Cross-Site Scripting? Do GWT requests contain CSRF protection?
Requests include a X-GWT-Permutation HTTP header Provides minimal protection since Form submissions cannot set headers XmlHttpRequest can not make requests across domains because of Same Origin Policy (SOP)
However, the X-GWT-Permutation value is not unique or tied to a users session. Can be bypassed as long as the X-GWTPermutation request header can be set. Since the X-GWT-Permutation is a static value this will not disrupt automated testing
ActionScript provides the ability to perform requests containing arbitrary headers Can only set HTTP headers not in their defined black-list X-GWT-Permutation is not this list
http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/net/URLRequestHeader.html
Cross Domain Policy Restrictions Can be exploited through Mis-configured cross domain policy file An application on an allowed domain allows upload of SWF file.
Cross-Site Scripting
CSRF protection prevents most GWT applications from being vulnerable to reflected XSS Can still be vulnerable if application is not using GWT RPC
GWT applications are still be vulnerable to stored XSS The GWT client API provide ways to render HTML within widgets (setInnerHTML, setHTML, and HTML constructor)
Request payload is a plaintext, pipe-delimited serialized string Separated into three parts Header String table Payload
Parsing Walkthrough
5|0|8|http://localhost:8080/test/|168 78339F02B83818D264AE430C20468|com.tes t.client.TestService|testMethod|java. lang.String|java.lang.Integer|myInput 1|java.lang.Integer/3438268394|1|2|3| 4|2|5|6|7|8|1|
Parsing Walkthrough
5|0|8|http://localhost:8080/test/|168 78339F02B83818D264AE430C20468|com.tes t.client.TestService|testMethod|java. lang.String|java.lang.Integer|myInput 1|java.lang.Integer/3438268394|1|2|3| 4|2|5|6|7|8|1|
Parsing Walkthrough
String table elements are referenced by the payload Payload reconstructs the method call, parameter types and values
1 http://localhost:8080/test/ 2 16878339F02B83818D264AE430C20468 3 com.test.client.TestService 4 testMethod 5 java.lang.String 6 java.lang.Integer 7 myInput1 8 java.lang.Integer/3438268394
Parsing Walkthrough
1|2|3|4|2|5|6|7|8|1|
1 http://localhost:8080/test/ 2 3 4 5 6 7 16878339F02B83818D264AE430C20468 com.test.client.TestService testMethod java.lang.String java.lang.Integer myInput1
8 java.lang.Integer/3438268394
Parsing Walkthrough
1|2|3|4|2|5|6|7|8|1|
1 http://localhost:8080/test/ 2 3 4 5 6 7 16878339F02B83818D264AE430C20468 com.test.client.TestService testMethod java.lang.String java.lang.Integer myInput1
8 java.lang.Integer/3438268394
Parsing Walkthrough
1|2|3|4|2|5|6|7|8|1|
1 http://localhost:8080/test/ 2 3 4 5 6 7 16878339F02B83818D264AE430C20468 com.test.client.TestService testMethod java.lang.String java.lang.Integer myInput1
8 java.lang.Integer/3438268394
Parsing Walkthrough
1|2|3|4|2|5|6|7|8|1|
1 http://localhost:8080/test/ 2 3 4 5 6 7 16878339F02B83818D264AE430C20468 com.test.client.TestService testMethod java.lang.String java.lang.Integer myInput1
8 java.lang.Integer/3438268394
Parsing Walkthrough
1|2|3|4|2|5|6|7|8|1|
1 http://localhost:8080/test/ 2 3 4 5 6 7 16878339F02B83818D264AE430C20468 com.test.client.TestService testMethod java.lang.String java.lang.Integer myInput1
8 java.lang.Integer/3438268394
Parsing Walkthrough
1|2|3|4|2|5|6|7|8|1|
1 http://localhost:8080/test/ 2 3 4 5 6 7 16878339F02B83818D264AE430C20468 com.test.client.TestService testMethod java.lang.String java.lang.Integer myInput1
8 java.lang.Integer/3438268394
Parsing Walkthrough
1|2|3|4|2|5|6|7|8|1|
1 http://localhost:8080/test/ 2 3 4 5 6 7 16878339F02B83818D264AE430C20468 com.test.client.TestService testMethod java.lang.String java.lang.Integer myInput1
Fuzzible
8 java.lang.Integer/3438268394
Parsing Walkthrough
1|2|3|4|2|5|6|7|8|1|
1 http://localhost:8080/test/ 2 3 4 5 6 7 16878339F02B83818D264AE430C20468 com.test.client.TestService testMethod java.lang.String java.lang.Integer myInput1
8 java.lang.Integer/3438268394
Parsing Walkthrough
1|2|3|4|2|5|6|7|8|1|
1 http://localhost:8080/test/ 2 3 4 5 6 7 16878339F02B83818D264AE430C20468 com.test.client.TestService testMethod java.lang.String java.lang.Integer myInput1
8 java.lang.Integer/3438268394
Parsing Walkthrough
That was a very simple example Different Java types can be serialized Primitive Java types and Objects Arrays, Lists, Vectors..etc Maps Custom Objects
Parsing Walkthrough
Fuzzing all pipe delimited values creates too much output The correct way to fuzz GWT requests is to identify user input and its data type Numeric values should not be tested for string related issues
GWTParse
Python script which parses the GWT-RPC request and identifies user input Supports multiple forms of output so that results can be used with an existing fuzzer Download at http://www.gdssecurity.com/l/t/
GWTParse
Usage: gwtparse.py [options] A tool for parsing GWT RPC Requests Options: --version show program's version number and exit -h, --help show this help message and exit -p, --pretty Output the GWT RPC Request in a human readable format -s SURROUND_VALUE, --surround=SURROUND_VALUE String used to surround all fuzzable values -r REPLACE_VALUE, --replace=REPLACE_VALUE String used to replace all fuzzable values -b, --burp Generates Burp Intruder Output -i RPC_REQUEST, --input=RPC_REQUEST RPC Request Payload (Required) -w WRITE, --write=WRITE Writes Fuzz String to a new output file -a APPEND, --append=APPEND Appends Fuzz String to an existing output file
GWTParse Limitations
Currently only supports the following types: Primitive Java Types and Objects Strings Arraylist, Vector, LinkedList Arrays Custom Objects ( to a limited extent )
Automated Fuzzing
Automated Fuzzing
Parses Burp proxy logs into python objects Interested? Stick around for the next presentation
http://mwielgoszewski.github.com/burpee
Automated Fuzzing
All GWT RPC requests are filtered from the Burp proxy log GWTParser identifies user input for fuzzing the filtered requests GWT requests can now be programmatically fuzzed.
Automated Fuzzing
Usage: gwtfuzzer.py [options] Automates the fuzzing of GWT RPC requests Options: --version show program's version number and exit -h, --help show this help message and exit -b BURP, --burp=BURP Burp logfile to fuzz -f FUZZFILE, --fuzzfile=FUZZFILE File containing attack strings -e ERRORFILE, --errorfile=ERRORFILE File containing error messages -o OUTPUT, --output=OUTPUT Directory to store results -k COOKIES, --cookies=COOKIES Cookies to use when requesting GWT RPC pages -p PROXY, --proxy=PROXY Proxy Host and Port (e.g. -p "http://proxy.internet.net:8080" -i IDRANGE, --idrange=IDRANGE Range of decrements and increments to test parameter manipulation with
Further Reading
http://www.gdssecurity.com/l/b/2009/10/08/gwt-rpcin-a-nutshell/ http://www.gdssecurity.com/l/b/2010/05/06/fuzzinggwt-rpc-requests/ http://www.gdssecurity.com/l/b/2010/07/20/gwtenumenumerating-gwt-rpc-method-calls/ http://groups.google.com/group/Google-WebToolkit/web/security-for-gwt-applications?pli=1 http://code.google.com/p/degwt/wiki/HowDeGWTWo rks
FIN