218 lines
7.4 KiB
Java
218 lines
7.4 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;
|
|
|
|
/**
|
|
* @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 );
|
|
private static Connection connection = null;
|
|
/* (non-Javadoc)
|
|
* @see lessons.AbstractLesson#getMenuItem()
|
|
*/
|
|
static boolean completed;
|
|
|
|
protected Category getDefaultCategory()
|
|
{
|
|
return AbstractLesson.WEB_SERVICES;
|
|
}
|
|
|
|
protected List getHints()
|
|
{
|
|
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
|
|
{
|
|
if ( connection == null )
|
|
{
|
|
connection = DatabaseUtilities.makeConnection( s );
|
|
}
|
|
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");
|
|
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.makeConnection();
|
|
if (connection == null) {
|
|
return null;
|
|
}
|
|
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);
|
|
}
|
|
}
|