Added Vagrant for users and developers

This commit is contained in:
Nanne Baars 2016-09-23 20:45:46 +02:00
parent 5d69467c6f
commit 1033df4d15
6 changed files with 245 additions and 96 deletions

View File

@ -55,7 +55,7 @@ wish to simply try/test/run the current development version of WebGoat
### Prerequisites:
* Java VM 1.8
## Easy Run Instructions:
## Standalone
#### 1. Download the easy run executable jar file which contains all the lessons and a embedded Tomcat server:
@ -73,9 +73,35 @@ Using the `--help` option will show the allowed command line arguments.
#### 3. Browse to the url shown in the console and happy hacking !
## Vagrant
To run WebGoat with Vagrant you must first have Vagrant and Virtualbox installed.
```shell
$ cd WebGoat/webgoat-images/vagrant-users
$ vagrant up
```
Once you see the message 'Browse to http://localhost:9999/WebGoat and happy hacking! you can open a
browser.
# For Developers
## Vagrant
For an easy development experience you can use Vagrant. Note you should have Vagrant and Virtualbox installed on your system.
```shell
$ cd WebGoat/webgoat-images/vagrant-developers
$ vagrant up
```
Once the provisioning is complete login to the Virtualbox with username vagrant and password vagrant.
The source code will be available in the home directory.
## Set up manual
Follow these instructions if you wish to run Webgoat and modify the source code as well.
### Prerequisites:

View File

@ -0,0 +1,57 @@
package org.owasp.webgoat.plugins;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.WebDriverWait;
import static java.util.concurrent.TimeUnit.SECONDS;
/**
* ************************************************************************************************
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
* <p>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
* Getting Source ==============
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
* <p>
*
* @author WebGoat
* @version $Id: $Id
* @since September 22, 2016
*/
public class TestUtils {
public static void assertTitlePresent(WebDriver webDriver, String title) {
FluentWait<WebDriver> wait = new WebDriverWait(webDriver, 15); // wait for a maximum of 15 seconds
wait.until(ExpectedConditions.textToBePresentInElementLocated(By.id("lesson-title"), title));
}
public static FluentWait createDefaultWait(WebDriver webDriver) {
return new FluentWait(webDriver)
.withTimeout(10, SECONDS)
.pollingEvery(2, SECONDS)
.ignoring(NoSuchElementException.class)
.ignoring(StaleElementReferenceException.class);
}
}

View File

@ -14,7 +14,6 @@ import org.junit.runner.RunWith;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.CapabilityType;
@ -29,11 +28,12 @@ import java.net.URL;
import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import static com.github.webdriverextensions.WebDriverExtensionsContext.getDriver;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.owasp.webgoat.plugins.TestUtils.assertTitlePresent;
import static org.owasp.webgoat.plugins.TestUtils.createDefaultWait;
/**
@ -138,10 +138,10 @@ public class WebGoatIT implements SauceOnDemandSessionIdProvider {
browsers.add(new String[]{"Windows 7", "45", "chrome", null, null});
// windows 10, Chrome 46
browsers.add(new String[]{"Windows 10", "46", "chrome", null, null});
//browsers.add(new String[]{"Windows 10", "46", "chrome", null, null});
// windows 10, Firefox 38
browsers.add(new String[]{"Windows 10", "38", "firefox", null, null});
// browsers.add(new String[]{"Windows 10", "38", "firefox", null, null});
// Linux, Firefox 37
browsers.add(new String[]{"Linux", "37", "firefox", null, null});
@ -207,7 +207,7 @@ public class WebGoatIT implements SauceOnDemandSessionIdProvider {
new URL("http://" + authentication.getUsername() + ":" + authentication.getAccessKey() +
"@ondemand.saucelabs.com:80/wd/hub"),
capabilities));
this.getWebDriver().manage().timeouts().implicitlyWait(2, SECONDS);
this.getWebDriver().manage().timeouts().implicitlyWait(4, SECONDS);
this.sessionId.set((((RemoteWebDriver) getWebDriver()).getSessionId()).toString());
String message = String.format("SauceOnDemandSessionID=%1$s job-name=%2$s", this.sessionId, methodName);
@ -283,7 +283,6 @@ public class WebGoatIT implements SauceOnDemandSessionIdProvider {
String pageSource = getWebDriver().getPageSource();
assertTrue("Page source should contain lessons: Test 1", pageSource.contains("Reflected XSS"));
assertTrue("Page source should contain lessons: Test 2", pageSource.contains("Access Control Flaws"));
assertTrue("Page source should contain lessons: Test 34", pageSource.contains("Fail Open Authentication Scheme"));
@ -297,17 +296,12 @@ public class WebGoatIT implements SauceOnDemandSessionIdProvider {
getWebDriver().get(baseWebGoatUrl + "/service/restartlesson.mvc");
getWebDriver().get(baseWebGoatUrl + "/start.mvc#attack/1708534694/200");
FluentWait<WebDriver> wait = new WebDriverWait(getWebDriver(), 15); // wait for a maximum of 15 seconds
FluentWait<WebDriver> wait = createDefaultWait(getWebDriver());
wait.until(ExpectedConditions.textToBePresentInElementLocated(By.id("lesson-title"), "Using an Access Control Matrix"));
wait = new FluentWait(getWebDriver())
.withTimeout(10, SECONDS)
.pollingEvery(2, SECONDS)
.ignoring(NoSuchElementException.class)
.ignoring(StaleElementReferenceException.class);
WebElement user = wait.until(ExpectedConditions.presenceOfElementLocated(By.name("User")));
user.click();
user.sendKeys("Larry");
user.sendKeys("L");
WebElement resource = getWebDriver().findElement(By.name("Resource"));
resource.click();
@ -316,11 +310,6 @@ public class WebGoatIT implements SauceOnDemandSessionIdProvider {
WebElement submit = getWebDriver().findElement(By.name("SUBMIT"));
submit.click();
wait = new FluentWait(getWebDriver())
.withTimeout(10, SECONDS)
.pollingEvery(2, SECONDS)
.ignoring(NoSuchElementException.class);
wait.until(new Predicate<WebDriver>() {
public boolean apply(WebDriver webDriver) {
return webDriver.getPageSource().contains("Congratulations");
@ -336,48 +325,35 @@ public class WebGoatIT implements SauceOnDemandSessionIdProvider {
getWebDriver().get(baseWebGoatUrl + "/service/restartlesson.mvc");
getWebDriver().get(baseWebGoatUrl + "/start.mvc#attack/160587164/200");
FluentWait<WebDriver> wait = new WebDriverWait(getDriver(), 15); // wait for a maximum of 15 seconds
wait.until(ExpectedConditions.textToBePresentInElementLocated(By.id("lesson-title"), "LAB: Role Based Access Control"));
assertTitlePresent(getWebDriver(), "LAB: Role Based Access Control");
this.getWebDriver().manage().timeouts().implicitlyWait(4, SECONDS);
wait = new FluentWait(getDriver())
.withTimeout(10, SECONDS)
.pollingEvery(2, SECONDS)
.ignoring(NoSuchElementException.class)
.ignoring(StaleElementReferenceException.class);
FluentWait<WebDriver> wait = createDefaultWait(getWebDriver());
WebElement user = wait.until(ExpectedConditions.presenceOfElementLocated(By.name("employee_id")));
user.click();
user.sendKeys("T");
WebElement resource = getDriver().findElement(By.name("password"));
WebElement resource = getWebDriver().findElement(By.name("password"));
resource.click();
resource.sendKeys("tom");
WebElement submit = getDriver().findElement(By.name("action"));
WebElement submit = getWebDriver().findElement(By.name("action"));
submit.click();
wait = new FluentWait(getDriver())
.withTimeout(10, SECONDS)
.pollingEvery(2, SECONDS)
.ignoring(NoSuchElementException.class);
wait = createDefaultWait(getWebDriver());
wait.until(new Predicate<WebDriver>() {
public boolean apply(WebDriver webDriver) {
return webDriver.getPageSource().contains("Welcome Back");
}
});
JavascriptExecutor javascript = (JavascriptExecutor) getDriver();
JavascriptExecutor javascript = (JavascriptExecutor) getWebDriver();
String value = "document.getElementsByName('action')[0].value='DeleteProfile';";
javascript.executeScript(value);
WebElement viewProfile = getDriver().findElements(By.name("action")).get(0);
WebElement viewProfile = getWebDriver().findElements(By.name("action")).get(0);
viewProfile.click();
wait = new FluentWait(getDriver())
.withTimeout(40, SECONDS)
.pollingEvery(2, SECONDS)
.ignoring(NoSuchElementException.class);
wait.until(new Predicate<WebDriver>() {
public boolean apply(WebDriver webDriver) {
return webDriver.getPageSource().contains("Stage 2");
@ -387,48 +363,37 @@ public class WebGoatIT implements SauceOnDemandSessionIdProvider {
//
// Stage 3
//
getDriver().get(baseWebGoatUrl + "/start.mvc#attack/160587164/200/3");
getWebDriver().get(baseWebGoatUrl + "/start.mvc#attack/160587164/200/3");
assertTitlePresent(getWebDriver(), "LAB: Role Based Access Control");
user = wait.until(ExpectedConditions.presenceOfElementLocated(By.name("employee_id")));
user.click();
user.sendKeys("T");
resource = getDriver().findElement(By.name("password"));
resource = wait.until(ExpectedConditions.presenceOfElementLocated(By.name("password")));
resource.click();
resource.sendKeys("tom");
submit = getDriver().findElement(By.name("action"));
submit = wait.until(ExpectedConditions.presenceOfElementLocated(By.name("action")));
submit.click();
wait = new FluentWait(getDriver())
.withTimeout(10, SECONDS)
.pollingEvery(2, SECONDS)
.ignoring(NoSuchElementException.class);
wait.until(new Predicate<WebDriver>() {
public boolean apply(WebDriver webDriver) {
return webDriver.getPageSource().contains("Welcome Back");
}
});
javascript = (JavascriptExecutor) getDriver();
javascript = (JavascriptExecutor) getWebDriver();
value = "var select = document.getElementsByName('employee_id')[0]; select.options[0].value='106'; ";
javascript.executeScript(value);
viewProfile = getDriver().findElements(By.name("action")).get(0);
viewProfile = wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.name("action"))).get(0);
viewProfile.click();
wait = new FluentWait(getDriver())
.withTimeout(10, SECONDS)
.pollingEvery(2, SECONDS)
.ignoring(NoSuchElementException.class);
wait.until(new Predicate<WebDriver>() {
public boolean apply(WebDriver webDriver) {
return webDriver.getPageSource().contains("You have completed Stage 3");
return webDriver.getPageSource().contains("Stage 4");
}
});
}
@Test
@ -439,14 +404,9 @@ public class WebGoatIT implements SauceOnDemandSessionIdProvider {
getWebDriver().get(baseWebGoatUrl + "/service/restartlesson.mvc");
getWebDriver().get(baseWebGoatUrl + "/start.mvc#attack/1075773632/200");
FluentWait<WebDriver> wait = new WebDriverWait(getWebDriver(), 15); // wait for a maximum of 15 seconds
FluentWait<WebDriver> wait = createDefaultWait(getWebDriver());
wait.until(ExpectedConditions.textToBePresentInElementLocated(By.id("lesson-title"), "Fail Open Authentication Scheme"));
wait = new FluentWait(getWebDriver())
.withTimeout(10, SECONDS)
.pollingEvery(2, SECONDS)
.ignoring(NoSuchElementException.class)
.ignoring(StaleElementReferenceException.class);
WebElement user = wait.until(ExpectedConditions.presenceOfElementLocated(By.name("Username")));
user.click();
user.sendKeys("Larry");
@ -458,11 +418,6 @@ public class WebGoatIT implements SauceOnDemandSessionIdProvider {
WebElement submit = getWebDriver().findElement(By.name("SUBMIT"));
submit.click();
wait = new FluentWait(getWebDriver())
.withTimeout(10, SECONDS)
.pollingEvery(2, SECONDS)
.ignoring(NoSuchElementException.class);
wait.until(new Predicate<WebDriver>() {
public boolean apply(WebDriver webDriver) {
return webDriver.getPageSource().contains("Congratulations");
@ -478,17 +433,13 @@ public class WebGoatIT implements SauceOnDemandSessionIdProvider {
getWebDriver().get(baseWebGoatUrl + "/service/restartlesson.mvc");
getWebDriver().get(baseWebGoatUrl + "/start.mvc#attack/1537271095/200");
FluentWait<WebDriver> wait = new FluentWait(getWebDriver())
.withTimeout(10, SECONDS)
.pollingEvery(2, SECONDS)
.ignoring(NoSuchElementException.class);
FluentWait<WebDriver> wait = createDefaultWait(getWebDriver());
wait.until(ExpectedConditions.textToBePresentInElementLocated(By.id("lesson-title"), "LAB: SQL Injection"));
assertFalse(getWebDriver().getPageSource().contains("Lesson Plan Title: How to Perform a SQL Injection"));
WebElement user = getWebDriver().findElement(By.id("show-plan-button"));
user.click();
wait = new WebDriverWait(getWebDriver(), 15); // wait for a maximum of 15 seconds
wait.until(ExpectedConditions.textToBePresentInElementLocated(By.id("lesson-plan-content"), "Lesson Plan Title: How to Perform a SQL Injection"));
}
@ -500,7 +451,7 @@ public class WebGoatIT implements SauceOnDemandSessionIdProvider {
getWebDriver().get(baseWebGoatUrl + "/service/restartlesson.mvc");
getWebDriver().get(baseWebGoatUrl + "/start.mvc#attack/1129417221/200");
FluentWait<WebDriver> wait = new WebDriverWait(getWebDriver(), 15); // wait for a maximum of 15 seconds
FluentWait<WebDriver> wait = createDefaultWait(getWebDriver());
wait.until(ExpectedConditions.textToBePresentInElementLocated(By.id("lesson-title"), "Insecure Client Storage"));
getWebDriver().manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
@ -512,10 +463,6 @@ public class WebGoatIT implements SauceOnDemandSessionIdProvider {
WebElement submit = getWebDriver().findElement(By.name("SUBMIT"));
submit.click();
wait = new FluentWait(getWebDriver())
.withTimeout(20, SECONDS)
.pollingEvery(2, SECONDS)
.ignoring(NoSuchElementException.class);
wait.until(new Predicate<WebDriver>() {
@Override
public boolean apply(WebDriver input) {
@ -524,11 +471,6 @@ public class WebGoatIT implements SauceOnDemandSessionIdProvider {
});
//Stage 2
wait = new FluentWait(getWebDriver())
.withTimeout(10, SECONDS)
.pollingEvery(2, SECONDS)
.ignoring(NoSuchElementException.class)
.ignoring(StaleElementReferenceException.class);
WebElement qty = wait.until(ExpectedConditions.presenceOfElementLocated(By.name("QTY1")));
qty.click();
qty.sendKeys("8");
@ -544,7 +486,6 @@ public class WebGoatIT implements SauceOnDemandSessionIdProvider {
getWebDriver().manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
submit = getWebDriver().findElement(By.name("SUBMIT"));
submit.click();
wait = new FluentWait(getWebDriver())
@ -566,13 +507,14 @@ public class WebGoatIT implements SauceOnDemandSessionIdProvider {
getWebDriver().get(baseWebGoatUrl + "/service/restartlesson.mvc");
getWebDriver().get(baseWebGoatUrl + "/start.mvc#attack/1574219258/1700");
FluentWait<WebDriver> wait = new WebDriverWait(getWebDriver(), 15); // wait for a maximum of 15 seconds
FluentWait<WebDriver> wait = createDefaultWait(getWebDriver());
wait.until(ExpectedConditions.textToBePresentInElementLocated(By.id("lesson-title"), "Bypass Client Side JavaScript Validation"));
getWebDriver().manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
for (int i = 1; i <= 7; i++) {
WebElement field = getWebDriver().findElement(By.name("field" + i));
WebElement field = wait.until(ExpectedConditions.presenceOfElementLocated(By.name("field" + i)));
field.click();
field.sendKeys("@#@{@#{");
}
@ -586,11 +528,6 @@ public class WebGoatIT implements SauceOnDemandSessionIdProvider {
getWebDriver().manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
wait = new FluentWait(getWebDriver())
.withTimeout(10, SECONDS)
.pollingEvery(2, SECONDS)
.ignoring(NoSuchElementException.class);
wait.until(new Predicate<WebDriver>() {
public boolean apply(WebDriver webDriver) {
return webDriver.getPageSource().contains("Congratulations");
@ -606,16 +543,20 @@ public class WebGoatIT implements SauceOnDemandSessionIdProvider {
getWebDriver().get(baseWebGoatUrl + "/service/restartlesson.mvc");
getWebDriver().get(baseWebGoatUrl + "/start.mvc#attack/1537271095/200");
FluentWait<WebDriver> wait = new WebDriverWait(getWebDriver(), 15); // wait for a maximum of 15 seconds
FluentWait<WebDriver> wait = createDefaultWait(getWebDriver());
wait.until(ExpectedConditions.textToBePresentInElementLocated(By.id("lesson-title"), "LAB: SQL Injection"));
this.getWebDriver().manage().timeouts().implicitlyWait(4, SECONDS);
WebElement user = getWebDriver().findElement(By.id("show-solution-button"));
WebElement user = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("show-solution-button")));
user.click();
assertTrue(getWebDriver().getPageSource().contains("Could not find the solution file"));
wait.until(new Predicate<WebDriver>() {
public boolean apply(WebDriver webDriver) {
return webDriver.getPageSource().contains("Could not find the solution file");
}
});
}
@Test
public void testLogoutMvc() {

View File

@ -0,0 +1,31 @@
Vagrant.configure(2) do |config|
config.vm.box = "boxcutter/ubuntu1604-desktop"
config.vm.provider "virtualbox" do |vb|
vb.gui = true
vb.memory = "4096"
vb.cpus = 2
vb.name = "WebGoat-Developers"
vb.customize ["modifyvm", :id, "--nictype1", "virtio"]
end
config.ssh.shell = "bash -c 'BASH_ENV=/etc/profile exec bash'"
config.vm.provision 'shell' do |s|
s.path = '../vagrant_provision.sh'
s.privileged = true
end
config.vm.provision :shell, inline: <<-SHELL
echo -e "Cloning the WebGoat container repository"
git clone https://github.com/WebGoat/WebGoat.git
echo -e "Cloning the WebGoat Lessons repository"
git clone https://github.com/WebGoat/WebGoat-Lessons.git
SHELL
config.vm.provision 'shell' do |s|
s.inline = "echo Finished provisioning, login with user vagrant pass vagrant"
end
end

View File

@ -0,0 +1,41 @@
#For now use the same as for developers but start WebGoat
#In the future we can add Docker as well and then Vagrant can start the
#Docker container
Vagrant.configure(2) do |config|
config.vm.box = "boxcutter/ubuntu1604-desktop"
config.vm.network :forwarded_port, guest: 8080, host: 9999
config.vm.provider "virtualbox" do |vb|
vb.gui = false
vb.memory = "4096"
vb.cpus = 2
vb.name = "WebGoat-Users"
vb.customize ["modifyvm", :id, "--nictype1", "virtio"]
end
config.ssh.shell = "bash -c 'BASH_ENV=/etc/profile exec bash'"
config.vm.provision 'shell' do |s|
s.path = '../vagrant_provision.sh'
s.privileged = true
end
config.vm.provision :shell, inline: <<-SHELL
echo -e "Cloning the WebGoat container repository"
git clone https://github.com/WebGoat/WebGoat.git
echo -e "Cloning the WebGoat Lessons repository"
git clone https://github.com/WebGoat/WebGoat-Lessons.git
echo -e "Compiling and installing the WebGoat Container lesson server....."
mvn -q -DskipTests -file WebGoat/pom.xml clean compile install
echo -e "Compiling and installing the WebGoat Lessons $COL_RESET"
mvn -q -DskipTests -file WebGoat-Lessons/pom.xml package
echo -e "Copying the compiled lessons jars into the container so we can start the lesson server with some base lessons"
cp -fa ./WebGoat-Lessons/target/plugins/*.jar ./WebGoat/webgoat-container/src/main/webapp/plugin_lessons/
nohup mvn -q -DskipTests -file WebGoat/pom.xml -pl webgoat-container tomcat7:run-war 0<&- &>/dev/null &
SHELL
config.vm.provision 'shell' do |s|
s.inline = "echo Finished provisioning, open a browser and browse to http://localhost:9999/WebGoat/"
end
end

View File

@ -0,0 +1,53 @@
#!/usr/bin/env bash
set -e
echo "Setting locale..."
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
sudo kill -9 $(lsof -t /var/lib/dpkg/lock) || true
sudo apt-get update
sudo apt-get install -y git
echo "Installing required packages..."
sudo apt-get install -y -q build-essential autotools-dev automake pkg-config expect
## Chrome
wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
sudo sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
sudo apt-get update
sudo apt-get install -y google-chrome-stable
## Java 8
echo "Provisioning Java 8..."
mkdir -p /home/vagrant/java
cd /home/vagrant/java
test -f /tmp/jdk-8-linux-x64.tar.gz || curl -q -L --cookie "oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u101-b13/jdk-8u101-linux-x64.tar.gz -o /tmp/jdk-8-linux-x64.tar.gz
sudo mkdir -p /usr/lib/jvm
sudo tar zxf /tmp/jdk-8-linux-x64.tar.gz -C /usr/lib/jvm
sudo update-alternatives --install "/usr/bin/java" "java" "/usr/lib/jvm/jdk1.8.0_101/bin/java" 1
sudo update-alternatives --install "/usr/bin/javac" "javac" "/usr/lib/jvm/jdk1.8.0_101/bin/javac" 1
sudo update-alternatives --install "/usr/bin/javaws" "javaws" "/usr/lib/jvm/jdk1.8.0_101/bin/javaws" 1
sudo chmod a+x /usr/bin/java
sudo chmod a+x /usr/bin/javac
sudo chmod a+x /usr/bin/javaws
sudo chown -R root:root /usr/lib/jvm/jdk1.8.0_101
echo "export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_101" >> /home/vagrant/.bashrc
## Maven
echo "Installing Maven.."
sudo apt-get install -y maven
## ZAP
echo "Provisioning ZAP..."
cd /home/vagrant
mkdir tools
cd tools
wget https://github.com/zaproxy/zaproxy/releases/download/2.5.0/ZAP_2.5.0_Linux.tar.gz
tar xvfx ZAP_2.5.0_Linux.tar.gz
rm -rf ZAP_2.5.0_Linux.tar.gz