<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>GDS Security Blog &#187; Application Security</title>
	<atom:link href="http://www.gdssecurity.com/l/b/category/application-security/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gdssecurity.com/l/b</link>
	<description>Gotham Digital Science Security Blog</description>
	<lastBuildDate>Tue, 10 Aug 2010 14:38:41 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Constricting the Web: The GDS Burp API</title>
		<link>http://www.gdssecurity.com/l/b/2010/08/10/constricting-the-web-the-gds-burp-api/</link>
		<comments>http://www.gdssecurity.com/l/b/2010/08/10/constricting-the-web-the-gds-burp-api/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 14:38:41 +0000</pubDate>
		<dc:creator>Marcin Wielgoszewski</dc:creator>
				<category><![CDATA[Application Security]]></category>

		<guid isPermaLink="false">http://www.gdssecurity.com/l/b/?p=534</guid>
		<description><![CDATA[Last week, I presented &#8220;Constricting the Web: Offensive Python for Web Hackers&#8221; 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 [...]]]></description>
			<content:encoded><![CDATA[<p>Last week, I presented &#8220;Constricting the Web: Offensive Python for Web Hackers&#8221; 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&#8217;d during our talk was the <a href="http://mwielgoszewski.github.com/burpee/">GDS Burp API</a>.</p>
<p><strong>Introducing the GDS Burp API</strong></p>
<p>At GDS, of the many web application security testing tools available, we often use PortSwigger&#8217;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.</p>
<p><strong>What is it?</strong></p>
<p>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.</p>
<p>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.</p>
<p><strong>How do I use it?</strong></p>
<p>Using the GDS Burp API is relatively simple, and takes only a beginner level understanding to Python to take advantage of.  After you&#8217;ve performed a thorough crawl, logging each request/response, you use the <tt>gds.pub.burp.parse()</tt> method to parse the proxy log into a list of Burp objects.</p>
<p><code>&gt;&gt;&gt; import gds.pub.burp<br />
&gt;&gt;&gt; proxylog = gds.pub.burp.parse("my_application_proxy.log")<br />
&gt;&gt;&gt; proxylog<br />
[&lt;Burp 1&gt;, &lt;Burp 2&gt;, &lt;Burp 3&gt;, &lt;Burp 4&gt;, &lt;Burp 5&gt;]</code></p>
<p>Within each Burp object there are several properties, as seen in an example object below:</p>
<p><code>&gt;&gt;&gt; pprint(proxylog[2].__dict__)<br />
{'host': 'http://demo.blah:80',<br />
&nbsp;'index': 3,<br />
&nbsp;'ip_address': '65.61.137.117',<br />
&nbsp;'parameters': {'query': {'txtSearch': 'hello'}},<br />
&nbsp;'request': {'body': '',<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'headers': {'Cookie': 'ASP=a0iq3c550j1xtyqbjajmymi4;',<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'User-Agent': 'Mozilla/5.0 (X11; U; Linux x86_64; },<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'method': 'GET',<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'path': '/search.aspx?txtSearch=hello',<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'version': 'HTTP/1.1'},<br />
&nbsp;'response': {'body': '\\r\\n\\r\\n&lt;!DOCTYPE html PUBLIC ..snip..&#39;,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;headers&#39;: {&#39;Content-Length&#39;: &#39;7275&#39;,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;Content-Type&#39;: &#39;text/html; charset=utf-8&#39;,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;Server&#39;: &#39;Microsoft-IIS/6.0&#39;,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;X-Aspnet-Version&#39;: &#39;2.0.50727&#39;,},<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;reason&#39;: &#39;OK&#39;,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;status&#39;: 200,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;version&#39;: &#39;HTTP/1.1&#39;},<br />
&nbsp;&#39;time&#39;: &#39;1:56:38 PM&#39;,<br />
&nbsp;&#39;url&#39;: ParseResult(scheme=&#39;http&#39;, netloc=&#39;demo.blah:80&#39;, path=&#39;/search.aspx&#39;, params=&#39;&#39;, query=&#39;txtSearch=hello&#39;, fragment=&#39;&#39;)}</code></p>
<p>You can access these object members directly or via object API methods such as <tt>get_request_header("User-Agent")</tt>, <tt>get_request_path()</tt>, <tt>get_response_body()</tt>, <tt>get_response_status()</tt>, 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.</p>
<p><strong>What can I do with it?</strong></p>
<p>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&#8217;s requirements may and very likely will be different than my own.</p>
<p>A couple ideas to get you started that I have done on my own are the following:</p>
<ul>
<li>Replaying individual requests as-is</li>
<li>Replaying sequences of requests (such as a login or a checkout operation)</li>
<li>Comparing two proxy logs, returning a diff output of the URLs and parameters submitted</li>
<li>Fuzzing requests (creating a Burp object) and appending them to the original&#8217;s replayed list</li>
<li>Comparing response bodies and headers of fuzzed requests against their original</li>
<li>Using difflib module in Python standard library to return a diff-formatted HTML output of two response bodies</li>
</ul>
<p><a href="http://www.gdssecurity.com/l/constricting_the_web_final.pdf">Download Constricting the Web: Offensive Python for Web Hackers</a>.</p>
<p><a href="http://mwielgoszewski.github.com/burpee/">Visit GDS Burp API on GitHub</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gdssecurity.com/l/b/2010/08/10/constricting-the-web-the-gds-burp-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GWTEnum: Enumerating GWT-RPC Method Calls</title>
		<link>http://www.gdssecurity.com/l/b/2010/07/20/gwtenum-enumerating-gwt-rpc-method-calls/</link>
		<comments>http://www.gdssecurity.com/l/b/2010/07/20/gwtenum-enumerating-gwt-rpc-method-calls/#comments</comments>
		<pubDate>Tue, 20 Jul 2010 14:09:02 +0000</pubDate>
		<dc:creator>Ron Gutierrez</dc:creator>
				<category><![CDATA[Application Security]]></category>

		<guid isPermaLink="false">http://www.gdssecurity.com/l/b/?p=486</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>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.<br />
<br />
Using a technique described by <a href="http://code.google.com/p/degwt/wiki/HowDeGWTWorks" target="new">Sripathi Krishnan</a>, 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.<br />
<br />
<strong>De-obfuscating the Javascript</strong><br />
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:<br />
<br />
Obfuscated: Javascript is obfuscated and minified to reduce the size of the generated files. This is the default compilation mode for GWT applications.<br />
<br />
Pretty: Generated Javascript is human readable<br />
<br />
Detailed: Javascript code contains even more detail, such as verbose variable names.<br />
<br />
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.<br />
<br />
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.<br />
<br />
<u>Pretty Mode</u></p>
<pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace;color: #000000;font-size: 12px;padding: 5px;width: 100%"><code>function $greetServer(this$static, arr, callback){
    var $e0, payload, requestId, streamWriter, clientSerializationStreamWriter;
    requestId = requestId_0++;
    !!$stats &amp;&amp; $stats({moduleName:$moduleName, sessionId:$sessionId,
          subSystem:'rpc', evtGroup:requestId,</code><font color='red'>
          method:'GreetingService_Proxy.greetServer'</font><code>, millis:(new Date).getTime(), type:'begin'});
    </code><font color='red'>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'));</font><code>
        $writeObject(streamWriter, arr);
        payload = $toString_3(streamWriter);
        $doInvoke(this$static, ($clinit_187() , 'GreetingService_Proxy.greetServer'), requestId, payload, callback);

</code></pre>
<p>
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)<br />
<br />
<code>append(streamWriter.encodeBuffer, </code><font color='red'>'1'</font><code>);</code><br />
<br />
and the data type it is expecting (String)<br />
<br />
<code>append(streamWriter.encodeBuffer, '' + $addString(streamWriter, </code><font color='red'>'[Ljava.lang.String;/2600011424'));</font><br />
<br />
Now, search through the obfuscated version of the same GWT application using the following regular expression:<br />
<br />
<code>"^function \w+\(.*method\:([A-Za-z0-9_\$]+),.*$"</code><br />
<br />
You should eventually encounter a matching method. Below is an example of the obfuscated version of the same method (code expanded for readability)<br />
<br />
<u>Obfuscated Mode</u><br />
</p>
<pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace;color: #000000;font-size: 12px;line-height: 14px;padding: 5px;width: 100%"><code>function aH(b,c,d){
      var a,f,g,h,i;
      g=Ky++;
      !!$stats&amp;&amp;$stats({moduleName:$moduleName,sessionId:$sessionId,subSystem:AQ,evtGroup:g,
        </code><font color="red">method:kS</font><code>,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);
      </code><font color="red">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));</font><code>
              hy(h,c);
              f=Cy(h);
              !!$stats&amp;&amp;$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..

</code></pre>
<p>
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.<br />
<br />
<code>kS='GreetingService_Proxy.greetServer</code><br />
<br />
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.<br />
<br />
<code>Ey(h.b,</code><font color='red'>oS</font><code>);</code><br />
<br />
By searching the Javascript code for the assigned value of “oS” we see that it is the expected value of “1”.<br />
<br />
<code>oS='1'</code><br />
<br />
Moving onto the next append method call<br />
<br />
<code>Ey(h.b,KO+</code><font color='red'>fy(h,pS)</font><code>);</code><br />
<br />
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.<br />
<br />
<code>pS='[Ljava.lang.String;/2600011424'</code><br />
<br />
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 <a href="http://www.gdssecurity.com/l/t/d.php?k=GwtEnum">GWTEnum</a>, a python tool that automates the process of enumerating GWT-RPC method calls for any GWT application compiled in obfuscated mode.<br />
<br />
<b>The Tool</b><br />
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.</p>
<p><code><br />
&gt;python gwtenum.py –u "http://www.whirled.com/gwt/frame/frame.nocache.js"</p>
<p>Analyzing http://www.whirled.com/gwt/frame/02DA50B7EB86809D55630981FE1D7F1A.cach<br />
e.html</p>
<p>===========================<br />
Enumerated Methods<br />
===========================</p>
<p>FacebookService_Proxy.getStoryFields(com.threerings.msoy.facebook.gwt.FacebookService$StoryKey/2584007011 )<br />
FacebookService_Proxy.trackPageRequest( I,java.lang.String/2004016611 )<br />
FacebookService_Proxy.trackStoryPosted(com.threerings.msoy.facebook.gwt.FacebookService$StoryKey/2584007011,java.lang.String/2004016611,java.lang.String/2004016611 )<br />
WebMemberService_Proxy.escapeTheme( )<br />
WebMemberService_Proxy.getInvitation( java.lang.String/2004016611,Z )<br />
WebMemberService_Proxy.getMemberCard( I )<br />
WebMemberService_Proxy.isThemeManager( I )<br />
WebMemberService_Proxy.noteNewVisitor(com.threerings.msoy.data.all.VisitorInfo/3279131818,java.lang.String/2004016611,Z )<br />
WebMemberService_Proxy.trackTestAction( java.lang.String/2004016611,java.lang.String/2004016611,com.threerings.msoy.data.all.VisitorInfo/3279131818 )<br />
WebUserService_Proxy.getApp( I )<br />
WebUserService_Proxy.getConnectConfig( )<br />
WebUserService_Proxy.loadLaunchConfig( I )<br />
WebUserService_Proxy.validateSession( java.lang.String/2004016611,java.lang.String/2004016611,I,I )</code><br />
<br />
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.  </p>
<p>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 <a href="http://www.gdevelop.com/w/blog/2010/02/25/syncproxy-0-1-1/" target="new">GWT SyncProxy</a> in order to invoke GWT-RPC calls using Java. </p>
<p>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<br />
<br />
GWTEnum can be downloaded <a href="http://www.gdssecurity.com/l/t/d.php?k=GwtEnum">here</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gdssecurity.com/l/b/2010/07/20/gwtenum-enumerating-gwt-rpc-method-calls/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ISSD Conference</title>
		<link>http://www.gdssecurity.com/l/b/2010/05/17/issd-conference/</link>
		<comments>http://www.gdssecurity.com/l/b/2010/05/17/issd-conference/#comments</comments>
		<pubDate>Mon, 17 May 2010 15:17:32 +0000</pubDate>
		<dc:creator>AndrewN</dc:creator>
				<category><![CDATA[Application Security]]></category>

		<guid isPermaLink="false">http://www.gdssecurity.com/l/b/?p=465</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>The very first <strong><a href="http://issdconference.com/index.php">International Secure Systems Development Conference (ISSD)</a></strong> 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:</p>
<p style="text-align: center;"><strong>The International Secure Systems Development Conference<br />
London 20-21st May 2010, Westminster Conference Centre<br />
Getting Started in Building Security In</strong></p>
<p>If you are planning on attending, Justin and Matt both speak on Friday<em> (Day 2)</em>:</p>
<ul>
<li> 11:15 <a href="http://www.issdconference.com/index.php?option=com_content&amp;view=article&amp;id=188">Managing Business Processes for Secure Software Development &#8211; Matt Bartoldus</a></li>
</ul>
<ul>
<li> 3:30 <a href="http://www.issdconference.com/index.php?option=com_content&amp;view=article&amp;id=209">Tips &amp; Tricks for Retro-fitting Secure Code</a> &#8211; Justin Clarke</li>
</ul>
<p>Be sure to stop by the GDS booth, as Justin will be signing and giving away a few free copies of his latest book &#8220;SQL Injection Attacks and  Defense&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gdssecurity.com/l/b/2010/05/17/issd-conference/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fuzzing GWT RPC Requests</title>
		<link>http://www.gdssecurity.com/l/b/2010/05/06/fuzzing-gwt-rpc-requests/</link>
		<comments>http://www.gdssecurity.com/l/b/2010/05/06/fuzzing-gwt-rpc-requests/#comments</comments>
		<pubDate>Thu, 06 May 2010 17:59:07 +0000</pubDate>
		<dc:creator>Ron Gutierrez</dc:creator>
				<category><![CDATA[Application Security]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.gdssecurity.com/l/b/?p=382</guid>
		<description><![CDATA[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. [...]]]></description>
			<content:encoded><![CDATA[<p>In a <a href="http://www.gdssecurity.com/l/b/2009/10/08/gwt-rpc-in-a-nutshell/" target="_new">previous post</a>,  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 <a href="http://www.gdssecurity.com/l/t/d.php?k=GwtParse">here</a> but I recommend you continue reading&#8230;<br />
<br />
<strong>Why use this tool?</strong></p>
<p><strong><span style="font-weight: normal">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 <strong>gwtparse.py</strong> 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.</span></strong><br />
<br />
<strong>gwtparse.py</strong></p>
<p>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.</p>
<p>The following types can be parsed:</p>
<ul>
<li>Primitive Java Types and Object (ie. Integer, Double, Byte, etc )</li>
<li>Strings</li>
<li>Arraylist, Vector, LinkedList</li>
<li>Arrays</li>
<li>Custom Objects ( to a limited extent )</li>
</ul>
<p>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:</p>
<ul>
<li>Parsing a GWT RPC request is as simple as follows</li>
</ul>
<p><code>$ python gwtparse.py -i "5|0|12|http://127.0.0.1:8888/gwt_test/|4E7583E4BED25F58DDD5F1A1D675522A|<br />
com.gwttest.client.GreetingService|greetServer|java.util.ArrayList/3821976829|<br />
com.gwttest.client.CustomObj/427743781|com.gwttest.client.Person/2847577871|<br />
PersonName|java.lang.Integer/3438268394|CustomObjParam1|CustomObjParam2|<br />
CustomObjParam3|1|2|3|4|2|5|6|5|2|7|200|8|7|200|8|6|9|200|10|11|12|10|"</code><br />
<br />
Output from above command:<br />
<br />
GWT RPC Payload Fuzz String</p>
<p><code>5|0|12|http://127.0.0.1:8888/gwt_test/|4E7583E4BED25F58DDD5F1A1D675522A|<br />
com.gwttest.client.GreetingService|greetServer|java.util.ArrayList/3821976829|<br />
com.gwttest.client.CustomObj/427743781|com.gwttest.client.Person/2847577871|<br />
%s|java.lang.Integer/3438268394|%s|%s|%s|1|2|3|4|2|5|6|5|2|7|<br />
%d|8|7|%d|8|6|9|%d|10|11|12|10|</code></p>
<p>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.</p>
<ul>
<li>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.</li>
</ul>
<ul>
<li>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.</li>
</ul>
<ul>
<li>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.</li>
</ul>
<p>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.</p>
<p>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 <a href="http://www.gdssecurity.com/l/t/d.php?k=GwtParse">here</a><br />
<br />
<strong>Sample output when using the –p Switch to Display GWT RPC Requests in Human Readable Format</strong><br />
<br />
<code>Serialized Object:</code></p>
<p><code>5|0|12|http://127.0.0.1:8888/gwt_test/|4E7583E4BED25F58DDD5F1A1D675522A|<br />
com.gwttest.client.GreetingService|greetServer|java.util.ArrayList/3821976829|<br />
com.gwttest.client.CustomObj/427743781|com.gwttest.client.Person/2847577871|<br />
PersonName|java.lang.Integer/3438268394|CustomObjParam1|CustomObjParam2|<br />
CustomObjParam3|1|2|3|4|2|5|6|5|2|7|200|8|7|200|8|6|9|200|10|11|12|10|</code></p>
<p><code>Stream Version: 5<br />
Flags: 0<br />
Column Numbers: 12<br />
Host: http://127.0.0.1:8888/gwt_test/<br />
Hash: 4E7583E4BED25F58DDD5F1A1D675522A<br />
Class Name: com.gwttest.client.GreetingService<br />
Method: greetServer<br />
# of Params: 2</p>
<p>Parameters:<br />
{'flag': False,<br />
'is_array': False,<br />
'is_custom_obj': True,<br />
'is_list': True,<br />
'subtype': 'com.gwttest.client.Person',<br />
'typename': 'java.util.ArrayList/3821976829',<br />
'values': [&lt;Parameter.Parameter object at 0x7fee4a4c&gt;,<br />
&lt;Parameter.Parameter object at 0x7fee4a6c&gt;]}</p>
<p>{        'flag': False,<br />
'is_array': False,<br />
'is_custom_obj': True,<br />
'is_list': False,<br />
'typename': 'com.gwttest.client.Person/2847577871',<br />
'values': [200, 'PersonName']}<br />
{         'flag': False,<br />
'is_array': False,<br />
'is_custom_obj': True,<br />
'is_list': False,<br />
'typename': 'com.gwttest.client.Person/2847577871',<br />
'values': [200, 'PersonName']}</p>
<p></code></p>
<p><code>{'flag': False,<br />
'is_array': False,<br />
'is_custom_obj': True,<br />
'is_list': False,<br />
'typename': 'com.gwttest.client.CustomObj/427743781',<br />
'values': [200,<br />
'CustomObjParam1',<br />
'CustomObjParam2',<br />
'CustomObjParam3',<br />
'CustomObjParam1']}</code></p>
<p>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.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gdssecurity.com/l/b/2010/05/06/fuzzing-gwt-rpc-requests/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>OWASP NYNJMetro &#8211; Pentesting Adobe Flex Applications</title>
		<link>http://www.gdssecurity.com/l/b/2010/04/23/owasp-nynjmetro-pentesting-adobe-flex-applications/</link>
		<comments>http://www.gdssecurity.com/l/b/2010/04/23/owasp-nynjmetro-pentesting-adobe-flex-applications/#comments</comments>
		<pubDate>Fri, 23 Apr 2010 13:20:56 +0000</pubDate>
		<dc:creator>Marcin Wielgoszewski</dc:creator>
				<category><![CDATA[Application Security]]></category>

		<guid isPermaLink="false">http://www.gdssecurity.com/l/b/?p=372</guid>
		<description><![CDATA[I&#8217;ve uploaded my slides from the presentation I gave last week at the OWASP NYC Chapter on Pentesting Adobe Flex Applications.
In an upcoming post, I&#8217;ll describe in detail working with custom objects and how to craft AMF messages containing them and other data types.
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve uploaded my <a href="http://www.gdssecurity.com/l/OWASP_NYNJMetro_Pentesting_Flex.pdf" title="Pentesting Adobe Flex Applications">slides</a> from the presentation I gave last week at the <a href="http://www.owasp.org/index.php/NYNJMetro" title="OWASP NYNJMetro">OWASP NYC Chapter</a> on Pentesting Adobe Flex Applications.</p>
<p>In an upcoming post, I&#8217;ll describe in detail working with custom objects and how to craft AMF messages containing them and other data types.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gdssecurity.com/l/b/2010/04/23/owasp-nynjmetro-pentesting-adobe-flex-applications/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Penetrating Intranets through Adobe Flex Applications</title>
		<link>http://www.gdssecurity.com/l/b/2010/03/17/penetrating-intranets-through-adobe-flex-applications/</link>
		<comments>http://www.gdssecurity.com/l/b/2010/03/17/penetrating-intranets-through-adobe-flex-applications/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 15:23:35 +0000</pubDate>
		<dc:creator>Marcin Wielgoszewski</dc:creator>
				<category><![CDATA[Application Security]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.gdssecurity.com/l/b/?p=356</guid>
		<description><![CDATA[In my last post, Pentesting Adobe Flex Applications with a Custom AMF Client, I described how one could write a client using Python and PyAMF to perform manual penetration testing of Flex applications.  The example application I focused on utilized RemoteObjects and communicated via binary AMF encoded messages, a common roadblock for security testers. [...]]]></description>
			<content:encoded><![CDATA[<p>In my last post, <a href="http://www.gdssecurity.com/l/b/2009/11/11/pentesting-adobe-flex-applications-with-a-custom-amf-client/" title="Pentesting Adobe Flex Applications with a Custom AMF Client">Pentesting Adobe Flex Applications with a Custom AMF Client</a>, I described how one could write a client using Python and PyAMF to perform manual penetration testing of Flex applications.  The example application I focused on utilized RemoteObjects and communicated via binary AMF encoded messages, a common roadblock for security testers.  If you are new to penetration testing Flex applications, I suggest reading my previous post to familiarize yourself with Flex and the techniques I discussed.</p>
<p></p>
<p>In this post, I&#8217;ll show how you can exploit Flex applications that use BlazeDS to gain access to internal networks and other hosts behind the firewall.  BlazeDS is a Java-based remoting server that allows developers to utilize existing application logic and web services in Flex applications.  The following also applies to applications that use Adobe LiveCycle Data Services ES.</p>
<p></p>
<p>A common insecure configuration that we encounter when assessing Flash applications is an insecure crossdomain.xml policy file (usually hosted within a web site&#8217;s root directory). By default, a Flash application hosted on domain A cannot access resources from domain B unless domain B has configured their cross-domain policy to allow domain A. More often than not, the cross domain policy file has been configured to allow the entire world access rather than a specific list of trusted domains. Now, assuming the cross domain policy file has been secured, developers of Flex applications that consume data from external web services must now incorporate this restriction into their design. This makes it difficult to develop Flex applications that will be hosted on multiple, possibly untrusted domains.</p>
<p></p>
<p>Enter BlazeDS. To get around the restrictions imposed by cross-domain policy files, BlazeDS allows developers to configure &#8220;Proxy Services&#8221;. Using Proxy Services, BlazeDS will make calls to remote service destinations on behalf of the Flex application. BlazeDS Proxy Services allows Flex applications to consume SOAP and Web Services hosted on other domains without the need for a cross-domain policy. A common use case for proxy services is to allow external access to internally hosted web services via a specified destination. A typical proxy service is configured like so (see <a href="http://livedocs.adobe.com/blazeds/1/blazeds_devguide/rpc_httpws_04.html" title="BlazeDS Developer Guide">BlazeDS Developer Guide</a> for more detail):</p>
<pre># contents of WEB-INF\flex\proxy-config.xml:
&lt;service id="proxy-service" class="flex.messaging.services.HTTPProxyService"&gt;
&nbsp;&nbsp;...
&nbsp;&nbsp;
&nbsp;&nbsp;&lt;destination id="web-service"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;properties&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;dynamic-url&gt;http://ws.localdomain:9899/web/service/content.jsp&lt;/dynamic-url&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/properties&gt;
&nbsp;&nbsp;&lt;/destination&gt;
&nbsp;&nbsp;
&nbsp;&nbsp;&lt;destination id="soap-service"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;properties&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;wsdl&gt;http://ws.localdomain:9899/ws?wsdl&lt;/wsdl&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;soap&gt;*&lt;/soap&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/properties&gt;
&nbsp;&nbsp;&lt;/destination&gt;
&lt;/service&gt;
</pre>
<p></p>
<p>In the <em>proxy-config.xml</em> above, we have two destinations defined: web-service and soap-service.  If you look closely, the <em>soap</em> property has an asterisk (wildcard) defined.  This property can define an absolute domain and path, however like cross-domain policies, an asterisk permits BlazeDS to make requests to any hosts it can reach on the network that match this property. This is a common occurrence, due in part to sample configuration files supplied with BlazeDS and lack of awareness on part of those responsible for securing the application server.  In more secure configurations, this property is set to a strict domain or path (such as the web-service destination).</p>
<p></p>
<p>If you want to build a Flex client that communicates with Proxy Services, you&#8217;ll need to familiarize yourself with the following objects (refer to the <a href="http://livedocs.adobe.com/flex/3/langref/index.html" title="Adobe Flex Language Reference">Flex Language Reference</a> for more information):</p>
<ul>
<li>mx.rpc.http.HTTPService (url)</li>
<li>mx.rpc.http.mxml.HTTPService(url)</li>
<li>mx.messaging.messages.HTTPRequestMessage (url)</li>
<li>mx.rpc.soap.WebService (endpointURI)</li>
<li>mx.rpc.soap.mxml.SOAPService (endpointURI)</li>
<li>mx.messaging.messages.SOAPMessage (url)</li>
</ul>
<p>Without further ado, I&#8217;d like to introduce Blazentoo, a tool I developed to exploit such functionality. With Blazentoo, you can exploit insecurely configured Proxy Services and browse internal websites, potentially those on trusted corporate networks. Just recently I was working on an assessment and I was able to successfully compromise an internal application via an exposed BlazeDS server – as this wasn&#8217;t the first (or last) time, I decided it was time to build Blazentoo.</p>
<p>To use Blazentoo, you&#8217;ll need to know the following (most of this information can be obtained by examining HTTP requests proxied through a tool like <a href="http://www.portswigger.net/suite/" title="Burp Suite">Burp Suite</a>, <a href="http://www.charlesproxy.com/" title="Charles Proxy">Charles Proxy</a>, or <a href="http://www.owasp.org/index.php/Category:OWASP_WebScarab_Project" title="OWASP WebScarab">WebScarab</a>):</p>
<ul>
<li>AMF/HTTP endpoint (the message broker servlet that flex requests are routed to)</li>
<li>The &#8220;destination&#8221; id (if this is left blank, the DefaultHTTP destination is used)</li>
<li>An optional &#8220;channel&#8221; id (leave blank if unknown)</li>
</ul>
<p>If using SOAP, you&#8217;ll need to know the following additional information:</p>
<ul>
<li>A SOAP Action associated with the destination id, and/or</li>
<li>URL of the WSDL (required if no destination id is defined)</li>
</ul>
<p>Below is a screenshot of Blazentoo in action.  Note that the URL being accessed in this example is &#8220;http://localhost/&#8221;.  This could just as easily have been an internal IP address or hostname.</p>
<p><a href="/l/blazentoo.png"><img alt="Blazentoo in action" src="/l/blazentoo.png" class="alignnone" width="258" height="199" /></a></p>
<p>You can download Blazentoo from our <a href="http://www.gdssecurity.com/l/t.php" title="Gotham Digital Science Tools">tools</a> page.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gdssecurity.com/l/b/2010/03/17/penetrating-intranets-through-adobe-flex-applications/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Multiple DOM-Based XSS in Dojo Toolkit SDK</title>
		<link>http://www.gdssecurity.com/l/b/2010/03/12/multiple-dom-based-xss-in-dojo-toolkit-sdk/</link>
		<comments>http://www.gdssecurity.com/l/b/2010/03/12/multiple-dom-based-xss-in-dojo-toolkit-sdk/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 19:11:33 +0000</pubDate>
		<dc:creator>Bix</dc:creator>
				<category><![CDATA[Application Security]]></category>

		<guid isPermaLink="false">http://www.gdssecurity.com/l/b/?p=345</guid>
		<description><![CDATA[We released an advisory today to Bugtraq regarding a DOM-Based XSS bug I found in the Dojo Toolkit SDK 1.4.1 and earlier versions. The Dojo team was informed on February 19, 2010 and released the fix today along with some other security bugs. If you want some more information on this bug as well as [...]]]></description>
			<content:encoded><![CDATA[<p>We released an advisory today to Bugtraq regarding a DOM-Based XSS bug I found in the Dojo Toolkit SDK 1.4.1 and earlier versions. The Dojo team was informed on February 19, 2010 and released the fix today along with some other security bugs. If you want some more information on this bug as well as the other bugs that were fixed, see their <a title="security bulletin" href="http://dojotoolkit.org/blog/post/dylan/2010/03/dojo-security-advisory">security bulletin</a>.</p>
<p>The files identified with the XSS issues are primarily designed for testing; however a quick Google search will identify numerous sites that have deployed these files along with the core framework components. Unfortunately, this is evidence of a much larger issue. All too often, test code gets deployed to production and ultimately leads to a security exposure. This is clearly a recipe for disaster!!! Folks, please clean up your web root. You clean up your house when relatives come by, right? You wouldn&#8217;t want them tripping over your GI Joe&#8217;s and breaking their leg! It&#8217;s the same thing, more or less : )</p>
<p><strong>Overview</strong></p>
<p>The Dojo Toolkit is an open source modular JavaScript library/toolkit designed to ease the rapid development of cross platform, JavaScript/Ajax based applications and web sites. Multiple instances of DOM-based Cross Site Scripting (XSS) vulnerabilities were found in the _testCommon.js and runner.html files within the SDK. The XSS vulnerabilities appear to affect all websites that deploy any of the affected SDK files.</p>
<p>More information on DOM-based XSS can be found at <a title="OWASP's site" href="http://www.owasp.org/index.php/DOM_Based_XSS">OWASP&#8217;s site</a>.</p>
<p><strong>Technical Details</strong></p>
<p>File: dojo-release-1.4.1-src\dojo-release-1.4.1-src\dijit\tests\_testCommon.js<br />
1) Data enters via &#8220;theme&#8221; URL parameter through the window.location.href property.<br />
Line 25:<br />
<code>var str = window.location.href.substr(window.location.href.indexOf("?")+1).split(/#/);</code><br />
..snip..<br />
2) The &#8220;theme&#8221; variable with user-controllable input is then passed into &#8220;themeCss&#8221; and &#8220;themeCssRtl&#8221; which is then passed to document.write().</p>
<p>Writing the un-validated data to HTML creates the XSS exposure.<br />
Line 54:<br />
..snip..<br />
<code>var themeCss = d.moduleUrl("dijit.themes",theme+"/"+theme+".css");<br />
var themeCssRtl = d.moduleUrl("dijit.themes",theme+"/"+theme+"_rtl.css");<br />
document.write('&lt;link rel="stylesheet" type="text/css" href="'+themeCss+'"&gt;');<br />
document.write('&lt;link rel="stylesheet" type="text/css" href="'+themeCssRtl+'"&gt;');</code></p>
<p>==================================================</p>
<p>File: dojo-release-1.4.1-src\dojo-release-1.4.1-src\util\doh\runner.html<br />
1) Data enters via &#8220;dojoUrl&#8221; or &#8220;testUrl&#8221; URL parameters through the window.location.search property.<br />
Line 40:<br />
<code>var qstr = window.location.search.substr(1);</code><br />
..snip..</p>
<p>2) The &#8220;dojoUrl&#8221; and &#8220;testUrl&#8221; variables with user-controllable input are passed to document.write(). Writing the un-validated data to HTML creates the XSS exposure.<br />
Line 64:<br />
<code>document.write("&lt;scr"+"ipt type='text/javascript' djConfig='isDebug: true' src='"+dojoUrl+"'&gt;&lt;/scr"+"ipt&gt;");<br />
..snip..<br />
document.write("&lt;scr"+"ipt type='text/javascript' src='"+testUrl+".js'&gt;&lt;/scr"+"ipt&gt;");</code></p>
<p><strong>Proof-of-Concept Exploit</strong></p>
<p>This vulnerability can be exploited against websites that have deployed any of the 145 SDK files which reference _testCommon.js.</p>
<p>Reproduction Request:<br />
http://WebApp/dijit/tests/form/test_Button.html?theme=&#8221;/&gt;&lt;script&gt;alert(/xss/)&lt;/script&gt;</p>
<p>(Note: test_Button.html is one of the SDK files that includes the _testCommon.js file)</p>
<p>==================================================</p>
<p>This vulnerability can be exploited against any website that has deployed the runner.html file.</p>
<p>Reproduction Request:<br />
http://WebApp/util/doh/runner.html?dojoUrl=&#8217;/&gt;foo&lt;/script&gt;&lt;&#8217;&#8221;&lt;script&gt;alert(/xss/)&lt;/script&gt;</p>
<p><strong>Recommendation</strong></p>
<p>Update to Dojo Toolkit SDK 1.4.2</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gdssecurity.com/l/b/2010/03/12/multiple-dom-based-xss-in-dojo-toolkit-sdk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Abusing WCF to Perform Remote Port Scans</title>
		<link>http://www.gdssecurity.com/l/b/2010/02/12/abusing-wcf-to-perform-remote-port-scans/</link>
		<comments>http://www.gdssecurity.com/l/b/2010/02/12/abusing-wcf-to-perform-remote-port-scans/#comments</comments>
		<pubDate>Fri, 12 Feb 2010 13:00:47 +0000</pubDate>
		<dc:creator>Brian Holyfield</dc:creator>
				<category><![CDATA[Application Security]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.gdssecurity.com/l/b/?p=267</guid>
		<description><![CDATA[Last weekend at Shmoocon, I demonstrated how an attacker can trick certain WCF web services into performing an unauthorized port scan of machines behind a firewall.  For those that were not able to attend the talk, the slides are posted here. The part that covers the port scanning technique may not be clear in isolation, so [...]]]></description>
			<content:encoded><![CDATA[<p>Last weekend at Shmoocon, I demonstrated how an attacker can trick certain WCF web services into performing an unauthorized port scan of machines behind a firewall.  For those that were not able to attend the talk, the <a href="http://www.gdssecurity.com/l/Attacking_WCF_Web_Services-Holyfield-Shmoocon_2010.pdf">slides are posted here</a>. The part that covers the port scanning technique may not be clear in isolation, so I’ll try and explain it in detail. The problem is related to the WSDualHttpBinding, so in order to understand how the scanning technique works you must first understand some WSDualHttpBinding basics. </p>
<p><strong>The WSDualHttpBinding</strong></p>
<p>The <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.wsdualhttpbinding.aspx">WSDualHttpBinding</a> is one of several “Duplex” WCF bindings.  The term Duplex refers to the bi-directional nature of the communication channel, meaning that both the client and the service can directly send messages to each other.   This is ideal for scenarios where a service needs to “push” data down to a client, rather than the alternative of constantly polling the server for a callback.   In order to do this over HTTP, which is by nature a one-way protocol, WCF sets up a dedicated HTTP listener port on the client that accepts incoming HTTP requests from the service (known as the callback channel).   If you are like me, you probably just raised an eyebrow when I said that WCF sets up an inbound HTTP listener on the client machine.  This scenario sounds odd from a security perspective, which is what initially caught my eye.</p>
<p>The first step in establishing a session with WSDualHttpBinding requires the client and server to negotiate the duplex connection.  This negotiation is a required part of the connection sequence, and is the mechanism that can be abused to perform remote port scanning.  The negotiation starts with the client sending a “CreateSequence” SOAP request to the web service endpoint.  A typical CreateSequence request is shown below.</p>
<p><img src="http://www.gdssecurity.com/l/wsd1.png" alt="" /></p>
<p>As you can see, the CreateSequence request includes a “ReplyTo” address.  This address is the URL of the callback channel at which the client expects to receive callback requests from the service.  When the service receives this request, it reacts by initiating a “CreateSequenceResponse” to the ReplyTo address, and then responding to the original request with a “202 Accepted”.  Conceptually this is represented by the diagram below.  Note that the circled numbers represent the order in which each request and response occurs. <br />
<img src="http://www.gdssecurity.com/l/wsd2.png" alt="" /><br />
The scenario above represents the intended chain of events for a CreateSequence negotiation.  There are a few important things to note:</p>
<ul>
<li>There are two separate HTTP conversations occurring.  One is between the client and the service over port 80, and the other is between the service and the client on port 8000.</li>
<li>When the service receives a CreateSequence request, it will immediately attempt to issue the CreateSequenceResponse request to the address that is passed within the ReplyTo value.  This does NOT have to be the same address (or port) where the CreateSequence request originated from. </li>
</ul>
<p>Next, let’s introduce another slightly more complex example.  In this scenario, we have 4 machines:</p>
<ul>
<li>The client, which in this case will end up being the bad guy</li>
<li>The WCF service that uses WSDualHttpBinding</li>
<li>Two unrelated hosts that will serve as targets</li>
</ul>
<p>The client in this case will send two CreateSequence requests to the service.  The first request will include a ReplyTo address of Target1, and the second request will include a ReplyTo address of Target2.  Again, the circled numbers represent the order in which each request and response occurs. <br />
<img src="http://www.gdssecurity.com/l/wsd3.png" alt="" /><br />
This diagram is much more interesting as it depicts what is certainly NOT an intended use case.  As illustrated above, the first CreateSequence request (1) causes the service to initiate a connection to Target1 on port 8000, just as the second CreateSequence request  (4) does to Target2.   Even more interesting is that the “Accepted” HTTP response (7) to the second CreateSequence request (4) does not occur until AFTER the connection to Target1 times out (5).  This means that the delay between the second CreateSequence (4) and the subsequent &#8220;Accepted&#8221; response (7) was directly related to the response time of the first CreateSequenceResponse attempt (5).  It appears that a WCF service will not respond to a new CreateService request until all previous CreateSequenceResponse requests have either been acknowledged or timed out. </p>
<p><strong>What Does this Mean?</strong></p>
<p>Based on the behavior described above, the CreateSequence HTTP response delay is an effective mechanism to determine the state of a prior connection request.  By issuing multiple requests to different hosts and ports, we can use this behavior to probe remote hosts from the server hosting the WCF service.  Depending on the connectivity available from the host, we can even probe systems that would not otherwise be available to us (such as on an internal network or DMZ). </p>
<p>In order to prove this theory, I wrote a utility to issue successive CreateSequence requests to a WCF service that each have a different ReplyTo address and/or port.  It measures the time between a CreateSequence request and the &#8220;202 Accepted&#8221; response in an attempt to determine whether a previous request was successful.  The utility is fairly simple and operates as follows (assume that <strong>Service</strong> is the WCF service we want to mis-use, and that the <strong>Target</strong> is the machine we want to port scan): </p>
<ul>
<li><strong>Request #1:</strong>  Issue a CreateSequence request to <strong>Service</strong> which will ReplyTo <strong>Target</strong> on <strong>Port 1</strong>.  The delay (if any) on this first request is not associated with a connection we initiated so the timing of this first response is ignored. </li>
<li><strong>Request #2:</strong> Issue another CreateSequence request to <strong>Service</strong> which will ReplyTo <strong>Target</strong> on <strong>Port2</strong>.  A timer is used to measure the time between this request the “202 Accepted” response from <strong>Service</strong>.   This response will not occur until the previous CreateSequenceResponse has been acknowledged or timed out.  As such, this delay will be used to infer the outcome of the probe caused by Request #1.</li>
<li><strong>Request #3:</strong>  Issue a CreateSequence request to <strong>Service</strong> which will ReplyTo <strong>Target</strong> on <strong>Port3</strong>.  A timer is used to measure the time between this request the “202 Accepted” response from <strong>Service</strong>.   This response will not occur until the previous CreateSequenceResponse has been acknowledged or timed out.  As such, this delay will be used to infer the outcome of the probe caused by Request #2.</li>
<li>and on and on and on…</li>
</ul>
<p><strong>Proof of Concept</strong></p>
<p>As a proof of concept, I deployed an instance of the <a href="http://msdn.microsoft.com/en-us/library/ms751450.aspx">MSDN CalculatorDuplex</a> sample service to a virtual machine in the Microsoft Azure cloud to use as a test case.  This service is a simple calculator web service that uses the WCF WSDualHttpBinding.  As it turns out, the Azure environment was a great place to test this concept since Azure VMs actually reside on an internal private 10.x.x.x network behind a firewall.  Conceptually, this is represented in the diagram below (note, this is an over simplified diagram based on what I have seen in my limited testing with Azure).</p>
<p><img src="http://www.gdssecurity.com/l/wsd4.png" alt="" /></p>
<p>Based on an analysis of the VM running the sample service, it also appeared that the VMs within the Azure environment typically run IIS on port 20000.  I used the utility to remotely scan other VMs within the 10.x.x.x address space on this port through requests to the Calculator service.  The results from the initial test are shown in the screenshot below.
<div style="text-align: center;"><img src="http://www.gdssecurity.com/l/wsd5.png" alt="" /></div>
<p> </p>
<p>As you can see, the result of each probe is inferred based on the average response time of the other requests.  The scan above shows that four of the probes returned very quickly (around 114 ms) while the others appear to have timed out.  The probes that do not time out in this case are the other internal VMs that are up and running IIS on port 20000.  As a second test, I used the utility to probe ports on the localhost of the machine running the Calculator service.  As you can see below, the probe to port 3389 times out while the others return after about 1 second.  So in this case, the Remote Desktop service is running on the localhost.</p>
<p>
<div align="center"><img src="http://www.gdssecurity.com/l/wsd6.png" alt="" /></div>
</p>
<p>So to summarize, this appears to be a potential design flaw within the WCF create sequence negotiation process.  As a result, any service that uses this binding can be abused by a remote user to scan other hosts (even those behind a firewall that they may not otherwise have access to).  Certain web-based attacks can also be proxied through these services since the remote attacker has the ability to control not only the target address and port, but also the complete URI that will be requested.  The source code for the scanner utility is <a href="http://www.gdssecurity.com/l/t/WsDualScanner.cs">posted here</a> for reference.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gdssecurity.com/l/b/2010/02/12/abusing-wcf-to-perform-remote-port-scans/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Breaking Password Based Encryption with Azure</title>
		<link>http://www.gdssecurity.com/l/b/2010/01/29/breaking-password-based-encryption-with-azure/</link>
		<comments>http://www.gdssecurity.com/l/b/2010/01/29/breaking-password-based-encryption-with-azure/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 21:02:20 +0000</pubDate>
		<dc:creator>Brian Holyfield</dc:creator>
				<category><![CDATA[Application Security]]></category>

		<guid isPermaLink="false">http://www.gdssecurity.com/l/b/?p=223</guid>
		<description><![CDATA[During a recent security review, we came across a .NET application that was encrypting query string data to thwart parameter based attacks. We had not been given access to the source code, but concluded this since each .aspx page was being passed a single Base64 encoded parameter which, when decoded, produced binary data with varying [...]]]></description>
			<content:encoded><![CDATA[<p>During a recent security review, we came across a .NET application that was encrypting query string data to thwart parameter based attacks. We had not been given access to the source code, but concluded this since each .aspx page was being passed a single Base64 encoded parameter which, when decoded, produced binary data with varying 16 byte blocks (likely AES considering it is the algorithm of choice for many .NET developers).</p>
<p><strong>The Code</strong></p>
<p>After doing some research (aka plugging the words &#8220;.NET”, “Query String” and “Encryption&#8221; into Google), we identified several references to a piece of code that had been written and published a few years back for encrypting query strings in .NET. The code we found even used the same parameter name as our application did to pass the encrypted query string data to each page, so we were fairly confident it was the code they were using.</p>
<p>Having written <a href="http://spf.codeplex.com/" target="_blank">SPF</a>, I am always interested to see how other applications implement cryptography since I know it is not always easy to do properly. In addition to the common problem of re-using the same IV for every encrypted query string, we noticed that the key was entirely derived from a static password embedded in the code (it was being derived using the .NET Framework PasswordDeriveBytes class directly from the literal string value &#8220;key&#8221;).</p>
<p>For reference, I&#8217;ve included the Decrypt method below:</p>
<pre>  private const string ENCRYPTION_KEY = "key";

  public static string Decrypt(string inputText)
  {
    RijndaelManaged rijndaelCipher = new RijndaelManaged();
    byte[] encryptedData = Convert.FromBase64String(inputText);
    byte[] salt = Encoding.ASCII.GetBytes(ENCRYPTION_KEY.Length.ToString());
    PasswordDeriveBytes secretKey = new PasswordDeriveBytes(ENCRYPTION_KEY, salt);

    using (ICryptoTransform decryptor = rijndaelCipher.CreateDecryptor(secretKey.GetBytes(32),</pre>
<pre>    secretKey.GetBytes(16)))
    {
      using (MemoryStream memoryStream = new MemoryStream(encryptedData))
      {
        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
        {
          byte[] plainText = new byte[encryptedData.Length];
          int decryptedCount = cryptoStream.Read(plainText, 0, plainText.Length);
          return Encoding.Unicode.GetString(plainText, 0, decryptedCount);
        }
      }
    }
  }</pre>
<p>Password based encryption schemes like this are common in many applications, since the key can easily be represented by a word or passphrase.  The nice thing from an attacker’s perspective is that regardless of how large the real encryption key is, the feasibility of a brute force attack is largely dependent on the length and complexity of the <strong>password</strong> used to derive the key and not the key itself.  So for this example, even though they are using 256-Bit AES encryption (generally considered secure), the password used to generate the key is easily brute forced since it is only 3 characters.</p>
<p>Given the code we found, the first and obvious test was to try decrypting our query string values with the same &#8220;key&#8221; string.  Sadly that didn&#8217;t work.  After trying several educated guesses at what we <em>thought </em>could be the password, I decided to clone the decryption logic into a .NET console utility and run a recursive alphanumeric brute force against the password. The approach was rather simple:</p>
<ul>
<li>Take one of our encrypted samples</li>
<li>Loop through every alphanumeric character combination</li>
<li>Using the identical logic shown above, derive the key and decrypt</li>
</ul>
<p>The caveat here is that we really don&#8217;t know what value to expect when it decrypts, but chances are it should be just ASCII text (and hopefully a query string name/value pair).  The good news is that most of the keys we generate will generate a <strong>CryptographicException</strong>, so we can rule out any key value that results in this exception.   For safety’s sake I decided to convert the results of every successful decrypt to ASCII and save for further review if needed.  </p>
<p><strong>The Cloud</strong></p>
<p>After running the utility for an hour or so I realized that a laptop Windows instance was not the optimal environment for running a brute force password crack (not to mention it rendered the machine pretty useless in the meantime).  Having recently signed up for a test account on the Microsoft Azure cloud platform for some unrelated WCF testing, I thought this would be a great opportunity to test out the power of the Microsoft cloud.  Even better, Azure is FREE to use until February 1, 2010.</p>
<p>The concept of using the cloud to crack passwords is not new.  Last year, David Campbell wrote about how to <a href="http://news.electricalchemy.net/2009/10/cracking-passwords-in-cloud.html" target="_blank">use Amazon EC2 to crack a PGP passphrase</a>.  Having never really worked with the Azure platform (aside from registering for a test account), I first needed to figure out the best way to perform this task in the environment. Windows Azure has two main components, which both run on the Azure Fabric Controller (the hosting environment of Windows Azure):</p>
<ul>
<li><span style="text-decoration: underline;">Compute</span> &#8211; Provides the computation environment.  Supports &#8220;Web Roles&#8221; (essentially web services and web applications) and &#8220;Worker Roles&#8221; (services that run in the background)</li>
<li><span style="text-decoration: underline;">Storage</span> &#8211; Provides scalable storage (Blobs, Tables, Queue)</li>
</ul>
<p>I decided to create and deploy a &#8220;Worker Role&#8221; to run the password cracking logic, and then log all output to a table in the storage layer.  I’ll spare you the boring details of how to port a console utility to a Worker Role, but it’s fairly simple.  The first run of the Worker Role was able to produce approximately 1,000,000 decryption attempts every 30 minutes, or about 555 tries/second.  This was definitely faster than the speed I was getting on the laptop, but not exactly what I was hoping for from &#8220;the cloud&#8221;. </p>
<p>I did some research on how the Fabric Controller allocates resources to each application, and as it turns out there are 4 VM sizes available as shown below:</p>
<p> </p>
<table border="0" cellspacing="0" cellpadding="0" width="609">
<tbody>
<tr>
<td width="173"><strong>Compute Instance Size</strong></td>
<td width="91"><strong>CPU</strong></td>
<td><strong>Memory</strong></td>
<td width="130"><strong>Instance Storage</strong></td>
<td width="132"><strong>I/O Performance</strong></td>
</tr>
<tr>
<td width="173" valign="top">Small</td>
<td width="91" valign="top">1.6 GHz</td>
<td valign="top">1.75 GB</td>
<td width="130" valign="top">225 GB</td>
<td width="132" valign="top">Moderate</td>
</tr>
<tr>
<td width="173" valign="top">Medium</td>
<td width="91" valign="top">2 x 1.6 GHz</td>
<td valign="top">3.5 GB</td>
<td width="130" valign="top">490 GB</td>
<td width="132" valign="top">High</td>
</tr>
<tr>
<td width="173" valign="top">Large</td>
<td width="91" valign="top">4 x 1.6 GHz</td>
<td valign="top">7 GB</td>
<td width="130" valign="top">1,000 GB</td>
<td width="132" valign="top">High</td>
</tr>
<tr>
<td width="173" valign="top">Extra large</td>
<td width="91" valign="top">8 x 1.6 GHz</td>
<td valign="top">14 GB</td>
<td width="130" valign="top">2,040 GB</td>
<td width="132" valign="top">High</td>
</tr>
</tbody>
</table>
<p> </p>
<p>The size of the VM used by the Worker Role is controlled through the role properties that get defined when the role is configured in Visual Studio.  By default, roles are set to use the &#8220;small&#8221; VM, but this is easily changed to another size.  The task at hand is all about CPU, so I increased the VM to &#8220;Extra Large&#8221; and redeployed the worker role. </p>
<p>Expecting significant performance gains, I was disappointed to see that the newly deployed role was running at the <strong>same exact speed as before</strong>.  The code was clearly not taking full advantage of all 8 cores, so a little more research led me to the Microsoft Task Parallel Library (TPL).  TPL is part of the Parallel Extensions, a managed concurrency library developed by Microsoft for .NET that was specifically designed to make running parallel processes in a multi-core environment easy.  Parallel Extensions are included by default as part of the .NET 4.0 Framework release.  Unfortunately Azure does not currently support .NET 4.0, but luckily TPL is supported on .NET 3.5 through the <a href="http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx" target="_blank">Reactive Extensions for .NET</a> (Rx).</p>
<p>Once you install Rx, you can reference the <strong>System.Threading.Tasks</strong> namespace which includes the <strong>Parallel</strong> class.  Of specific interest for our purpose is the <strong>Parallel.For</strong> method.  Essentially, this method executes a <strong>for</strong> loop in which iterations may run in parallel.  Best of all, the job of spawning and terminating threads, as well as scaling the number of threads according to the number of available processors, is done automatically by the library.</p>
<p>As expected, this was the secret sauce I had been missing.  Once re-implemented with a <strong>Parallel.For</strong> loop, the speed increased significantly to 7,500,000 decryption attempts every 30 minutes, or around 4,200 tries/second.   That’s 1M tries every 4 minutes, meaning we can crack a 5 character alphanumeric (lowercase) password in about 4 hours, or the same 6 character equivalent in about 6 days.   This is still significantly slower than the speed obtained by Campbell’s experiment, but then again he was using a distributed program designed specifically for fast password cracking (as opposed to the proof of concept code we are using here), not to mention I am also logging output to a database in the storage layer.  At the time of writing, the password hasn’t cracked but the worker process has only been running for about 24 hours (so there’s still plenty of time).  What remains to be seen is how fast this same code would run in the Amazon EC2 cloud, which may be a comparison worth doing.</p>
<p>The important takeaway here is not about the power of the cloud (since there’s nothing we can do to stop it), but rather about Password Based Encryption.  Regardless of key length and choice of algorithm, the strength of your encryption always boils down to the weakest link&#8230;which in this case, is the choice of password.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gdssecurity.com/l/b/2010/01/29/breaking-password-based-encryption-with-azure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WCF Binary Soap Plug-In for Burp</title>
		<link>http://www.gdssecurity.com/l/b/2009/11/19/wcf-binary-soap-plug-in-for-burp/</link>
		<comments>http://www.gdssecurity.com/l/b/2009/11/19/wcf-binary-soap-plug-in-for-burp/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 00:38:55 +0000</pubDate>
		<dc:creator>Brian Holyfield</dc:creator>
				<category><![CDATA[Application Security]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.gdssecurity.com/l/b/?p=206</guid>
		<description><![CDATA[Update 2010:  With the official release of Burp Suite v1.3, both plug-ins discussed in this post can be used with either Pro or Free versions of Burp.
If you run into a Silverlight application that consumes WCF, there’s a good chance it will use Binary XML Message Encoding to send data between the Silverlight client and the [...]]]></description>
			<content:encoded><![CDATA[<p><strong><em>Update 2010:  With the official release of Burp Suite v1.3, both plug-ins discussed in this post can be used with either Pro or Free versions of Burp.</em></strong></p>
<p>If you run into a Silverlight application that consumes WCF, there’s a good chance it will use Binary XML Message Encoding to send data between the Silverlight client and the WCF endpoint. These messages usually include a <code>Content-Type: application/soap+msbin1</code> header to indicate that they are using <a href="http://msdn.microsoft.com/en-us/library/cc219175(PROT.10).aspx">Microsoft’s .NET Binary Format for SOAP (NBFS)</a>. From an attack perspective, the main problem with this encoding format is that you can’t simply edit requests or responses on-the-fly like you would with text-based SOAP messages, since the recipient of the message expects the data to be properly encoded (otherwise it will throw an exception) and, as such, will throw an exception if it’s not.</p>
<p>My initial research into what security tools support NBFS didn’t turn up much. The only option I found were two WCF Binary Inspectors for <a href="http://www.fiddler2.com/fiddler2/">Fiddler</a> (one <a href="http://tfstoys.codeplex.com/">here</a> written by Richard Berg, and another <a href="http://code.msdn.microsoft.com/wcfbinaryinspector">here</a> written by Samuel Jack). Both of these inspectors are essentially plug-ins for Fiddler that add support to view NBFS encoded data. Originally these both looked like the solution I was after, however upon further analysis I realized that while those plug-ins let you VIEW encoded messages, they don’t let you EDIT them. I decided it would be a worthwhile effort to try and leverage the plug-in architecture of <a href="http://portswigger.net/suite/">Burp Suite</a> (through use of the <a href="http://blog.portswigger.net/2009/04/using-burp-extender.html">BurpExtender</a> interface) to write a NBFS plug-in for Burp.</p>
<p><strong>The Solution (sort of)</strong><br />
Not wanting to re-invent the wheel, I figured I would leverage the work that had already been done with Fiddler by calling into one of the existing Fiddler libraries from Burp. I chose to use Richard Berg’s code since it looks like it can be ported entirely to Java down the road if needed (it doesn’t rely on WCF’s built-in decoder). Luckily for me, his code also had all of the methods needed to both encode and decode message data.</p>
<p>The way the plug-in works is pretty simple…when a request comes in, the <code>processProxyMessage</code> method of BurpExtender is used to check whether the requests should be decoded and, if so, passes the request data to the C# library. The C# library decodes the message and returns the plain-text version back to Burp. As requests exit Burp, the <code>processHttpMessage</code> method of BurpExtender is used to determine whether the request needs to be re-encoded and, if so, calls into the C# library again.</p>
<p>There are a couple of interesting points to note here:</p>
<ul>
<li>The <code>processHttpMessage</code> of BurpExtender is currently only supported in the Professional version of Burp Suite. It is my understanding that this method will be supported in the Free version starting with the <a href="http://blog.portswigger.net/2009/11/burp-suite-feature-requests-please.html">next release</a> (v1.3) but for now only licensed users of Burp pro have access to this extender method.</li>
<li>Both the <code>processProxyMessage</code> AND <code>processHttpMessage </code>methods of BurpExtender alway fire BEFORE a response can be edited by the user. Unfortunately this precludes the Plug-in from being able to re-encode RESPONSE messages should the user want to edit one.</li>
</ul>
<p>What this means is that you’ll need to resort to the proxy chaining as a workaround for this if you use the Burp Free Edition (explained in more detail below). Additionally, even if you use Burp Professional Edition, you’ll need to use this workaround if you want to edit RESPONSE data (REQUEST data can be edited on the fly with a single instance of Burp Professional).</p>
<p><strong>Plug-In Versions</strong><br />
There are two version of the Burp plug-in available:</p>
<p><a href="http://www.gdssecurity.com/l/t.php">Burp Professional Edition Plug-in</a>: Allows binary requests to be edited on the fly. This version does not support editing of response data. Pro users can use the Free Edition Plug-in with Burp Professional for editing response data.</p>
<p><a href="http://www.gdssecurity.com/l/t.php">Burp Universal Plug-in</a>: The Universal Plug-in works with both Free and Professional Editions of Burp and supports editing of binary REQUESTS and RESPONSES. The caveat to using this version of the plug-in is that you’ll need to chain two burp instances together as outlined in the diagram below for the plugin to work properly.</p>
<div><img src="/l/burp_chain.gif" alt="" /></div>
<p>The purpose of chaining two proxies together is as follows:</p>
<ul>
<li>The first instance handles decoding requests, intercepting (and editing) requests, and re-encoding edited responses. Set this instance to intercept REQUESTS only (not responses) and to use the 2nd proxy as the next hop.</li>
<li>The second instance handles re-encoding edited requests, decoding responses, and intercepting (and editing) responses. Set this instance to intercept RESPONSES only (not requests).</li>
</ul>
<p>Each proxy will add or remove a custom header (<code>X-WCF-Proxy: must-encode</code>) to edited requests/responses which they use to notify each other of whether re-encoding of a message is necessary. This custom header is removed when read by the plug-in, so it shouldn’t ever get disclosed to the target system.</p>
<p>Albeit it slightly crude, I didn’t see much in the way of a better work around (I am certainly open to suggestions if anyone has any). It should be noted that this workaround is ONLY necessary if you are using the Free Edition (1.2.x) of Burp Suite OR if you want to want to edit WCF binary response content using Burp Professional Edition. Editing WCF binary request data is supported with a single instance of the Burp Professional Plug-In.</p>
<p><strong>Next Steps</strong><br />
These plug-ins were created as a proof of concept for the talk at <a href="http://www.gdssecurity.com/l/b/2009/11/19/slides-from-appsec-dc-posted/">OWASP AppSec DC 2009</a>. Looking forward, the C# decoding library should easily port to pure Java since it doesn’t make use of the native WCF decoding classes. This would not only eliminate cross-language calls but would also make the plug-in platform independent (since the implementation would be in pure Java). The drawback to this approach, of course, is that we would be using a home grown decoder for a proprietary Microsoft protocol that could change down the road.</p>
<p>In any case, hopefully the plug-ins will be useful in the short term until more security tools include native support for NBFS messages. You can find both versions of the plug-in <a href="http://www.gdssecurity.com/l/t.php">available for free on our tools page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gdssecurity.com/l/b/2009/11/19/wcf-binary-soap-plug-in-for-burp/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
