263 lines
8.0 KiB
Java
263 lines
8.0 KiB
Java
package org.owasp.webgoat.lessons;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.File;
|
|
import java.io.FileReader;
|
|
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.HR;
|
|
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;
|
|
|
|
/**
|
|
* Copyright (c) 2002 Free Software Foundation developed under the custody of the Open Web
|
|
* Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.is published by OWASP
|
|
* under the GPL. You should read and accept the LICENSE before you use, modify and/or redistribute
|
|
* this software.
|
|
*
|
|
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
|
|
* @created October 28, 2003
|
|
*/
|
|
public class PathBasedAccessControl extends LessonAdapter
|
|
{
|
|
private final static String FILE = "File";
|
|
|
|
|
|
/**
|
|
* 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();
|
|
|
|
try
|
|
{
|
|
String dir = s.getContext().getRealPath( "/lesson_plans" );
|
|
File d = new File( dir );
|
|
|
|
Table t = new Table().setCellSpacing( 0 ).setCellPadding( 2 ).setWidth("90%").setAlign("center");
|
|
|
|
if ( s.isColor() )
|
|
{
|
|
t.setBorder( 1 );
|
|
}
|
|
|
|
String[] list = d.list();
|
|
String listing = " <p><B>Current Directory is:</B> " + Encoding.urlDecode( dir ) + "<br><br> Choose the file to view:</p>";
|
|
|
|
TR tr = new TR();
|
|
tr.addElement(new TD().setColSpan(2).addElement( new StringElement(listing) ));
|
|
t.addElement(tr);
|
|
|
|
tr = new TR();
|
|
tr.addElement( new TD().setWidth("35%").addElement( ECSFactory.makePulldown( FILE, list, "", 15 )));
|
|
tr.addElement( new TD().addElement( ECSFactory.makeButton( "View File" )));
|
|
t.addElement(tr);
|
|
|
|
ec.addElement( t );
|
|
|
|
|
|
// FIXME: would be cool to allow encodings here -- hex, percent, url, etc...
|
|
String file = s.getParser().getRawParameter( FILE, "" );
|
|
|
|
// defuse file searching
|
|
boolean illegalCommand = s.isDefuseOSCommands();
|
|
if ( s.isDefuseOSCommands() )
|
|
{
|
|
// allow them to look at any file in the webgoat hierachy. Don't allow them
|
|
// to look about the webgoat root, except to see the LICENSE file
|
|
if( upDirCount( file ) == 3 && !file.endsWith("LICENSE"))
|
|
{
|
|
s.setMessage( "Access denied" );
|
|
s.setMessage( "It appears that you are on the right track. " +
|
|
"Commands that may compromise the operating system have been disabled. " +
|
|
"You are only allowed to see one file in this directory. ");;
|
|
}
|
|
else if ( upDirCount( file ) > 3 )
|
|
{
|
|
s.setMessage( "Access denied" );
|
|
s.setMessage( "It appears that you are on the right track. " +
|
|
"Commands that may compromise the operating system have been disabled. " +
|
|
"You are only allowed to see files in the webgoat directory. ");
|
|
}
|
|
else
|
|
{
|
|
illegalCommand = false;
|
|
}
|
|
}
|
|
|
|
// Using the URI supports encoding of the data.
|
|
// We could force the user to use encoded '/'s == %2f to make the lesson more difficult.
|
|
// We url Encode our dir name to avoid problems with special characters in our own path.
|
|
//File f = new File( new URI("file:///" + Encoding.urlEncode(dir).replaceAll("\\\\","/") + "/" + file.replaceAll("\\\\","/")) );
|
|
File f = new File( (dir + "\\" + file).replaceAll("\\\\","/"));
|
|
|
|
if( s.isDebug() )
|
|
{
|
|
|
|
s.setMessage("File: " + file );
|
|
s.setMessage("Dir: " + dir );
|
|
//s.setMessage("File URI: " + "file:///" + (Encoding.urlEncode(dir) + "\\" + Encoding.urlEncode(file)).replaceAll("\\\\","/"));
|
|
s.setMessage(" - isFile(): " + f.isFile() );
|
|
s.setMessage(" - exists(): " + f.exists() );
|
|
}
|
|
if ( !illegalCommand )
|
|
{
|
|
if ( f.isFile() && f.exists() )
|
|
{
|
|
// Don't set completion if they are listing files in the
|
|
// directory listing we gave them.
|
|
if ( upDirCount( file ) >= 1 )
|
|
{
|
|
s.setMessage( "Congratulations! Access to file allowed" );
|
|
s.setMessage( " ==> " + Encoding.urlDecode( f.getCanonicalPath() ));
|
|
makeSuccess( s );
|
|
}
|
|
else
|
|
{
|
|
s.setMessage( "File is already in allowed directory - try again!" );
|
|
s.setMessage( " ==> " + Encoding.urlDecode( f.getCanonicalPath() ));
|
|
}
|
|
}
|
|
else if ( file != null && file.length() != 0 )
|
|
{
|
|
s.setMessage( "Access to file/directory \"" + Encoding.urlDecode( f.getCanonicalPath() ) + "\" denied" );
|
|
}
|
|
else
|
|
{
|
|
// do nothing, probably entry screen
|
|
}
|
|
|
|
try
|
|
{
|
|
// Show them the file
|
|
// Strip out some of the extra html from the "help" file
|
|
ec.addElement( new BR() );
|
|
ec.addElement( new BR() );
|
|
ec.addElement( new HR().setWidth("100%") );
|
|
ec.addElement( "Viewing file: " + f.getCanonicalPath() );
|
|
ec.addElement( new HR().setWidth("100%") );
|
|
if ( f.length() > 80000 )
|
|
{
|
|
throw new Exception("File is too large");
|
|
}
|
|
String fileData= getFileText( new BufferedReader( new FileReader( f ) ), false );
|
|
if ( fileData.indexOf(0x00) != -1)
|
|
{
|
|
throw new Exception("File is binary");
|
|
}
|
|
ec.addElement( new StringElement( fileData.replaceAll(System.getProperty("line.separator"),"<br>")
|
|
.replaceAll("(?s)<!DOCTYPE.*/head>","")
|
|
.replaceAll("<br><br>","<br>")
|
|
.replaceAll("<br>\\s<br>","<br>")
|
|
.replaceAll("<\\?", "<")
|
|
.replaceAll("<(r|u|t)", "<$1")));
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
ec.addElement( new BR() );
|
|
ec.addElement("The following error occurred while accessing the file: <");
|
|
ec.addElement( e.getMessage() );
|
|
}
|
|
}
|
|
}
|
|
catch ( Exception e )
|
|
{
|
|
s.setMessage( "Error generating " + this.getClass().getName() );
|
|
e.printStackTrace();
|
|
}
|
|
|
|
return ( ec );
|
|
}
|
|
|
|
private int upDirCount( String fileName )
|
|
{
|
|
int count = 0;
|
|
int startIndex = fileName.indexOf("..");
|
|
while ( startIndex != -1 )
|
|
{
|
|
count++;
|
|
startIndex = fileName.indexOf("..", startIndex+1);
|
|
}
|
|
return count;
|
|
}
|
|
|
|
/**
|
|
* DOCUMENT ME!
|
|
*
|
|
* @return DOCUMENT ME!
|
|
*/
|
|
protected Category getDefaultCategory()
|
|
{
|
|
return AbstractLesson.A2;
|
|
}
|
|
|
|
|
|
/**
|
|
* Gets the hints attribute of the AccessControlScreen object
|
|
*
|
|
* @return The hints value
|
|
*/
|
|
protected List getHints()
|
|
{
|
|
List<String> hints = new ArrayList<String>();
|
|
hints.add( "Most operating systems allow special characters in the path." );
|
|
hints.add( "Use a file explorer to find the tomcat\\webapps\\WebGoat\\lesson_plans directory" );
|
|
hints.add( "Try .. in the path" );
|
|
hints.add( "Try ..\\..\\..\\LICENSE" );
|
|
|
|
return hints;
|
|
}
|
|
|
|
|
|
/**
|
|
* Gets the instructions attribute of the WeakAccessControl object
|
|
*
|
|
* @return The instructions value
|
|
*/
|
|
public String getInstructions(WebSession s)
|
|
{
|
|
String instructions = "The '" + s.getUserName() + "' user has access to all the files in the " +
|
|
"lesson_plans directory. Try to break the access control mechanism and access a " +
|
|
"resource that is not in the listed directory. After selecting a file to view, WebGoat " +
|
|
"will report if access to the file was granted. An interesting file to try and obtain might " +
|
|
"be a file like tomcat/conf/tomcat-users.xml";
|
|
|
|
return ( instructions );
|
|
}
|
|
|
|
|
|
|
|
|
|
private final static Integer DEFAULT_RANKING = new Integer(120);
|
|
|
|
protected Integer getDefaultRanking()
|
|
{
|
|
return DEFAULT_RANKING;
|
|
}
|
|
|
|
|
|
/**
|
|
* Gets the title attribute of the AccessControlScreen object
|
|
*
|
|
* @return The title value
|
|
*/
|
|
public String getTitle()
|
|
{
|
|
return ( "How to Bypass a Path Based Access Control Scheme" );
|
|
}
|
|
}
|
|
|