divide by zero, inaccurate discount and totals, reflection of user input git-svn-id: http://webgoat.googlecode.com/svn/trunk/webgoat@273 4033779f-a91e-0410-96ef-6bf7bf53c507
295 lines
9.1 KiB
Java
295 lines
9.1 KiB
Java
/*
|
|
* Created on Jun 1, 2005
|
|
*
|
|
* TODO To change the template for this generated file go to
|
|
* Window - Preferences - Java - Code Style - Code Templates
|
|
*/
|
|
package org.owasp.webgoat.lessons;
|
|
|
|
import java.sql.Connection;
|
|
import java.sql.ResultSet;
|
|
import java.sql.ResultSetMetaData;
|
|
import java.sql.SQLException;
|
|
import java.sql.Statement;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
import org.apache.ecs.Element;
|
|
import org.apache.ecs.ElementContainer;
|
|
import org.apache.ecs.html.A;
|
|
import org.apache.ecs.html.BR;
|
|
import org.apache.ecs.html.IMG;
|
|
import org.apache.ecs.html.Input;
|
|
import org.apache.ecs.html.P;
|
|
import org.apache.ecs.html.PRE;
|
|
|
|
import org.owasp.webgoat.session.DatabaseUtilities;
|
|
import org.owasp.webgoat.session.ECSFactory;
|
|
import org.owasp.webgoat.session.WebSession;
|
|
import org.owasp.webgoat.session.WebgoatContext;
|
|
|
|
/*******************************************************************************
|
|
*
|
|
*
|
|
* 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 asmolen
|
|
*
|
|
* TODO To change the template for this generated type comment go to
|
|
* Window - Preferences - Java - Code Style - Code Templates
|
|
*/
|
|
public class WsSqlInjection extends LessonAdapter
|
|
{
|
|
|
|
public final static String ccNumber = "cc_number";
|
|
|
|
private final static String ACCT_NUM = "account_number";
|
|
|
|
private String accountNumber;
|
|
|
|
final static IMG CREDITS_LOGO = new IMG("images/logos/parasoft.jpg")
|
|
.setAlt("Parasoft").setBorder(0).setHspace(0).setVspace(0);
|
|
|
|
/* (non-Javadoc)
|
|
* @see lessons.AbstractLesson#getMenuItem()
|
|
*/
|
|
static boolean completed;
|
|
|
|
private static WebgoatContext webgoatContext;
|
|
|
|
/**
|
|
* We maintain a static reference to WebgoatContext, since this class
|
|
* is also automatically instantiated by the Axis web services module,
|
|
* which does not call setWebgoatContext()
|
|
* (non-Javadoc)
|
|
* @see org.owasp.webgoat.lessons.AbstractLesson#setWebgoatContext(org.owasp.webgoat.session.WebgoatContext)
|
|
*/
|
|
@Override
|
|
public void setWebgoatContext(WebgoatContext webgoatContext) {
|
|
WsSqlInjection.webgoatContext = webgoatContext;
|
|
}
|
|
|
|
@Override
|
|
public WebgoatContext getWebgoatContext() {
|
|
return WsSqlInjection.webgoatContext;
|
|
}
|
|
|
|
|
|
protected Category getDefaultCategory()
|
|
{
|
|
return Category.WEB_SERVICES;
|
|
}
|
|
|
|
|
|
protected List<String> getHints(WebSession s)
|
|
{
|
|
List<String> hints = new ArrayList<String>();
|
|
hints
|
|
.add("Try connecting to the WSDL with a browser or Web Service tool.");
|
|
hints
|
|
.add("Sometimes the server side code will perform input validation before issuing "
|
|
+ "the request to the web service operation. Try to bypass this check by "
|
|
+ "accessing the web service directly");
|
|
hints
|
|
.add("The URL for the web service is: http://localhost/WebGoat/services/WsSqlInjection?WSDL <br>"
|
|
+ "The WSDL can usually be viewed by adding a ?WSDL on the end of the request.");
|
|
hints
|
|
.add("Create a new soap request for the getCreditCard(String id) operation.");
|
|
hints
|
|
.add("A soap request uses the following HTTP header: <br> "
|
|
+ "SOAPAction: some action header, can be ""<br><br>"
|
|
+ "The soap message body has the following format:<br>"
|
|
+ "<?xml version='1.0' encoding='UTF-8'?> <br>"
|
|
+ " <SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> <br>"
|
|
+ " <SOAP-ENV:Body> <br>"
|
|
+ " <ns1:getCreditCard SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' xmlns:ns1='http://lessons'> <br>"
|
|
+ " <id xsi:type='xsd:string'>101</id> <br>"
|
|
+ " </ns1:getCreditCard> <br>"
|
|
+ " </SOAP-ENV:Body> <br>"
|
|
+ " </SOAP-ENV:Envelope> <br>" + "");
|
|
/* "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <br>" +
|
|
" <SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" <br>" +
|
|
" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" <br>" +
|
|
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"> <br>" +
|
|
" <SOAP-ENV:Body> <br>" +
|
|
" <ns1:getCreditCard SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:ns1=\"http://lessons\"> <br>" +
|
|
" <id xsi:type=\"xsd:string\">101</id> <br>"+
|
|
" </ns1:getCreditCard> <br>" +
|
|
" </SOAP-ENV:Body> <br>" +
|
|
" </SOAP-ENV:Envelope> <br><br>" +
|
|
"Intercept the HTTP request and try to create a soap request."); */
|
|
return hints;
|
|
}
|
|
|
|
private final static Integer DEFAULT_RANKING = new Integer(150);
|
|
|
|
|
|
protected Integer getDefaultRanking()
|
|
{
|
|
return DEFAULT_RANKING;
|
|
}
|
|
|
|
|
|
public String getTitle()
|
|
{
|
|
return "Web Service SQL Injection";
|
|
}
|
|
|
|
|
|
protected Element makeAccountLine(WebSession s)
|
|
{
|
|
ElementContainer ec = new ElementContainer();
|
|
|
|
ec.addElement(new P().addElement("Enter your Account Number: "));
|
|
|
|
accountNumber = s.getParser().getRawParameter(ACCT_NUM, "101");
|
|
Input input = new Input(Input.TEXT, ACCT_NUM, accountNumber.toString());
|
|
ec.addElement(input);
|
|
|
|
Element b = ECSFactory.makeButton("Go!");
|
|
ec.addElement(b);
|
|
|
|
return ec;
|
|
}
|
|
|
|
|
|
protected Element createContent(WebSession s)
|
|
{
|
|
ElementContainer ec = new ElementContainer();
|
|
try
|
|
{
|
|
ec.addElement(makeAccountLine(s));
|
|
|
|
String query = "SELECT * FROM user_data WHERE userid = "
|
|
+ accountNumber;
|
|
ec.addElement(new PRE(query));
|
|
for (int i = 0; i < accountNumber.length(); i++)
|
|
{
|
|
char c = accountNumber.charAt(i);
|
|
if (c < '0' || c > '9')
|
|
{
|
|
ec.addElement("Invalid account number. ");
|
|
accountNumber = "0";
|
|
}
|
|
}
|
|
try
|
|
{
|
|
ResultSet results = getResults(accountNumber);
|
|
if ((results != null) && (results.first() == true))
|
|
{
|
|
ResultSetMetaData resultsMetaData = results.getMetaData();
|
|
ec.addElement(DatabaseUtilities.writeTable(results,
|
|
resultsMetaData));
|
|
results.last();
|
|
if (results.getRow() >= 6)
|
|
{
|
|
//this should never happen
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ec.addElement("No results matched. Try Again.");
|
|
}
|
|
}
|
|
catch (SQLException sqle)
|
|
{
|
|
ec.addElement(new P().addElement(sqle.getMessage()));
|
|
}
|
|
A a = new A("services/WsSqlInjection?WSDL", "WebGoat WSDL File");
|
|
ec
|
|
.addElement(new P()
|
|
.addElement("Exploit the following WSDL to access sensitive data:"));
|
|
ec.addElement(new BR());
|
|
ec.addElement(a);
|
|
getLessonTracker(s).setCompleted(completed);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
s.setMessage("Error generating " + this.getClass().getName());
|
|
e.printStackTrace();
|
|
}
|
|
return (ec);
|
|
}
|
|
|
|
|
|
public ResultSet getResults(String id)
|
|
{
|
|
try
|
|
{
|
|
Connection connection = DatabaseUtilities.getConnection("guest", getWebgoatContext());
|
|
String query = "SELECT * FROM user_data WHERE userid = " + id;
|
|
try
|
|
{
|
|
Statement statement = connection.createStatement(
|
|
ResultSet.TYPE_SCROLL_INSENSITIVE,
|
|
ResultSet.CONCUR_READ_ONLY);
|
|
ResultSet results = statement.executeQuery(query);
|
|
return results;
|
|
}
|
|
catch (SQLException sqle)
|
|
{}
|
|
}
|
|
catch (Exception e)
|
|
{}
|
|
return null;
|
|
}
|
|
|
|
|
|
public String[] getCreditCard(String id)
|
|
{
|
|
ResultSet results = getResults(id);
|
|
if ((results != null))
|
|
{
|
|
try
|
|
{
|
|
results.last();
|
|
String[] users = new String[results.getRow()];
|
|
if (users.length > 4)
|
|
{
|
|
completed = true;
|
|
}
|
|
results.beforeFirst();
|
|
while (results.next() == true)
|
|
{
|
|
int i = results.getRow();
|
|
users[i - 1] = results.getString(ccNumber);
|
|
}
|
|
return users;
|
|
}
|
|
catch (SQLException sqle)
|
|
{}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
|
|
public Element getCredits()
|
|
{
|
|
return super.getCustomCredits("By Alex Smolen", CREDITS_LOGO);
|
|
}
|
|
}
|