Files
doc
java
org
owasp
webgoat
controller
lessons
service
servlets
session
util
Exec.java
ExecResults.java
ExecutionException.java
HtmlEncoder.java
Interceptor.java
ThreadWatcher.java
WebGoatI18N.java
Catcher.java
HammerHead.java
LessonSource.java
resources
scripts
tomcatconf
webapp
.gitignore
README.txt
build.xml
pom.xml
webgoat for SQL Server.bat
webgoat.bat
webgoat.sh
webgoat_8080.bat
webscarab.bat
WebGoat/java/org/owasp/webgoat/util/Exec.java

528 lines
14 KiB
Java

package org.owasp.webgoat.util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.BitSet;
/***************************************************************************************************
*
*
* 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 Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @created October 28, 2003
*/
public class Exec
{
/**
* Description of the Method
*
* @param command
* Description of the Parameter
* @param input
* Description of the Parameter
* @return Description of the Return Value
*/
public static ExecResults execInput(String command, String input)
{
return (execOptions(command, input, 0, 0, false));
}
/**
* Description of the Method
*
* @param command
* Description of the Parameter
* @return Description of the Return Value
*/
public static ExecResults execLazy(String command)
{
return (execOptions(command, "", 0, 0, true));
}
/*
* Execute an OS command and capture the output in an ExecResults. All exceptions are caught and
* stored in the ExecResults. @param String command is the OS command to execute @param String
* input is piped into the OS command @param int successCode is the expected return code if the
* command completes successfully @param int timeout is the number of milliseconds to wait
* before interrupting the command @param boolean quit tells the method to exit when there is no
* more output waiting
*/
/**
* Description of the Method
*
* @param command
* Description of the Parameter
* @param input
* Description of the Parameter
* @param successCode
* Description of the Parameter
* @param timeout
* Description of the Parameter
* @param lazy
* Description of the Parameter
* @return Description of the Return Value
*/
public static ExecResults execOptions(String[] command, String input, int successCode, int timeout, boolean lazy)
{
Process child = null;
ByteArrayOutputStream output = new ByteArrayOutputStream();
ByteArrayOutputStream errors = new ByteArrayOutputStream();
ExecResults results = new ExecResults(Arrays.asList(command).toString(), input, successCode, timeout);
BitSet interrupted = new BitSet(1);
boolean lazyQuit = false;
ThreadWatcher watcher;
try
{
// start the command
child = Runtime.getRuntime().exec(command);
// get the streams in and out of the command
InputStream processIn = child.getInputStream();
InputStream processError = child.getErrorStream();
OutputStream processOut = child.getOutputStream();
// start the clock running
if (timeout > 0)
{
watcher = new ThreadWatcher(child, interrupted, timeout);
new Thread(watcher).start();
}
// Write to the child process' input stream
if ((input != null) && !input.equals(""))
{
try
{
processOut.write(input.getBytes());
processOut.flush();
processOut.close();
} catch (IOException e1)
{
results.setThrowable(e1);
}
}
// Read from the child process' output stream
// The process may get killed by the watcher at any time
int c = 0;
try
{
while (true)
{
if (interrupted.get(0) || lazyQuit)
{
break;
}
// interrupted
c = processIn.read();
if (c == -1)
{
break;
}
// end of stream
output.write(c);
if (lazy && (processIn.available() < 1))
{
lazyQuit = true;
}
// if lazy and nothing then quit (after at least one read)
}
processIn.close();
} catch (IOException e2)
{
results.setThrowable(e2);
} finally
{
if (interrupted.get(0))
{
results.setInterrupted();
}
results.setOutput(output.toString());
}
// Read from the child process' error stream
// The process may get killed by the watcher at any time
try
{
while (true)
{
if (interrupted.get(0) || lazyQuit)
{
break;
}
// interrupted
c = processError.read();
if (c == -1)
{
break;
}
// end of stream
output.write(c);
if (lazy && (processError.available() < 1))
{
lazyQuit = true;
}
// if lazy and nothing then quit (after at least one read)
}
processError.close();
} catch (IOException e3)
{
results.setThrowable(e3);
} finally
{
if (interrupted.get(0))
{
results.setInterrupted();
}
results.setErrors(errors.toString());
}
// wait for the return value of the child process.
if (!interrupted.get(0) && !lazyQuit)
{
int returnCode = child.waitFor();
results.setReturnCode(returnCode);
if (returnCode != successCode)
{
results.setError(ExecResults.BADRETURNCODE);
}
}
} catch (InterruptedException i)
{
results.setInterrupted();
} catch (Throwable t)
{
results.setThrowable(t);
} finally
{
if (child != null)
{
child.destroy();
}
}
return (results);
}
/*
* Execute an OS command and capture the output in an ExecResults. All exceptions are caught and
* stored in the ExecResults. @param String command is the OS command to execute @param String
* input is piped into the OS command @param int successCode is the expected return code if the
* command completes successfully @param int timeout is the number of milliseconds to wait
* before interrupting the command @param boolean quit tells the method to exit when there is no
* more output waiting
*/
/**
* Description of the Method
*
* @param command
* Description of the Parameter
* @param input
* Description of the Parameter
* @param successCode
* Description of the Parameter
* @param timeout
* Description of the Parameter
* @param lazy
* Description of the Parameter
* @return Description of the Return Value
*/
public static ExecResults execOptions(String command, String input, int successCode, int timeout, boolean lazy)
{
Process child = null;
ByteArrayOutputStream output = new ByteArrayOutputStream();
ByteArrayOutputStream errors = new ByteArrayOutputStream();
ExecResults results = new ExecResults(command, input, successCode, timeout);
BitSet interrupted = new BitSet(1);
boolean lazyQuit = false;
ThreadWatcher watcher;
try
{
// start the command
child = Runtime.getRuntime().exec(command);
// get the streams in and out of the command
InputStream processIn = child.getInputStream();
InputStream processError = child.getErrorStream();
OutputStream processOut = child.getOutputStream();
// start the clock running
if (timeout > 0)
{
watcher = new ThreadWatcher(child, interrupted, timeout);
new Thread(watcher).start();
}
// Write to the child process' input stream
if ((input != null) && !input.equals(""))
{
try
{
processOut.write(input.getBytes());
processOut.flush();
processOut.close();
} catch (IOException e1)
{
results.setThrowable(e1);
}
}
// Read from the child process' output stream
// The process may get killed by the watcher at any time
int c = 0;
try
{
while (true)
{
if (interrupted.get(0) || lazyQuit)
{
break;
}
// interrupted
c = processIn.read();
if (c == -1)
{
break;
}
// end of stream
output.write(c);
if (lazy && (processIn.available() < 1))
{
lazyQuit = true;
}
// if lazy and nothing then quit (after at least one read)
}
processIn.close();
} catch (IOException e2)
{
results.setThrowable(e2);
} finally
{
if (interrupted.get(0))
{
results.setInterrupted();
}
results.setOutput(output.toString());
}
// Read from the child process' error stream
// The process may get killed by the watcher at any time
try
{
while (true)
{
if (interrupted.get(0) || lazyQuit)
{
break;
}
// interrupted
c = processError.read();
if (c == -1)
{
break;
}
// end of stream
output.write(c);
if (lazy && (processError.available() < 1))
{
lazyQuit = true;
}
// if lazy and nothing then quit (after at least one read)
}
processError.close();
} catch (IOException e3)
{
results.setThrowable(e3);
} finally
{
if (interrupted.get(0))
{
results.setInterrupted();
}
results.setErrors(errors.toString());
}
// wait for the return value of the child process.
if (!interrupted.get(0) && !lazyQuit)
{
int returnCode = child.waitFor();
results.setReturnCode(returnCode);
if (returnCode != successCode)
{
results.setError(ExecResults.BADRETURNCODE);
}
}
} catch (InterruptedException i)
{
results.setInterrupted();
} catch (Throwable t)
{
results.setThrowable(t);
} finally
{
if (child != null)
{
child.destroy();
}
}
return (results);
}
/**
* Description of the Method
*
* @param command
* Description of the Parameter
* @return Description of the Return Value
*/
public static ExecResults execSimple(String[] command)
{
return (execOptions(command, "", 0, 0, false));
}
/**
* Description of the Method
*
* @param command
* Description of the Parameter
* @return Description of the Return Value
*/
public static ExecResults execSimple(String command)
{
return (execOptions(command, "", 0, 0, false));
}
/**
* Description of the Method
*
* @param command
* Description of the Parameter
* @param args
* Description of the Parameter
* @return Description of the Return Value
*/
public static ExecResults execSimple(String command, String args)
{
return (execOptions(command, args, 0, 0, false));
}
/**
* Description of the Method
*
* @param command
* Description of the Parameter
* @param timeout
* Description of the Parameter
* @return Description of the Return Value
*/
public static ExecResults execTimeout(String command, int timeout)
{
return (execOptions(command, "", 0, timeout, false));
}
/**
* The main program for the Exec class
*
* @param args
* The command line arguments
*/
public static void main(String[] args)
{
ExecResults results;
String sep = System.getProperty("line.separator");
System.out.println("-------------------------------------------" + sep + "TEST 1: execSimple");
results = Exec.execSimple("c:/swarm-2.1.1/bin/whoami.exe");
System.out.println(results);
System.out.println("-------------------------------------------" + sep + "TEST 2: execSimple (with search)");
results = Exec.execSimple("netstat -r");
System.out.println(results);
if (results.outputContains("localhost:1031"))
{
System.out.println("ERROR: listening on 1031");
}
System.out.println("-------------------------------------------" + sep + "TEST 3: execInput");
results = Exec.execInput("find \"cde\"", "abcdefg1\nhijklmnop\nqrstuv\nabcdefg2");
System.out.println(results);
System.out.println("-------------------------------------------" + sep + "TEST 4:execTimeout");
results = Exec.execTimeout("ping -t 127.0.0.1", 5 * 1000);
System.out.println(results);
System.out.println("-------------------------------------------" + sep + "TEST 5:execLazy");
results = Exec.execLazy("ping -t 127.0.0.1");
System.out.println(results);
System.out.println("-------------------------------------------" + sep
+ "TEST 6:ExecTimeout process never outputs");
results = Exec.execTimeout("c:/swarm-2.1.1/bin/sleep.exe 20", 5 * 1000);
System.out.println(results);
System.out.println("-------------------------------------------" + sep
+ "TEST 7:ExecTimeout process waits for input");
results = Exec.execTimeout("c:/swarm-2.1.1/bin/cat", 5 * 1000);
System.out.println(results);
}
}