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
|
@Autowired
|
||||||
private UserTracker userTracker;
|
private UserTracker userTracker;
|
||||||
@Autowired
|
@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) {
|
protected AttackResult trackProgress(AttackResult attackResult) {
|
||||||
if (attackResult.assignmentSolved()) {
|
if (attackResult.assignmentSolved()) {
|
||||||
userTracker.assignmentSolved(webSession.getCurrentLesson(), this);
|
userTracker.assignmentSolved(webSession.getCurrentLesson(), this);
|
||||||
@ -56,4 +57,9 @@ public abstract class Assignment extends Endpoint {
|
|||||||
return attackResult;
|
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, Connection> connections = new HashMap<String, Connection>();
|
||||||
private static Map<String, Boolean> dbBuilt = new HashMap<String, Boolean>();
|
private static Map<String, Boolean> dbBuilt = new HashMap<String, Boolean>();
|
||||||
@Autowired
|
|
||||||
private static WebSession webSession;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>getConnection.</p>
|
* <p>getConnection.</p>
|
||||||
@ -54,9 +52,9 @@ public class DatabaseUtilities
|
|||||||
* @return a {@link java.sql.Connection} object.
|
* @return a {@link java.sql.Connection} object.
|
||||||
* @throws java.sql.SQLException if any.
|
* @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.
|
* @return a {@link java.sql.Connection} object.
|
||||||
* @throws java.sql.SQLException if any.
|
* @throws java.sql.SQLException if any.
|
||||||
*/
|
*/
|
||||||
public static synchronized Connection getConnection() throws SQLException {
|
public static synchronized Connection getConnection(WebSession s) throws SQLException {
|
||||||
return DatabaseUtilities.getConnection();
|
return DatabaseUtilities.getConnection(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,9 +53,8 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
|||||||
public class SqlInjectionLesson5a extends Assignment {
|
public class SqlInjectionLesson5a extends Assignment {
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST)
|
@RequestMapping(method = RequestMethod.POST)
|
||||||
public @ResponseBody AttackResult completed(@RequestParam String answer, HttpServletRequest request) throws IOException {
|
public @ResponseBody AttackResult completed(@RequestParam String account, HttpServletRequest request) throws IOException {
|
||||||
System.out.println("answer:" + answer);
|
return injectableQuery(account);
|
||||||
return injectableQuery(answer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -64,12 +63,11 @@ System.out.println("answer:" + answer);
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected AttackResult injectableQuery(String accountName)
|
protected AttackResult injectableQuery(String accountName)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Connection connection = DatabaseUtilities.getConnection();
|
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
||||||
String query = "SELECT * FROM user_data WHERE last_name = '" + accountName + "'";
|
String query = "SELECT * FROM user_data WHERE last_name = '" + accountName + "'";
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -91,7 +89,7 @@ System.out.println("answer:" + answer);
|
|||||||
{
|
{
|
||||||
return trackProgress(AttackResult.success("You have succeed: " + output.toString()));
|
return trackProgress(AttackResult.success("You have succeed: " + output.toString()));
|
||||||
} else {
|
} 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. "));
|
return trackProgress(AttackResult.failed("No Results Matched. Try Again. "));
|
||||||
|
|
||||||
// output.append(getLabelManager().get("NoResultsMatched"));
|
|
||||||
}
|
}
|
||||||
} catch (SQLException sqle)
|
} catch (SQLException sqle)
|
||||||
{
|
{
|
||||||
|
|
||||||
return trackProgress(AttackResult.failed(sqle.getMessage()));
|
return trackProgress(AttackResult.failed(sqle.getMessage()));
|
||||||
}
|
}
|
||||||
} catch (Exception e)
|
} 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();
|
int numColumns = resultsMetaData.getColumnCount();
|
||||||
results.beforeFirst();
|
results.beforeFirst();
|
||||||
StringBuffer t = new StringBuffer();
|
StringBuffer t = new StringBuffer();
|
||||||
|
t.append("<p>");
|
||||||
|
|
||||||
if (results.next())
|
if (results.next())
|
||||||
{
|
{
|
||||||
@ -126,7 +126,7 @@ System.out.println("answer:" + answer);
|
|||||||
t.append(", ");
|
t.append(", ");
|
||||||
}
|
}
|
||||||
|
|
||||||
t.append(System.getProperty("line.separator"));
|
t.append("<br />");
|
||||||
results.beforeFirst();
|
results.beforeFirst();
|
||||||
|
|
||||||
while (results.next())
|
while (results.next())
|
||||||
@ -138,15 +138,17 @@ System.out.println("answer:" + answer);
|
|||||||
t.append(", ");
|
t.append(", ");
|
||||||
}
|
}
|
||||||
|
|
||||||
t.append(System.getProperty("line.separator"));
|
t.append("<br />");
|
||||||
}
|
}
|
||||||
|
|
||||||
return (t.toString());
|
|
||||||
}
|
}
|
||||||
else
|
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)
|
// 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>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Account Name:</td>
|
<td>Account Name:</td>
|
||||||
<td><input name="answer" value="" type="TEXT" /></td>
|
<td><input name="account" value="" type="TEXT" /></td>
|
||||||
<td></td>
|
<td><input
|
||||||
|
name="Get Account Info" value="Get Account Info" type="SUBMIT"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</form>
|
</form>
|
||||||
@ -87,7 +88,9 @@
|
|||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Name:</td>
|
<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>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@ -106,6 +109,65 @@
|
|||||||
<div class="adoc-content" th:replace="doc:SqlInjection_content6.adoc"></div>
|
<div class="adoc-content" th:replace="doc:SqlInjection_content6.adoc"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="lesson-page-wrapper">
|
<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 -->
|
<!-- 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,
|
<!-- 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 -->
|
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
|
||||||
|
@ -1,23 +1,26 @@
|
|||||||
== Example of SQL Injection
|
== Example of SQL Injection
|
||||||
|
|
||||||
=== Dynamic query in application
|
=== Dynamic query in application
|
||||||
|
|
||||||
|
==== Potential String Injection
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
"select * from users where name = ‘" + userName + "'";
|
"select * from users where name = ‘" + userName + "'";
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
|
||||||
|
==== Potential Numeric Injection
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
|
||||||
"select * from users where employee_id = " + userID;
|
"select * from users where employee_id = " + userID;
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
|
||||||
=== Attacker supplies unexpected text
|
=== Attacker supplies unexpected text
|
||||||
* userName = [red]#Smith’ or ‘1’=‘1#
|
* userName = [red]#Smith' or '1'='1#
|
||||||
* userName =[red]#‘ or 1=1 --#
|
* userName =[red]#' or 1=1 --#
|
||||||
* userID = [red]#1234567 or 1=1#
|
* userID = [red]#1234567 or 1=1#
|
||||||
* UserName = [red]#Smith’;drop table users; truncate audit_log;--#
|
* UserName = [red]#Smith’;drop table users; truncate audit_log;--#
|
||||||
|
|
||||||
=== Application executes query
|
=== Application executes query
|
||||||
* select * from users where name = [red]#‘Smith’ or ‘1’ = ‘1’#
|
* 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 TRUE#
|
||||||
* select * from users where employee_id = 1234567 or 1=1
|
* select * from users where employee_id = 1234567 or 1=1
|
||||||
* *All records are returned from database*
|
* *All records are returned from database*
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
== Try It! String SQL Injection
|
== 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 + "'";
|
"select * from users where name = ‘" + userName + "'";
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
== Try It! Numeric SQL Injection
|
== 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;
|
"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