XXE first attempt

This commit is contained in:
Nanne Baars 2016-11-17 16:27:41 +01:00
parent 6d45bbc09c
commit f698a2d6ae
14 changed files with 604 additions and 0 deletions

View File

@ -17,6 +17,7 @@
<module>client-side-filtering</module> <module>client-side-filtering</module>
<module>http-basics</module> <module>http-basics</module>
<module>sql-injection</module> <module>sql-injection</module>
<module>xxe</module>
</modules> </modules>
<dependencies> <dependencies>

View File

@ -0,0 +1,36 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>xxe</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>org.owasp.webgoat.lesson</groupId>
<artifactId>webgoat-lessons-parent</artifactId>
<version>8.0-SNAPSHOT</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>1.5.3</version>
<executions>
<execution>
<id>output-html</id>
<phase>generate-resources</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>html</backend>
<sourceDirectory>src/main/resources/plugin/XXE/lessonPlans/en/</sourceDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,83 @@
package org.owasp.webgoat.plugin;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.model.AttackResult;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import java.io.IOException;
import static org.owasp.webgoat.plugin.SimpleXXE.checkSolution;
import static org.owasp.webgoat.plugin.SimpleXXE.parseXml;
/**
* ************************************************************************************************
* 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 nbaars
* @version $Id: $Id
* @since November 17, 2016
*/
public class ContentTypeAssignment extends Assignment {
@Override
public String getPath() {
return "XXE/content-type";
}
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.ALL_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public AttackResult createNewUser(@RequestBody String userInfo, @RequestHeader("Content-Type") String contentType) throws Exception {
User user = new User();
AttackResult attackResult = AttackResult.failed("Try again!");
if (MediaType.APPLICATION_JSON_VALUE.equals(contentType)) {
user = parseJson(userInfo);
attackResult = AttackResult.failed("You are posting JSON which does not work with a XXE");
}
if (MediaType.APPLICATION_XML_VALUE.equals(contentType)) {
user = parseXml(userInfo);
attackResult = AttackResult.failed("You are posting XML but there is no XXE attack performed");
}
if (checkSolution(user)) {
attackResult = AttackResult.success(String.format("Welcome %s", user.getUsername()));
}
return attackResult;
}
private User parseJson(String userInfo) {
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.readValue(userInfo, User.class);
} catch (IOException e) {
return new User();
}
}
}

View File

@ -0,0 +1,89 @@
package org.owasp.webgoat.plugin;
import org.apache.commons.exec.OS;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.model.AttackResult;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import java.io.StringReader;
/**
* ************************************************************************************************
* 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 nbaars
* @version $Id: $Id
* @since November 17, 2016
*/
public class SimpleXXE extends Assignment {
private final static String[] DEFAULT_LINUX_DIRECTORIES = {"usr", "opt", "var"};
private final static String[] DEFAULT_WINDOWS_DIRECTORIES = {"Windows", "Program Files (x86)", "Program Files"};
@Override
public String getPath() {
return "XXE/simple";
}
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.ALL_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public AttackResult createNewUser(@RequestBody String userInfo) throws Exception {
User user = parseXml(userInfo);
if (checkSolution(user)) {
return AttackResult.success(String.format("Welcome %s", user.getUsername()));
}
return AttackResult.failed("Try again!");
}
public static User parseXml(String xml) throws Exception {
JAXBContext jc = JAXBContext.newInstance(User.class);
XMLInputFactory xif = XMLInputFactory.newFactory();
xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, true);
xif.setProperty(XMLInputFactory.SUPPORT_DTD, true);
XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(xml));
Unmarshaller unmarshaller = jc.createUnmarshaller();
return (User) unmarshaller.unmarshal(xsr);
}
public static boolean checkSolution(User userInfo) {
String[] directoriesToCheck = OS.isFamilyUnix() ? DEFAULT_LINUX_DIRECTORIES : DEFAULT_WINDOWS_DIRECTORIES;
boolean success = true;
for (String directory : directoriesToCheck) {
success &= userInfo.getUsername().contains(directory);
}
return success;
}
}

View File

@ -0,0 +1,65 @@
package org.owasp.webgoat.plugin;
import javax.xml.bind.annotation.XmlRootElement;
/**
* ************************************************************************************************
* 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 nbaars
* @version $Id: $Id
* @since November 17, 2016
*/
@XmlRootElement
public class User {
private String username = "";
private String password = "";
private String email = "";
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}

View File

@ -0,0 +1,69 @@
package org.owasp.webgoat.plugin;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.NewLesson;
import java.util.ArrayList;
import java.util.List;
/**
* ************************************************************************************************
* 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 nbaars
* @version $Id: $Id
* @since November 17, 2016
*/
public class XXE extends NewLesson {
@Override
public Category getDefaultCategory() {
return Category.INJECTION;
}
@Override
public List<String> getHints() {
List<String> hints = new ArrayList<String>();
hints.add("Try searching with BOS, SFO or OAK");
hints.add("XXE stands for XML External Entity attack");
hints.add("Look at the search form when you submit");
hints.add("Try to include your own DTD");
return hints;
}
@Override
public Integer getDefaultRanking() {
return 1;
}
@Override
public String getTitle() {
return "XXE";
}
@Override
public String getId() {
return "XXE";
}
}

View File

@ -0,0 +1,69 @@
price,destination,departure date,arrive date,departing from
1223,HNL,12/26/13,01/02/14,SFO
1223,HNL,12/26/13,01/02/14,SFO
1131,SJU,12/26/13,01/02/14,SFO
1175,SJU,12/26/13,01/02/14,SFO
1430,BCN,12/26/13,01/02/14,SFO
1180,FRA,12/26/13,01/02/14,SFO
1683,LIM,12/26/13,01/02/14,SFO
1119,LHR,12/26/13,01/02/14,SFO
858,CUN,12/26/13,01/02/14,SFO
888,SJD,12/26/13,01/02/14,SFO
1223,HNL,12/26/13,01/02/14,OAK
1208,SJU,12/26/13,01/02/14,OAK
1428,FRA,12/26/13,01/02/14,OAK
1864,LIM,12/26/13,01/02/14,OAK
1484,LHR,12/26/13,01/02/14,OAK
977,CUN,12/26/13,01/02/14,OAK
868,SJD,12/26/13,01/02/14,OAK
1394,HNL,12/26/13,01/02/14,BOS
734,SJU,12/26/13,01/02/14,BOS
1299,BCN,12/26/13,01/02/14,BOS
1141,FRA,12/26/13,01/02/14,BOS
944,CUN,12/26/13,01/02/14,BOS
1355,SJD,12/26/13,01/02/14,BOS
595,HNL,01/04/14,01/11/14,SFO
587,SJU,01/04/14,01/11/14,SFO
1385,BCN,01/04/14,01/11/14,SFO
1376,FRA,01/04/14,01/11/14,SFO
1005,LIM,01/04/14,01/11/14,SFO
1396,LHR,01/04/14,01/11/14,SFO
496,CUN,01/04/14,01/11/14,SFO
363,SJD,01/04/14,01/11/14,SFO
563,HNL,01/04/14,01/11/14,OAK
857,SJU,01/04/14,01/11/14,OAK
1743,BCN,01/04/14,01/11/14,OAK
1768,FRA,01/04/14,01/11/14,OAK
1355,LIM,01/04/14,01/11/14,OAK
2039,LHR,01/04/14,01/11/14,OAK
1035,HNL,01/04/14,01/11/14,BOS
533,SJU,01/04/14,01/11/14,BOS
1206,BCN,01/04/14,01/11/14,BOS
1180,LHR,01/04/14,01/11/14,BOS
432,CUN,01/04/14,01/11/14,BOS
612,SJD,01/04/14,01/11/14,BOS
473,HNL,1/09/14,01/17/14,SFO
417,SJU,1/09/14,01/17/14,SFO
864,BCN,1/09/14,01/17/14,SFO
953,LHR,1/09/14,01/17/14,SFO
450,CUN,1/09/14,01/17/14,SFO
363,SJD,1/09/14,01/17/14,SFO
417,HNL,1/09/14,01/17/14,OAK
577,SJU,1/09/14,01/17/14,OAK
993,LIM,1/09/14,01/17/14,OAK
1039,LHR,1/09/14,01/17/14,OAK
460,CUN,1/09/14,01/17/14,OAK
368,SJD,1/09/14,01/17/14,OAK
738,HNL,1/09/14,01/17/14,BOS
309,SJU,1/09/14,01/17/14,BOS
716,BCN,1/09/14,01/17/14,BOS
859,FRA,1/09/14,01/17/14,BOS
1121,LIM,1/09/14,01/17/14,BOS
591,SJD,1/09/14,01/17/14,BOS
422,HNL,01/14/14,01/23/14,SFO
385,SJU,01/14/14,01/23/14,SFO
892,BCN,01/14/14,01/23/14,SFO
956,FRA,01/14/14,01/23/14,SFO
723,LIM,01/14/14,01/23/14,SFO
894,LHR,01/14/14,01/23/14,SFO
397,HNL,01/14/14,01/23/14,OAK

View File

@ -0,0 +1,109 @@
<html xmlns:th="http://www.thymeleaf.org">
<div class="lesson-page-wrapper">
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
<!-- include content here, or can be placed in another location. Content will be presented via asciidocs files,
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<div class="adoc-content" th:replace="doc:XXE_plan.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
<!-- include content here, or can be placed in another location. Content will be presented via asciidocs files,
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<div class="adoc-content" th:replace="doc:XXE_intro.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<!-- reuse this block for each 'page' of content -->
<!-- sample ascii doc content for second page -->
<div class="adoc-content" th:replace="doc:XXE_simple.adoc"></div>
<!-- if including attack, reuse this section, leave classes in place -->
<div class="attack-container">
<!-- using attack-form class on your form will allow your request to be ajaxified and stay within the display framework for webgoat -->
<!-- you can write your own custom forms, but standard form submission will take you to your endpoint and outside of the WebGoat framework -->
<!-- of course, you can write your own ajax submission /handling in your own javascript if you like -->
<form class="attack-form" accept-charset="UNKNOWN" prepareData="register" method="POST" name="form"
action="/WebGoat/XXE/simple" contentType="application/xml">
<script th:src="@{/plugin_lessons/plugin/XXE/js/xxe.js}"
language="JavaScript"></script>
<div id="lessonContent">
<strong>Registration form</strong>
<form prepareData="register" accept-charset="UNKNOWN" method="POST" name="form" action="#attack/307/100">
<table>
<tr>
<td>Username</td>
<td><input name="username" value="" type="TEXT"/></td>
</tr>
<tr>
<td>E-mail</td>
<td><input name="email" value="" type="TEXT"/></td>
</tr>
<tr>
<td>Password</td>
<td><input name="email" value="" type="TEXT"/></td>
</tr>
<tr>
<td></td>
<td align="right"><input type="submit" id="registerButton" value="Sign up"/></td>
</tr>
</table>
<br/>
<strong>By signing up you agree to WebGoat's Terms of Service.</strong>
<br/>
</form>
</div>
</form>
<div id='registration_success'></div>
</div>
<!-- do not remove the two following div's, this is where your feedback/output will land -->
<div class="attack-feedback"></div>
<div class="attack-output"></div>
<!-- ... of course, you can move them if you want to, but that will not look consistent to other lessons -->
</div>
<div class="lesson-page-wrapper">
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
<!-- include content here, or can be placed in another location. Content will be presented via asciidocs files,
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<div class="adoc-content" th:replace="doc:XXE_changing_content_type.adoc"></div>
<div class="attack-container">
<!-- using attack-form class on your form will allow your request to be ajaxified and stay within the display framework for webgoat -->
<!-- you can write your own custom forms, but standard form submission will take you to your endpoint and outside of the WebGoat framework -->
<!-- of course, you can write your own ajax submission /handling in your own javascript if you like -->
<form class="attack-form" accept-charset="UNKNOWN" prepareData="registerJson" method="POST" name="form"
action="/WebGoat/XXE/content-type" contentType="application/json">
<script th:src="@{/plugin_lessons/plugin/XXE/js/xxe.js}"
language="JavaScript"></script>
<div id="lessonContent">
<strong>Registration form</strong>
<form prepareData="registerJson" accept-charset="UNKNOWN" method="POST" name="form" action="#attack/307/100">
<table>
<tr>
<td>Username</td>
<td><input name="username" value="" type="TEXT"/></td>
</tr>
<tr>
<td>E-mail</td>
<td><input name="email" value="" type="TEXT"/></td>
</tr>
<tr>
<td>Password</td>
<td><input name="email" value="" type="TEXT"/></td>
</tr>
<tr>
<td></td>
<td align="right"><input type="submit" value="Sign up"/></td>
</tr>
</table>
<br/>
<strong>By signing up you agree to WebGoat's Terms of Service.</strong>
<br/>
</form>
</div>
</form>
</div>
</div>
</html>

View File

@ -0,0 +1,15 @@
webgoat.customjs.register = function () {
var xml = '<?xml version="1.0"?>' +
'<user>' +
' <username>' + 'test' + '</username>' +
' <password>' + 'test' + '</password>' +
'</user>';
return xml;
}
webgoat.customjs.registerJson = function () {
var json = '{' +
' "user":' + '"test"' +
' "password":' + '"test"' +
'}';
return json;
}

View File

@ -0,0 +1,4 @@
== Modern REST framework
Again same exercise but try to enforce the same XML injection as we did in first lesson.

View File

@ -0,0 +1,34 @@
=== What is a XML entity?
An XML Entity allows tags to be defined that will be replaced by content when the XML Document is parsed.
In general there are three types of entities:
* internal entities
* external entities
* parameter entities.
An entity must be created in the Document Type Definition (DTD), let's start with an example:
[source]
----
<?xml version="1.0" standalone="yes" ?>
<!DOCTYPE author [
<!ELEMENT author (#PCDATA)>
<!ENTITY js "Jo Smith">
]>
<author>&js;</author>
----
So everywhere you use the entity ``&js;` the parser will replace it with the value defined in the entity.
=== What is an XXE injection?
An XML External Entity attack is a type of attack against an application that parses XML input. This attack occurs when XML input containing a
reference to an external entity is processed by a weakly configured XML parser. This attack may lead to the disclosure of confidential data,
denial of service, server side request forgery, port scanning from the perspective of the machine where the parser is located, and other system impacts.
Attacks can include disclosing local files, which may contain sensitive data such as passwords or private user data, using file: schemes or relative
paths in the system identifier. Since the attack occurs relative to the application processing the XML document, an attacker may use this
trusted application to pivot to other internal systems, possibly disclosing other internal content via http(s) requests or launching a CSRF attack to
any unprotected internal services. In some situations, an XML processor library that is vulnerable to client-side memory corruption issues
may be exploited by dereferencing a malicious URI, possibly allowing arbitrary code execution under the application account. Other attacks can access
local resources that may not stop returning data, possibly impacting application availability if too many threads or processes are not released.

View File

@ -0,0 +1,11 @@
= XML External Entity (XXE) Processing
== Concept
This lesson teaches how to perform a XML External Entity attack is and how it can be abused and protected against.
== Goals
* The user should have basic knowledge of XML
* The user will understand how XML parsers work
* The user will learn to perform a XXE attack and how to protected against it.

View File

@ -0,0 +1,4 @@
== Let't try
In this assignment you will need to sign up with a registration form. When submitting the form try to execute an XXE injection with the
username field. Try listing the root directory of the filesystem.

View File

@ -0,0 +1,15 @@
- Describe how the attack works / should be some outpu
<p><b>Concept / Topic To Teach:</b> </p>
This lesson teaches how to perform XML External Entity Attacks.
<br>
<div align="Left">
<p>
<b>How the attacks works:</b>
</p>
An XML External Entity attack is a type of attack against an application that parses XML input.
This attack occurs when XML input containing a reference to an external entity is processed by a weakly
configured XML parser. This attack may lead to the disclosure of confidential data, denial of service,
server side request forgery, port scanning from the perspective of the machine where the parser is located, and other system impacts.