Added JSONInjection, SilentTransactions
Modified The install guide git-svn-id: http://webgoat.googlecode.com/svn/trunk@48 4033779f-a91e-0410-96ef-6bf7bf53c507
This commit is contained in:
parent
af2df52e91
commit
5e061d5bad
@ -0,0 +1,220 @@
|
||||
package org.owasp.webgoat.lessons;
|
||||
|
||||
import org.owasp.webgoat.session.WebSession;
|
||||
|
||||
import org.apache.ecs.Element;
|
||||
import org.apache.ecs.ElementContainer;
|
||||
import org.apache.ecs.StringElement;
|
||||
import org.apache.ecs.html.Div;
|
||||
import org.apache.ecs.html.Form;
|
||||
import org.apache.ecs.html.Table;
|
||||
import org.apache.ecs.html.TR;
|
||||
import org.apache.ecs.html.TD;
|
||||
import org.apache.ecs.html.Input;
|
||||
import org.apache.ecs.html.BR;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class JSONInjection extends LessonAdapter {
|
||||
|
||||
private final static Integer DEFAULT_RANKING = new Integer(30);
|
||||
private final static String TRAVEL_FROM = "travelFrom";
|
||||
private final static String TRAVEL_TO = "travelTo";
|
||||
|
||||
/**
|
||||
* Copyright (c) 2002 Free Software Foundation developed under the
|
||||
* custody of the Open Web Application Security Project
|
||||
* (http://www.owasp.org) This software package is published by OWASP
|
||||
* under the GPL. You should read and accept the LICENSE before you
|
||||
* use, modify and/or redistribute this software.
|
||||
*
|
||||
* @author sherif@macadamian.com
|
||||
* @created December 25, 2006
|
||||
*/
|
||||
|
||||
public void handleRequest(WebSession s) {
|
||||
|
||||
try
|
||||
{
|
||||
if(s.getParser().getRawParameter("from", "").equals("ajax"))
|
||||
{
|
||||
String lineSep = System.getProperty("line.separator");
|
||||
String jsonStr = "{" + lineSep +
|
||||
"\"From\": \"Boston\"," + lineSep +
|
||||
"\"To\": \"Seattle\", " + lineSep +
|
||||
"\"flights\": [" + lineSep +
|
||||
"{\"stops\": \"0\", \"transit\" : \"N/A\", \"price\": \"600$\"}," + lineSep +
|
||||
"{\"stops\": \"2\", \"transit\" : \"Newark,Chicago\", \"price\": \"300$\"} " + lineSep +
|
||||
"]" + lineSep +
|
||||
"}" ;
|
||||
s.getResponse().setContentType("text/html");
|
||||
s.getResponse().setHeader("Cache-Control", "no-cache");
|
||||
PrintWriter out = new PrintWriter(s.getResponse().getOutputStream());
|
||||
out.print(jsonStr);
|
||||
out.flush();
|
||||
out.close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
Form form = new Form( getFormAction(), Form.POST ).setName( "form" ).setEncType( "" );
|
||||
form.setOnSubmit("check();");
|
||||
|
||||
form.addElement( createContent( s ) );
|
||||
|
||||
setContent(form);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of the Method
|
||||
*
|
||||
* @param s Current WebSession
|
||||
*/
|
||||
|
||||
protected Element createContent(WebSession s)
|
||||
{
|
||||
ElementContainer ec = new ElementContainer();
|
||||
String lineSep = System.getProperty("line.separator");
|
||||
String script = "<script>" + lineSep +
|
||||
"function getFlights() {" + lineSep +
|
||||
"var fromField = document.getElementById('" + TRAVEL_FROM + "');" + lineSep +
|
||||
"if (fromField.value.length < 3 ) { return; }" + lineSep +
|
||||
"var toField = document.getElementById('" + TRAVEL_TO + "');" + lineSep +
|
||||
"if (toField.value.length < 3 ) { return; }" + lineSep +
|
||||
"var url = '/WebGoat/attack?Screen=" + String.valueOf(getScreenId()) +
|
||||
"&menu=" + getDefaultCategory().getRanking().toString() +
|
||||
"&from=ajax&" + TRAVEL_FROM + "=' + encodeURIComponent(fromField.value) +" +
|
||||
"'&" + TRAVEL_TO + "=' + encodeURIComponent(toField.value);" + lineSep +
|
||||
"if (typeof XMLHttpRequest != 'undefined') {" + lineSep +
|
||||
"req = new XMLHttpRequest();" + lineSep +
|
||||
"} else if (window.ActiveXObject) {" + lineSep +
|
||||
"req = new ActiveXObject('Microsoft.XMLHTTP');" + lineSep +
|
||||
" }" + lineSep +
|
||||
" req.open('GET', url, true);" + lineSep +
|
||||
" req.onreadystatechange = callback;" + lineSep +
|
||||
" req.send(null);" + lineSep +
|
||||
"}" + lineSep +
|
||||
"function callback() {" + lineSep +
|
||||
" if (req.readyState == 4) { " + lineSep +
|
||||
" if (req.status == 200) { " + lineSep +
|
||||
" var card = eval('(' + req.responseText + ')');" + lineSep +
|
||||
" var flightsDiv = document.getElementById('flightsDiv');" + lineSep +
|
||||
" flightsDiv.innerHTML = '';" + lineSep +
|
||||
" var strHTML='';"+ lineSep +
|
||||
" strHTML = '<tr><td> </td><td>No of Stops</td>';" + lineSep +
|
||||
" strHTML = strHTML + '<td>Stops</td><td>Prices</td></tr>';" + lineSep +
|
||||
" for(var i=0; i<card.flights.length; i++){" + lineSep +
|
||||
" var node = card.flights[i];" + lineSep +
|
||||
" strHTML = strHTML + '<tr><td><input name=\"radio' + i +'\" type=\"radio\"></td><td>';" + lineSep +
|
||||
" strHTML = strHTML + card.flights[i].stops + '</td><td>';" + lineSep +
|
||||
" strHTML = strHTML + card.flights[i].transit + '</td><td>';" + lineSep +
|
||||
" strHTML = strHTML + '<div name=\"priceID'+i+'\" id=\"priceID'+i+'\">' + card.flights[i].price + '</div></td></tr>';" + lineSep +
|
||||
" }" + lineSep +
|
||||
" strHTML = '<table border=\"1\">' + strHTML + '</table>';" + lineSep +
|
||||
" flightsDiv.innerHTML = strHTML;"+ lineSep +
|
||||
" }}}" + lineSep +
|
||||
|
||||
"function check(){" + lineSep +
|
||||
" if ( document.getElementById('radio0').checked )" + lineSep +
|
||||
" { document.getElementById('price2Submit').value = document.getElementById('priceID0').innerText; }" + lineSep +
|
||||
" else if ( document.getElementById('radio1').checked )" + lineSep +
|
||||
" { document.getElementById('price2Submit').value = document.getElementById('priceID1').innerText; }" + lineSep +
|
||||
" else " + lineSep +
|
||||
" { alert('Please choose one flight'); }" + lineSep +
|
||||
"}" + lineSep +
|
||||
"</script>" + lineSep;
|
||||
ec.addElement( new StringElement(script));
|
||||
Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0).setWidth("90%").setAlign("center");
|
||||
|
||||
TR tr = new TR();
|
||||
|
||||
tr.addElement( new TD("From: "));
|
||||
Input in = new Input( Input.TEXT , TRAVEL_FROM ,"" );
|
||||
in.addAttribute("onkeyup", "getFlights();");
|
||||
tr.addElement( new TD(in) );
|
||||
|
||||
t1.addElement( tr );
|
||||
|
||||
tr = new TR();
|
||||
tr.addElement( new TD("To: "));
|
||||
in = new Input( Input.TEXT , TRAVEL_TO ,"" );
|
||||
in.addAttribute("onkeyup", "getFlights();");
|
||||
tr.addElement( new TD(in) );
|
||||
|
||||
t1.addElement( tr );
|
||||
ec.addElement(t1);
|
||||
|
||||
ec.addElement(new BR());
|
||||
ec.addElement(new BR());
|
||||
Div div = new Div();
|
||||
div.addAttribute("name", "flightsDiv");
|
||||
div.addAttribute("id", "flightsDiv");
|
||||
ec.addElement(div);
|
||||
|
||||
Input b = new Input();
|
||||
b.setType( Input.SUBMIT );
|
||||
b.setValue( "Submit" );
|
||||
b.setName("SUBMIT");
|
||||
ec.addElement(b);
|
||||
|
||||
Input price2Submit = new Input();
|
||||
price2Submit.setType( Input.HIDDEN);
|
||||
price2Submit.setName("price2Submit");
|
||||
ec.addElement( price2Submit );
|
||||
if (s.getParser().getRawParameter("radio0" , "").equals("on"))
|
||||
{
|
||||
String price = s.getParser().getRawParameter("price2Submit" , "");
|
||||
price = price.replace("$", "");
|
||||
|
||||
if (Integer.parseInt(price) < 600)
|
||||
{
|
||||
makeSuccess(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
s.setMessage("You are close, try to set the price for the non-stop flight to be less than 600$");
|
||||
}
|
||||
}
|
||||
return ec;
|
||||
}
|
||||
|
||||
protected Category getDefaultCategory()
|
||||
{
|
||||
return AbstractLesson.AJAX_SECURITY;
|
||||
}
|
||||
|
||||
protected List getHints()
|
||||
{
|
||||
List<String> hints = new ArrayList<String>();
|
||||
hints.add( "JSON stands for JavaScript Object Notation." );
|
||||
hints.add( "JSON is a way of representing data just like XML." );
|
||||
hints.add( "The JSON payload is easily interceptable." );
|
||||
hints.add( "Intercept the reply, change the 600$ to 25$." );
|
||||
return hints;
|
||||
|
||||
}
|
||||
|
||||
protected Integer getDefaultRanking()
|
||||
{
|
||||
return DEFAULT_RANKING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the title attribute of the HelloScreen object
|
||||
*
|
||||
* @return The title value
|
||||
*/
|
||||
public String getTitle()
|
||||
{
|
||||
return ( "JSON Injection" );
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,221 @@
|
||||
package org.owasp.webgoat.lessons;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ecs.Element;
|
||||
import org.apache.ecs.ElementContainer;
|
||||
import org.apache.ecs.StringElement;
|
||||
import org.apache.ecs.html.BR;
|
||||
import org.apache.ecs.html.Div;
|
||||
import org.apache.ecs.html.Form;
|
||||
import org.apache.ecs.html.H1;
|
||||
import org.apache.ecs.html.H3;
|
||||
import org.apache.ecs.html.Input;
|
||||
import org.apache.ecs.html.PRE;
|
||||
import org.apache.ecs.html.TD;
|
||||
import org.apache.ecs.html.TR;
|
||||
import org.apache.ecs.html.Table;
|
||||
import org.owasp.webgoat.session.WebSession;
|
||||
|
||||
public class SilentTransactions extends LessonAdapter {
|
||||
private final static Integer DEFAULT_RANKING = new Integer(40);
|
||||
|
||||
/**
|
||||
* Copyright (c) 2002 Free Software Foundation developed under the
|
||||
* custody of the Open Web Application Security Project
|
||||
* (http://www.owasp.org) This software package is published by OWASP
|
||||
* under the GPL. You should read and accept the LICENSE before you
|
||||
* use, modify and/or redistribute this software.
|
||||
*
|
||||
* @author sherif@macadamian.com
|
||||
* @created December 26, 2006
|
||||
*/
|
||||
|
||||
public void handleRequest(WebSession s) {
|
||||
|
||||
try
|
||||
{
|
||||
if(s.getParser().getRawParameter("from", "").equals("ajax"))
|
||||
{
|
||||
if (s.getParser().getRawParameter( "confirm", "").equals("Confirm"))
|
||||
{
|
||||
s.getResponse().setContentType("text/html");
|
||||
s.getResponse().setHeader("Cache-Control", "no-cache");
|
||||
PrintWriter out = new PrintWriter(s.getResponse().getOutputStream());
|
||||
out.print("<br><br>* Congratulations. You have successfully completed this lesson.");
|
||||
out.flush();
|
||||
out.close();
|
||||
return;
|
||||
}
|
||||
else if (s.getParser().getRawParameter( "confirm", "").equals("Transferring"))
|
||||
{
|
||||
s.getResponse().setContentType("text/html");
|
||||
s.getResponse().setHeader("Cache-Control", "no-cache");
|
||||
PrintWriter out = new PrintWriter(s.getResponse().getOutputStream());
|
||||
out.print("<br><br>The transaction had been completed successfully.");
|
||||
out.flush();
|
||||
out.close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
Form form = new Form( getFormAction(), Form.POST ).setName( "form" ).setEncType( "" );
|
||||
|
||||
form.addElement( createContent( s ) );
|
||||
|
||||
setContent(form);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of the Method
|
||||
*
|
||||
* @param s Current WebSession
|
||||
*/
|
||||
|
||||
protected Element createContent(WebSession s)
|
||||
{
|
||||
ElementContainer ec = new ElementContainer();
|
||||
String lineSep = System.getProperty("line.separator");
|
||||
String script = "<script>" + lineSep +
|
||||
"function processData(){" + lineSep +
|
||||
" var accountNo = document.getElementById('newAccount').value;" + lineSep +
|
||||
" var amount = document.getElementById('amount').value;" + lineSep +
|
||||
" if ( accountNo == ''){" + lineSep +
|
||||
" alert('Please enter a valid account number to transfer to.')" + lineSep +
|
||||
" return;" + lineSep +
|
||||
"}" + lineSep +
|
||||
" else if ( amount == ''){" + lineSep +
|
||||
" alert('Please enter a valid amount to transfer.')" + lineSep +
|
||||
" return;" + lineSep +
|
||||
"}" + lineSep +
|
||||
" document.getElementById('confirm').value = 'Transferring'" + lineSep +
|
||||
"submitData(accountNo, amount);" + lineSep +
|
||||
" document.getElementById('confirm').value = 'Confirm'" + lineSep +
|
||||
"}" + lineSep +
|
||||
"function submitData(accountNo, balance) {" + lineSep +
|
||||
"var url = '/WebGoat/attack?Screen=" + String.valueOf(getScreenId()) +
|
||||
"&menu=" + getDefaultCategory().getRanking().toString() +
|
||||
"&from=ajax&newAccount='+ accountNo+ '&amount=' + balance +'&confirm=' + document.getElementById('confirm').value; " + lineSep +
|
||||
"if (typeof XMLHttpRequest != 'undefined') {" + lineSep +
|
||||
"req = new XMLHttpRequest();" + lineSep +
|
||||
"} else if (window.ActiveXObject) {" + lineSep +
|
||||
"req = new ActiveXObject('Microsoft.XMLHTTP');" + lineSep +
|
||||
" }" + lineSep +
|
||||
" req.open('GET', url, true);" + lineSep +
|
||||
" req.onreadystatechange = callback;" + lineSep +
|
||||
" req.send(null);" + lineSep +
|
||||
"}" + lineSep +
|
||||
"function callback() {" + lineSep +
|
||||
" if (req.readyState == 4) { " + lineSep +
|
||||
" if (req.status == 200) { " + lineSep +
|
||||
" var result = req.responseText ;" + lineSep +
|
||||
" var resultsDiv = document.getElementById('resultsDiv');" + lineSep +
|
||||
" resultsDiv.innerHTML = '';" + lineSep +
|
||||
" resultsDiv.innerHTML = result;" + lineSep +
|
||||
" }}}" + lineSep +
|
||||
"</script>" + lineSep;
|
||||
|
||||
ec.addElement( new StringElement(script) );
|
||||
ec.addElement( new H1("Welcome to WebGoat Banking System"));
|
||||
ec.addElement( new BR() );
|
||||
ec.addElement( new H3("Account Summary:"));
|
||||
|
||||
Table t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(1).setWidth("70%").setAlign("left");
|
||||
ec.addElement( new BR() );
|
||||
TR tr = new TR();
|
||||
tr.addElement( new TD( new StringElement( "Account Number" ) ));
|
||||
tr.addElement( new TD( new StringElement( "Account Balance" ) ));
|
||||
t1.addElement( tr );
|
||||
|
||||
tr = new TR();
|
||||
tr.addElement( new TD( new StringElement( "007-872108-023" )));
|
||||
tr.addElement( new TD( new StringElement( "11983" )));
|
||||
t1.addElement( tr );
|
||||
|
||||
ec.addElement( t1 );
|
||||
ec.addElement( new BR() );
|
||||
ec.addElement( new BR() );
|
||||
|
||||
ec.addElement( new H3("<br><br>Transfer Information:<br>"));
|
||||
ec.addElement( new BR() );
|
||||
|
||||
t1 = new Table().setCellSpacing(0).setCellPadding(0).setBorder(1).setWidth("70%").setAlign("left");
|
||||
|
||||
tr = new TR();
|
||||
tr.addElement( new TD( new StringElement( "Transfer to Account:" ) ));
|
||||
Input newAccount = new Input();
|
||||
newAccount.setType( Input.TEXT );
|
||||
newAccount.setName( "newAccount" );
|
||||
newAccount.setValue( "" );
|
||||
tr.addElement( new TD( newAccount ));
|
||||
t1.addElement( tr );
|
||||
|
||||
tr = new TR();
|
||||
tr.addElement( new TD( new StringElement( "Transfer Amount:" )));
|
||||
Input amount = new Input();
|
||||
amount.setType( Input.TEXT );
|
||||
amount.setName( "amount" );
|
||||
amount.setValue( 0 );
|
||||
tr.addElement( new TD( amount ));
|
||||
t1.addElement( tr );
|
||||
|
||||
ec.addElement( t1 );
|
||||
|
||||
ec.addElement( new PRE() );
|
||||
Input b = new Input();
|
||||
b.setType( Input.BUTTON );
|
||||
b.setName( "confirm" );
|
||||
b.setValue( "Confirm" );
|
||||
b.setOnClick( "processData();" );
|
||||
ec.addElement( b );
|
||||
|
||||
ec.addElement( new BR());
|
||||
Div div = new Div();
|
||||
div.addAttribute("name", "resultsDiv");
|
||||
div.addAttribute("id", "resultsDiv");
|
||||
div.setStyle("font-weight: bold;color:red;");
|
||||
ec.addElement(div);
|
||||
|
||||
return ec;
|
||||
}
|
||||
|
||||
protected Category getDefaultCategory()
|
||||
{
|
||||
return AbstractLesson.AJAX_SECURITY;
|
||||
}
|
||||
|
||||
protected List getHints()
|
||||
{
|
||||
List<String> hints = new ArrayList<String>();
|
||||
hints.add("Check the javascript in the HTML source.");
|
||||
hints.add("Check how the application calls a specific javascript function to execute the transaction.");
|
||||
hints.add("Try to navigate to 'javascript:submitData(1234556,11000);'");
|
||||
return hints;
|
||||
|
||||
}
|
||||
|
||||
protected Integer getDefaultRanking()
|
||||
{
|
||||
return DEFAULT_RANKING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the title attribute of the HelloScreen object
|
||||
*
|
||||
* @return The title value
|
||||
*/
|
||||
public String getTitle()
|
||||
{
|
||||
return ( "Silent Transactions Attacks" );
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -10,13 +10,13 @@ How to perform DOM injection attacks.
|
||||
<b>How the attacks works:</b>
|
||||
</p>
|
||||
Some applications specially the ones that uses AJAX manipulates and updates the DOM
|
||||
directly using javascript, DHTML and eval.<br>
|
||||
directly using javascript, DHTML and eval() method.<br>
|
||||
An attacker may take advantage of that by intercepting the reply and try to inject some
|
||||
javascript commands to exploit his attacks.
|
||||
</div>
|
||||
<p><b>General Goal(s):</b> </p>
|
||||
<!-- Start Instructions -->
|
||||
* Your victim is a system that takes an activatation key to allow you to use it.
|
||||
* Your victim is a system that takes an activatation key to allow you to use it.<br>
|
||||
* Your goal should be to try to get to enable the activate button.<br>
|
||||
* Take some time to see the HTML source in order to understand how does it work.<br>
|
||||
* Take some time to see the HTML source in order to understand how the key validation process works.<br>
|
||||
<!-- Stop Instructions -->
|
||||
|
@ -0,0 +1,23 @@
|
||||
<div align="Center">
|
||||
<p><b>Lesson Plan Title:</b> How to Perform JSON Injection </p>
|
||||
</div>
|
||||
|
||||
<p><b>Concept / Topic To Teach:</b> </p>
|
||||
This lesson teaches how to perform JSON Injection Attacks.
|
||||
<br>
|
||||
<div align="Left">
|
||||
<p>
|
||||
<b>How the attacks works:</b>
|
||||
</p>
|
||||
JavaScript Object Notation (JSON) is a simple and effective lightweight data exchange format. JSON can be in a lot of forms such as arrays, lists, hashtables and other data structures.
|
||||
JSON is widely used in AJAX and Web2.0 application and is favored by programmers over XML because of its ease of use and speed.
|
||||
However, JSON, like XML is prone to Injection attacks. A malacious attackers can inject the reply from the server and inject some aribtrary values in there.
|
||||
|
||||
</div>
|
||||
<p><b>General Goal(s):</b> </p>
|
||||
<!-- Start Instructions -->
|
||||
* You are travelling from Boston, MA- Airport code BOS to Seattle, WA - Airport code SEA.<br>
|
||||
* Once you enter the three digits code of the airport, an AJAX request will be executed asking for the tickets price.<br>
|
||||
* You will notice that there are two flights available, an expensive one with no stops and another cheaper one with 2 stops.<br>
|
||||
* Your goal is to try to get the one with no stops but for a cheaper price.
|
||||
<!-- Stop Instructions -->
|
@ -0,0 +1,24 @@
|
||||
<div align="Center">
|
||||
<p><b>Lesson Plan Title:</b> How to Perform Silent Transactions Attacks. </p>
|
||||
</div>
|
||||
|
||||
<p><b>Concept / Topic To Teach:</b> </p>
|
||||
This lesson teaches how to perform silent transactions attacks.
|
||||
<br>
|
||||
<div align="Left">
|
||||
<p>
|
||||
<b>How the attacks works:</b>
|
||||
</p>
|
||||
Any system that silently processes transactions using a single submission is dangerous to the client.
|
||||
For example, if a normal web application allows a simple URL submission, a preset session attack will
|
||||
allow the attacker to complete a transaction without the user’s authorization.
|
||||
In Ajax, it gets worse: the transaction is silent; it happens with no user feedback on the page,
|
||||
so an injected attack script may be able to steal money from the client without authorization.
|
||||
</div>
|
||||
<p><b>General Goal(s):</b> </p>
|
||||
<!-- Start Instructions -->
|
||||
* This is a sample internet banking application - money transfers page.<br>
|
||||
* It shows below your balance, the account you are transferring to and amount you will transfer.<br>
|
||||
* The application uses AJAX to submit the transaction after doing some basic client side validations.<br>
|
||||
* Your goal is to try to bypass the user's authorization and silently execute the transaction<br>
|
||||
<!-- Stop Instructions -->
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user