First wave is complete; some rendering issues
This commit is contained in:
parent
24b2e79dc5
commit
29447a11b4
@ -44,9 +44,10 @@ public abstract class Assignment extends Endpoint {
|
||||
@Autowired
|
||||
private UserTracker userTracker;
|
||||
@Autowired
|
||||
private WebSession webSession;
|
||||
private WebSession webSession;
|
||||
|
||||
//// TODO: 11/13/2016 events better fit?
|
||||
|
||||
//// TODO: 11/13/2016 events better fit?
|
||||
protected AttackResult trackProgress(AttackResult attackResult) {
|
||||
if (attackResult.assignmentSolved()) {
|
||||
userTracker.assignmentSolved(webSession.getCurrentLesson(), this);
|
||||
@ -55,5 +56,10 @@ public abstract class Assignment extends Endpoint {
|
||||
}
|
||||
return attackResult;
|
||||
}
|
||||
|
||||
protected WebSession getWebSession() {
|
||||
return webSession;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -44,8 +44,6 @@ public class DatabaseUtilities
|
||||
|
||||
private static Map<String, Connection> connections = new HashMap<String, Connection>();
|
||||
private static Map<String, Boolean> dbBuilt = new HashMap<String, Boolean>();
|
||||
@Autowired
|
||||
private static WebSession webSession;
|
||||
|
||||
/**
|
||||
* <p>getConnection.</p>
|
||||
@ -54,9 +52,9 @@ public class DatabaseUtilities
|
||||
* @return a {@link java.sql.Connection} object.
|
||||
* @throws java.sql.SQLException if any.
|
||||
*/
|
||||
public static Connection getConnection() throws SQLException
|
||||
public static Connection getConnection(WebSession s) throws SQLException
|
||||
{
|
||||
return getConnection(webSession.getUserName(), webSession.getWebgoatContext());
|
||||
return getConnection(s.getUserName(), s.getWebgoatContext());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -62,8 +62,8 @@ public class WebSession {
|
||||
* @return a {@link java.sql.Connection} object.
|
||||
* @throws java.sql.SQLException if any.
|
||||
*/
|
||||
public static synchronized Connection getConnection() throws SQLException {
|
||||
return DatabaseUtilities.getConnection();
|
||||
public static synchronized Connection getConnection(WebSession s) throws SQLException {
|
||||
return DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,9 +53,8 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||
public class SqlInjectionLesson5a extends Assignment {
|
||||
|
||||
@RequestMapping(method = RequestMethod.POST)
|
||||
public @ResponseBody AttackResult completed(@RequestParam String answer, HttpServletRequest request) throws IOException {
|
||||
System.out.println("answer:" + answer);
|
||||
return injectableQuery(answer);
|
||||
public @ResponseBody AttackResult completed(@RequestParam String account, HttpServletRequest request) throws IOException {
|
||||
return injectableQuery(account);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -64,12 +63,11 @@ System.out.println("answer:" + answer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected AttackResult injectableQuery(String accountName)
|
||||
{
|
||||
try
|
||||
{
|
||||
Connection connection = DatabaseUtilities.getConnection();
|
||||
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
||||
String query = "SELECT * FROM user_data WHERE last_name = '" + accountName + "'";
|
||||
|
||||
try
|
||||
@ -91,7 +89,7 @@ System.out.println("answer:" + answer);
|
||||
{
|
||||
return trackProgress(AttackResult.success("You have succeed: " + output.toString()));
|
||||
} else {
|
||||
return trackProgress(AttackResult.failed("You are close, try again. "));
|
||||
return trackProgress(AttackResult.failed("You are close, try again. " + output.toString()));
|
||||
}
|
||||
|
||||
}
|
||||
@ -99,15 +97,16 @@ System.out.println("answer:" + answer);
|
||||
{
|
||||
return trackProgress(AttackResult.failed("No Results Matched. Try Again. "));
|
||||
|
||||
// output.append(getLabelManager().get("NoResultsMatched"));
|
||||
}
|
||||
} catch (SQLException sqle)
|
||||
{
|
||||
|
||||
return trackProgress(AttackResult.failed(sqle.getMessage()));
|
||||
}
|
||||
} catch (Exception e)
|
||||
{
|
||||
return trackProgress(AttackResult.failed( "ErrorGenerating" + this.getClass().getName()));
|
||||
e.printStackTrace();
|
||||
return trackProgress(AttackResult.failed( "ErrorGenerating" + this.getClass().getName() + " : " + e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,6 +116,7 @@ System.out.println("answer:" + answer);
|
||||
int numColumns = resultsMetaData.getColumnCount();
|
||||
results.beforeFirst();
|
||||
StringBuffer t = new StringBuffer();
|
||||
t.append("<p>");
|
||||
|
||||
if (results.next())
|
||||
{
|
||||
@ -126,7 +126,7 @@ System.out.println("answer:" + answer);
|
||||
t.append(", ");
|
||||
}
|
||||
|
||||
t.append(System.getProperty("line.separator"));
|
||||
t.append("<br />");
|
||||
results.beforeFirst();
|
||||
|
||||
while (results.next())
|
||||
@ -138,15 +138,17 @@ System.out.println("answer:" + answer);
|
||||
t.append(", ");
|
||||
}
|
||||
|
||||
t.append(System.getProperty("line.separator"));
|
||||
t.append("<br />");
|
||||
}
|
||||
|
||||
return (t.toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
return ("Query Successful; however no data was returned from this query.");
|
||||
t.append ("Query Successful; however no data was returned from this query.");
|
||||
}
|
||||
|
||||
t.append("</p>");
|
||||
return (t.toString());
|
||||
}
|
||||
//
|
||||
// protected Element parameterizedQuery(WebSession s)
|
||||
|
@ -0,0 +1,234 @@
|
||||
package org.owasp.webgoat.plugin;
|
||||
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.owasp.webgoat.lessons.Assignment;
|
||||
import org.owasp.webgoat.lessons.model.AttackResult;
|
||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
*
|
||||
*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
* please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 20014 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 https://github.com/WebGoat/WebGoat, a repository for free software
|
||||
* projects.
|
||||
*
|
||||
* For details, please see http://webgoat.github.io
|
||||
*
|
||||
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
|
||||
* @created October 28, 2003
|
||||
*/
|
||||
public class SqlInjectionLesson5b extends Assignment {
|
||||
|
||||
@RequestMapping(method = RequestMethod.POST)
|
||||
public @ResponseBody AttackResult completed(@RequestParam String userid, HttpServletRequest request) throws IOException {
|
||||
return injectableQuery(userid);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return "/SqlInjection/attack5b";
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected AttackResult injectableQuery(String accountName)
|
||||
{
|
||||
try
|
||||
{
|
||||
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
||||
String query = "SELECT * FROM user_data WHERE userid = " + accountName;
|
||||
|
||||
try
|
||||
{
|
||||
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY);
|
||||
ResultSet results = statement.executeQuery(query);
|
||||
|
||||
if ((results != null) && (results.first() == true))
|
||||
{
|
||||
ResultSetMetaData resultsMetaData = results.getMetaData();
|
||||
StringBuffer output = new StringBuffer();
|
||||
|
||||
output.append(writeTable(results, resultsMetaData));
|
||||
results.last();
|
||||
|
||||
// If they get back more than one user they succeeded
|
||||
if (results.getRow() >= 6)
|
||||
{
|
||||
return trackProgress(AttackResult.success("You have succeed: " + output.toString()));
|
||||
} else {
|
||||
return trackProgress(AttackResult.failed("You are close, try again. " + output.toString()));
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return trackProgress(AttackResult.failed("No Results Matched. Try Again. "));
|
||||
|
||||
// output.append(getLabelManager().get("NoResultsMatched"));
|
||||
}
|
||||
} catch (SQLException sqle)
|
||||
{
|
||||
|
||||
return trackProgress(AttackResult.failed(sqle.getMessage()));
|
||||
}
|
||||
} catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return trackProgress(AttackResult.failed( "ErrorGenerating" + this.getClass().getName() + " : " + e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
public String writeTable(ResultSet results, ResultSetMetaData resultsMetaData) throws IOException,
|
||||
SQLException
|
||||
{
|
||||
int numColumns = resultsMetaData.getColumnCount();
|
||||
results.beforeFirst();
|
||||
StringBuffer t = new StringBuffer();
|
||||
t.append("<p>");
|
||||
|
||||
if (results.next())
|
||||
{
|
||||
for (int i = 1; i < (numColumns + 1); i++)
|
||||
{
|
||||
t.append(resultsMetaData.getColumnName(i));
|
||||
t.append(", ");
|
||||
}
|
||||
|
||||
t.append("<br />");
|
||||
results.beforeFirst();
|
||||
|
||||
while (results.next())
|
||||
{
|
||||
|
||||
for (int i = 1; i < (numColumns + 1); i++)
|
||||
{
|
||||
t.append(results.getString(i));
|
||||
t.append(", ");
|
||||
}
|
||||
|
||||
t.append("<br />");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
t.append ("Query Successful; however no data was returned from this query.");
|
||||
}
|
||||
|
||||
t.append("</p>");
|
||||
return (t.toString());
|
||||
}
|
||||
//
|
||||
// protected Element parameterizedQuery(WebSession s)
|
||||
// {
|
||||
// ElementContainer ec = new ElementContainer();
|
||||
//
|
||||
// ec.addElement(getLabelManager().get("StringSqlInjectionSecondStage"));
|
||||
// if (s.getParser().getRawParameter(ACCT_NAME, "YOUR_NAME").equals("restart"))
|
||||
// {
|
||||
// getLessonTracker(s).getLessonProperties().setProperty(STAGE, "1");
|
||||
// return (injectableQuery(s));
|
||||
// }
|
||||
//
|
||||
// ec.addElement(new BR());
|
||||
//
|
||||
// try
|
||||
// {
|
||||
// Connection connection = DatabaseUtilities.getConnection(s);
|
||||
//
|
||||
// ec.addElement(makeAccountLine(s));
|
||||
//
|
||||
// String query = "SELECT * FROM user_data WHERE last_name = ?";
|
||||
// ec.addElement(new PRE(query));
|
||||
//
|
||||
// try
|
||||
// {
|
||||
// PreparedStatement statement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
// ResultSet.CONCUR_READ_ONLY);
|
||||
// statement.setString(1, accountName);
|
||||
// ResultSet results = statement.executeQuery();
|
||||
//
|
||||
// if ((results != null) && (results.first() == true))
|
||||
// {
|
||||
// ResultSetMetaData resultsMetaData = results.getMetaData();
|
||||
// ec.addElement(DatabaseUtilities.writeTable(results, resultsMetaData));
|
||||
// results.last();
|
||||
//
|
||||
// // If they get back more than one user they succeeded
|
||||
// if (results.getRow() >= 6)
|
||||
// {
|
||||
// makeSuccess(s);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// ec.addElement(getLabelManager().get("NoResultsMatched"));
|
||||
// }
|
||||
// } catch (SQLException sqle)
|
||||
// {
|
||||
// ec.addElement(new P().addElement(sqle.getMessage()));
|
||||
// }
|
||||
// } catch (Exception e)
|
||||
// {
|
||||
// s.setMessage(getLabelManager().get("ErrorGenerating") + this.getClass().getName());
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// return (ec);
|
||||
// }
|
||||
//
|
||||
// protected Element makeAccountLine(WebSession s)
|
||||
// {
|
||||
// ElementContainer ec = new ElementContainer();
|
||||
// ec.addElement(new P().addElement(getLabelManager().get("EnterLastName")));
|
||||
//
|
||||
// accountName = s.getParser().getRawParameter(ACCT_NAME, "Your Name");
|
||||
// Input input = new Input(Input.TEXT, ACCT_NAME, accountName.toString());
|
||||
// ec.addElement(input);
|
||||
//
|
||||
// Element b = ECSFactory.makeButton(getLabelManager().get("Go!"));
|
||||
// ec.addElement(b);
|
||||
//
|
||||
// return ec;
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,232 @@
|
||||
|
||||
package org.owasp.webgoat.plugin;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.owasp.webgoat.lessons.Assignment;
|
||||
import org.owasp.webgoat.lessons.model.AttackResult;
|
||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
*
|
||||
*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
* please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 20014 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 https://github.com/WebGoat/WebGoat, a repository for free software
|
||||
* projects.
|
||||
*
|
||||
* For details, please see http://webgoat.github.io
|
||||
*
|
||||
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
|
||||
* @created October 28, 2003
|
||||
*/
|
||||
public class SqlInjectionLesson6a extends Assignment {
|
||||
|
||||
@RequestMapping(method = RequestMethod.POST)
|
||||
public @ResponseBody AttackResult completed(@RequestParam String userid_6a, HttpServletRequest request) throws IOException {
|
||||
return injectableQuery(userid_6a);
|
||||
// The answer: Smith' union select userid,user_name, password,cookie,cookie, cookie,userid from user_system_data --
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return "/SqlInjection/attack6a";
|
||||
}
|
||||
|
||||
|
||||
protected AttackResult injectableQuery(String accountName)
|
||||
{
|
||||
try
|
||||
{
|
||||
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
||||
String query = "SELECT * FROM user_data WHERE last_name = '" + accountName + "'";
|
||||
|
||||
try
|
||||
{
|
||||
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY);
|
||||
ResultSet results = statement.executeQuery(query);
|
||||
|
||||
if ((results != null) && (results.first() == true))
|
||||
{
|
||||
ResultSetMetaData resultsMetaData = results.getMetaData();
|
||||
StringBuffer output = new StringBuffer();
|
||||
|
||||
output.append(writeTable(results, resultsMetaData));
|
||||
results.last();
|
||||
|
||||
// If they get back more than one user they succeeded
|
||||
if (results.getRow() >= 6)
|
||||
{
|
||||
return trackProgress(AttackResult.success("You have succeed: " + output.toString()));
|
||||
} else {
|
||||
return trackProgress(AttackResult.failed("You are close, try again. " + output.toString()));
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return trackProgress(AttackResult.failed("No Results Matched. Try Again. "));
|
||||
|
||||
}
|
||||
} catch (SQLException sqle)
|
||||
{
|
||||
|
||||
return trackProgress(AttackResult.failed(sqle.getMessage()));
|
||||
}
|
||||
} catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return trackProgress(AttackResult.failed( "ErrorGenerating" + this.getClass().getName() + " : " + e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
public String writeTable(ResultSet results, ResultSetMetaData resultsMetaData) throws IOException,
|
||||
SQLException
|
||||
{
|
||||
int numColumns = resultsMetaData.getColumnCount();
|
||||
results.beforeFirst();
|
||||
StringBuffer t = new StringBuffer();
|
||||
t.append("<p>");
|
||||
|
||||
if (results.next())
|
||||
{
|
||||
for (int i = 1; i < (numColumns + 1); i++)
|
||||
{
|
||||
t.append(resultsMetaData.getColumnName(i));
|
||||
t.append(", ");
|
||||
}
|
||||
|
||||
t.append("<br />");
|
||||
results.beforeFirst();
|
||||
|
||||
while (results.next())
|
||||
{
|
||||
|
||||
for (int i = 1; i < (numColumns + 1); i++)
|
||||
{
|
||||
t.append(results.getString(i));
|
||||
t.append(", ");
|
||||
}
|
||||
|
||||
t.append("<br />");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
t.append ("Query Successful; however no data was returned from this query.");
|
||||
}
|
||||
|
||||
t.append("</p>");
|
||||
return (t.toString());
|
||||
}
|
||||
//
|
||||
// protected Element parameterizedQuery(WebSession s)
|
||||
// {
|
||||
// ElementContainer ec = new ElementContainer();
|
||||
//
|
||||
// ec.addElement(getLabelManager().get("StringSqlInjectionSecondStage"));
|
||||
// if (s.getParser().getRawParameter(ACCT_NAME, "YOUR_NAME").equals("restart"))
|
||||
// {
|
||||
// getLessonTracker(s).getLessonProperties().setProperty(STAGE, "1");
|
||||
// return (injectableQuery(s));
|
||||
// }
|
||||
//
|
||||
// ec.addElement(new BR());
|
||||
//
|
||||
// try
|
||||
// {
|
||||
// Connection connection = DatabaseUtilities.getConnection(s);
|
||||
//
|
||||
// ec.addElement(makeAccountLine(s));
|
||||
//
|
||||
// String query = "SELECT * FROM user_data WHERE last_name = ?";
|
||||
// ec.addElement(new PRE(query));
|
||||
//
|
||||
// try
|
||||
// {
|
||||
// PreparedStatement statement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
// ResultSet.CONCUR_READ_ONLY);
|
||||
// statement.setString(1, accountName);
|
||||
// ResultSet results = statement.executeQuery();
|
||||
//
|
||||
// if ((results != null) && (results.first() == true))
|
||||
// {
|
||||
// ResultSetMetaData resultsMetaData = results.getMetaData();
|
||||
// ec.addElement(DatabaseUtilities.writeTable(results, resultsMetaData));
|
||||
// results.last();
|
||||
//
|
||||
// // If they get back more than one user they succeeded
|
||||
// if (results.getRow() >= 6)
|
||||
// {
|
||||
// makeSuccess(s);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// ec.addElement(getLabelManager().get("NoResultsMatched"));
|
||||
// }
|
||||
// } catch (SQLException sqle)
|
||||
// {
|
||||
// ec.addElement(new P().addElement(sqle.getMessage()));
|
||||
// }
|
||||
// } catch (Exception e)
|
||||
// {
|
||||
// s.setMessage(getLabelManager().get("ErrorGenerating") + this.getClass().getName());
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// return (ec);
|
||||
// }
|
||||
//
|
||||
// protected Element makeAccountLine(WebSession s)
|
||||
// {
|
||||
// ElementContainer ec = new ElementContainer();
|
||||
// ec.addElement(new P().addElement(getLabelManager().get("EnterLastName")));
|
||||
//
|
||||
// accountName = s.getParser().getRawParameter(ACCT_NAME, "Your Name");
|
||||
// Input input = new Input(Input.TEXT, ACCT_NAME, accountName.toString());
|
||||
// ec.addElement(input);
|
||||
//
|
||||
// Element b = ECSFactory.makeButton(getLabelManager().get("Go!"));
|
||||
// ec.addElement(b);
|
||||
//
|
||||
// return ec;
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
|
||||
package org.owasp.webgoat.plugin;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.owasp.webgoat.lessons.Assignment;
|
||||
import org.owasp.webgoat.lessons.model.AttackResult;
|
||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
*
|
||||
*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
* please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 20014 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 https://github.com/WebGoat/WebGoat, a repository for free software
|
||||
* projects.
|
||||
*
|
||||
* For details, please see http://webgoat.github.io
|
||||
*
|
||||
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
|
||||
* @created October 28, 2003
|
||||
*/
|
||||
public class SqlInjectionLesson6b extends Assignment {
|
||||
|
||||
@RequestMapping(method = RequestMethod.POST)
|
||||
public @ResponseBody AttackResult completed(@RequestParam String userid_6b, HttpServletRequest request) throws IOException {
|
||||
if (!userid_6b.toString().equals(getPassword())) {
|
||||
return trackProgress(AttackResult.success());
|
||||
} else {
|
||||
return trackProgress(AttackResult.failed("You are close, try again"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return "/SqlInjection/attack6b";
|
||||
}
|
||||
|
||||
|
||||
protected String getPassword()
|
||||
{
|
||||
|
||||
String password="dave";
|
||||
try
|
||||
{
|
||||
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
||||
String query = "SELECT password FROM user_system_data WHERE user_name = 'dave'";
|
||||
|
||||
try
|
||||
{
|
||||
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY);
|
||||
ResultSet results = statement.executeQuery(query);
|
||||
|
||||
if ((results != null) && (results.first() == true))
|
||||
{
|
||||
password = results.getNString("password");
|
||||
}
|
||||
} catch (SQLException sqle)
|
||||
{
|
||||
sqle.printStackTrace();
|
||||
// do nothing
|
||||
}
|
||||
} catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
// do nothing
|
||||
}
|
||||
System.out.println("Password: " + password);
|
||||
return (password);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -57,8 +57,9 @@
|
||||
<table>
|
||||
<tr>
|
||||
<td>Account Name:</td>
|
||||
<td><input name="answer" value="" type="TEXT" /></td>
|
||||
<td></td>
|
||||
<td><input name="account" value="" type="TEXT" /></td>
|
||||
<td><input
|
||||
name="Get Account Info" value="Get Account Info" type="SUBMIT"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
@ -87,7 +88,9 @@
|
||||
<table>
|
||||
<tr>
|
||||
<td>Name:</td>
|
||||
<td><input name="answer" value="" type="TEXT" /></td>
|
||||
<td><input name="userid" value="" type="TEXT" /></td>
|
||||
<td><input
|
||||
name="Get Account Info" value="Get Account Info" type="SUBMIT"/></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -106,6 +109,65 @@
|
||||
<div class="adoc-content" th:replace="doc:SqlInjection_content6.adoc"></div>
|
||||
</div>
|
||||
<div class="lesson-page-wrapper">
|
||||
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
|
||||
<!-- include content here. Content will be presented via asciidocs files,
|
||||
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
|
||||
<div class="adoc-content" th:replace="doc:SqlInjection_content6a.adoc"></div>
|
||||
<div class="attack-container">
|
||||
<!-- using attack-form class on your form, will allow your request to be ajaxified and stay within the display framework for webgoat -->
|
||||
<div id="lessonContent">
|
||||
<!-- using attack-form class on your form will allow your request to be ajaxified and stay within the display framework for webgoat -->
|
||||
<!-- you can write your own custom forms, but standard form submission will take you to your endpoint and outside of the WebGoat framework -->
|
||||
<!-- of course, you can write your own ajax submission /handling in your own javascript if you like -->
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="/WebGoat/SqlInjection/attack6a"
|
||||
enctype="application/json;charset=UTF-8">
|
||||
<table>
|
||||
<tr>
|
||||
<td>Name:</td>
|
||||
<td><input name="userid_6a" value="" type="TEXT" /></td>
|
||||
<td><input
|
||||
name="Get Account Info" value="Get Account Info" type="SUBMIT"/></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
<!-- do not remove the two following div's, this is where your feedback/output will land -->
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
<!-- ... of course, you can move them if you want to, but that will not look consistent to other lessons -->
|
||||
</div>
|
||||
<div class="attack-container">
|
||||
<!-- using attack-form class on your form, will allow your request to be ajaxified and stay within the display framework for webgoat -->
|
||||
<div id="lessonContent">
|
||||
<!-- using attack-form class on your form will allow your request to be ajaxified and stay within the display framework for webgoat -->
|
||||
<!-- you can write your own custom forms, but standard form submission will take you to your endpoint and outside of the WebGoat framework -->
|
||||
<!-- of course, you can write your own ajax submission /handling in your own javascript if you like -->
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="/WebGoat/SqlInjection/attack6b"
|
||||
enctype="application/json;charset=UTF-8">
|
||||
<table>
|
||||
<tr>
|
||||
<td>Password:</td>
|
||||
<td><input name="userid_6b" value="" type="TEXT" /></td>
|
||||
<td><input
|
||||
name="Check Dave's Password:" value="Check Password" type="SUBMIT"/></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
<!-- do not remove the two following div's, this is where your feedback/output will land -->
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
<!-- ... of course, you can move them if you want to, but that will not look consistent to other lessons -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="lesson-page-wrapper">
|
||||
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
|
||||
<!-- include content here, or can be placed in another location. Content will be presented via asciidocs files,
|
||||
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
|
||||
|
@ -1,23 +1,26 @@
|
||||
== Example of SQL Injection
|
||||
|
||||
=== Dynamic query in application
|
||||
|
||||
==== Potential String Injection
|
||||
-------------------------------------------------------
|
||||
"select * from users where name = ‘" + userName + "'";
|
||||
-------------------------------------------------------
|
||||
|
||||
==== Potential Numeric Injection
|
||||
-------------------------------------------------------
|
||||
|
||||
"select * from users where employee_id = " + userID;
|
||||
-------------------------------------------------------
|
||||
|
||||
=== Attacker supplies unexpected text
|
||||
* userName = [red]#Smith’ or ‘1’=‘1#
|
||||
* userName =[red]#‘ or 1=1 --#
|
||||
* userName = [red]#Smith' or '1'='1#
|
||||
* userName =[red]#' or 1=1 --#
|
||||
* userID = [red]#1234567 or 1=1#
|
||||
* UserName = [red]#Smith’;drop table users; truncate audit_log;--#
|
||||
|
||||
=== Application executes query
|
||||
* select * from users where name = [red]#‘Smith’ or ‘1’ = ‘1’#
|
||||
** select * from users where name = [red]#‘Smith’ or TRUE#
|
||||
* select * from users where name = [red]#'Smith' or '1' = '1'#
|
||||
** select * from users where name = [red]#'Smith' or TRUE#
|
||||
* select * from users where employee_id = 1234567 or 1=1
|
||||
* *All records are returned from database*
|
||||
|
@ -1,6 +1,7 @@
|
||||
== Try It! String SQL Injection
|
||||
|
||||
The query in the code builds a dynamic query as seen in the previous example. The query in the code looks like:
|
||||
The query in the code builds a dynamic query as seen in the previous example. The query in the code builds a dynamic query by concatenating strings making it susceptible to String SQL injection:
|
||||
|
||||
-------------------------------------------------------
|
||||
"select * from users where name = ‘" + userName + "'";
|
||||
-------------------------------------------------------
|
||||
|
@ -1,6 +1,7 @@
|
||||
== Try It! Numeric SQL Injection
|
||||
|
||||
The query in the code builds a dynamic query as seen in the previous example. The query in the code looks like:
|
||||
The query in the code builds a dynamic query as seen in the previous example. The query in the code builds a dynamic query by concatenating a number making it susceptible to Numeric SQL injection:
|
||||
|
||||
-------------------------------------------------------
|
||||
"select * from users where employee_id = " + userID;
|
||||
-------------------------------------------------------
|
||||
|
@ -0,0 +1,14 @@
|
||||
== Try It! Pulling data from other tables
|
||||
|
||||
Lets try to exploit a join to another table. One of the tables in the WebGoat database is:
|
||||
|
||||
-------------------------------------------------------
|
||||
CREATE TABLE user_system_data (userid varchar(5) not null primary key,
|
||||
user_name varchar(12),
|
||||
password varchar(10),
|
||||
cookie varchar(30));
|
||||
-------------------------------------------------------
|
||||
|
||||
Execute a query to union or join these tables. When you have figured it out.... What is Dave's password?
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user