Integrated XXE assigment from CTF to XXE lesson
This commit is contained in:
parent
d25f71532b
commit
4a061f61a6
@ -22,8 +22,6 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.owasp.webgoat.plugin.SimpleXXE.parseXml;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ************************************************************************************************
|
* ************************************************************************************************
|
||||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||||
@ -75,7 +73,7 @@ public class BlindSendFileAssignment extends AssignmentEndpoint {
|
|||||||
public AttackResult createNewUser(@RequestBody String userInfo) throws Exception {
|
public AttackResult createNewUser(@RequestBody String userInfo) throws Exception {
|
||||||
String error = "Parsing successful contents not send to server";
|
String error = "Parsing successful contents not send to server";
|
||||||
try {
|
try {
|
||||||
parseXml(userInfo);
|
//parseXml(userInfo);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
error = ExceptionUtils.getFullStackTrace(e);
|
error = ExceptionUtils.getFullStackTrace(e);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package org.owasp.webgoat.plugin;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author nbaars
|
||||||
|
* @since 4/8/17.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@XmlRootElement
|
||||||
|
public class Comment {
|
||||||
|
private String user;
|
||||||
|
private String dateTime;
|
||||||
|
private String text;
|
||||||
|
}
|
@ -0,0 +1,90 @@
|
|||||||
|
package org.owasp.webgoat.plugin;
|
||||||
|
|
||||||
|
import com.beust.jcommander.internal.Lists;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.google.common.collect.EvictingQueue;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
import org.joda.time.format.DateTimeFormat;
|
||||||
|
import org.joda.time.format.DateTimeFormatter;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.xml.bind.JAXBContext;
|
||||||
|
import javax.xml.bind.Unmarshaller;
|
||||||
|
import javax.xml.stream.XMLInputFactory;
|
||||||
|
import javax.xml.stream.XMLStreamReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author nbaars
|
||||||
|
* @since 5/3/17.
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Scope("singleton")
|
||||||
|
public class Comments {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected WebSession webSession;
|
||||||
|
|
||||||
|
protected static DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd, HH:mm:ss");
|
||||||
|
|
||||||
|
private static final Map<String, EvictingQueue<Comment>> userComments = Maps.newHashMap();
|
||||||
|
private static final EvictingQueue<Comment> comments = EvictingQueue.create(100);
|
||||||
|
|
||||||
|
static {
|
||||||
|
comments.add(new Comment("webgoat", DateTime.now().toString(fmt), "Silly cat...."));
|
||||||
|
comments.add(new Comment("guest", DateTime.now().toString(fmt), "I think I will use this picture in one of my projects."));
|
||||||
|
comments.add(new Comment("guest", DateTime.now().toString(fmt), "Lol!! :-)."));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Collection<Comment> getComments() {
|
||||||
|
Collection<Comment> allComments = Lists.newArrayList();
|
||||||
|
Collection<Comment> xmlComments = userComments.get(webSession.getUserName());
|
||||||
|
if (xmlComments != null) {
|
||||||
|
allComments.addAll(xmlComments);
|
||||||
|
}
|
||||||
|
allComments.addAll(comments);
|
||||||
|
return allComments;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Comment parseXml(String xml) throws Exception {
|
||||||
|
JAXBContext jc = JAXBContext.newInstance(Comment.class);
|
||||||
|
|
||||||
|
XMLInputFactory xif = XMLInputFactory.newFactory();
|
||||||
|
xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, true);
|
||||||
|
xif.setProperty(XMLInputFactory.IS_VALIDATING, false);
|
||||||
|
|
||||||
|
xif.setProperty(XMLInputFactory.SUPPORT_DTD, true);
|
||||||
|
XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(xml));
|
||||||
|
|
||||||
|
Unmarshaller unmarshaller = jc.createUnmarshaller();
|
||||||
|
return (Comment) unmarshaller.unmarshal(xsr);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Comment parseJson(String comment) {
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
try {
|
||||||
|
return mapper.readValue(comment, Comment.class);
|
||||||
|
} catch (IOException e) {
|
||||||
|
return new Comment();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addComment(Comment comment, boolean visibleForAllUsers) {
|
||||||
|
comment.setDateTime(DateTime.now().toString(fmt));
|
||||||
|
comment.setUser(webSession.getUserName());
|
||||||
|
if (visibleForAllUsers) {
|
||||||
|
comments.add(comment);
|
||||||
|
} else {
|
||||||
|
EvictingQueue<Comment> comments = userComments.getOrDefault(webSession.getUserName(), EvictingQueue.create(100));
|
||||||
|
comments.add(comment);
|
||||||
|
userComments.put(webSession.getUserName(), comments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,17 +6,10 @@ import org.owasp.webgoat.assignments.AssignmentHints;
|
|||||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
import org.owasp.webgoat.assignments.AssignmentPath;
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.*;
|
||||||
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 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,
|
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||||
@ -60,13 +53,13 @@ public class ContentTypeAssignment extends AssignmentEndpoint {
|
|||||||
attackResult = failed().feedback("xxe.content.type.feedback.json").build();
|
attackResult = failed().feedback("xxe.content.type.feedback.json").build();
|
||||||
}
|
}
|
||||||
if (MediaType.APPLICATION_XML_VALUE.equals(contentType)) {
|
if (MediaType.APPLICATION_XML_VALUE.equals(contentType)) {
|
||||||
user = parseXml(userInfo);
|
// user = parseXml(userInfo);
|
||||||
attackResult = failed().feedback("xxe.content.type.feedback.xml").build();
|
attackResult = failed().feedback("xxe.content.type.feedback.xml").build();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkSolution(user)) {
|
// if (checkSolution(user)) {
|
||||||
attackResult = success().output("xxe.content.output").outputArgs(user.getUsername()).build();
|
// attackResult = success().output("xxe.content.output").outputArgs(user.getUsername()).build();
|
||||||
}
|
// }
|
||||||
return attackResult;
|
return attackResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,17 +5,21 @@ import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
|||||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
import org.owasp.webgoat.assignments.AssignmentPath;
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
|
import org.owasp.webgoat.session.WebSession;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
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.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
import javax.xml.bind.JAXBContext;
|
import java.util.Collection;
|
||||||
import javax.xml.bind.Unmarshaller;
|
|
||||||
import javax.xml.stream.XMLInputFactory;
|
import static org.springframework.http.MediaType.ALL_VALUE;
|
||||||
import javax.xml.stream.XMLStreamReader;
|
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||||
import java.io.StringReader;
|
import static org.springframework.web.bind.annotation.RequestMethod.GET;
|
||||||
|
import static org.springframework.web.bind.annotation.RequestMethod.POST;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ************************************************************************************************
|
* ************************************************************************************************
|
||||||
@ -46,47 +50,58 @@ import java.io.StringReader;
|
|||||||
* @version $Id: $Id
|
* @version $Id: $Id
|
||||||
* @since November 17, 2016
|
* @since November 17, 2016
|
||||||
*/
|
*/
|
||||||
@AssignmentPath("XXE/simple")
|
|
||||||
|
/**
|
||||||
|
* @author nbaars
|
||||||
|
* @since 4/8/17.
|
||||||
|
*/
|
||||||
|
@AssignmentPath("xxe/simple")
|
||||||
@AssignmentHints({"xxe.hints.simple.xxe.1", "xxe.hints.simple.xxe.2", "xxe.hints.simple.xxe.3", "xxe.hints.simple.xxe.4"})
|
@AssignmentHints({"xxe.hints.simple.xxe.1", "xxe.hints.simple.xxe.2", "xxe.hints.simple.xxe.3", "xxe.hints.simple.xxe.4"})
|
||||||
public class SimpleXXE extends AssignmentEndpoint {
|
public class SimpleXXE extends AssignmentEndpoint {
|
||||||
|
|
||||||
private final static String[] DEFAULT_LINUX_DIRECTORIES = {"usr", "opt", "var"};
|
private final static String[] DEFAULT_LINUX_DIRECTORIES = {"usr", "opt", "var"};
|
||||||
private final static String[] DEFAULT_WINDOWS_DIRECTORIES = {"Windows", "Program Files (x86)", "Program Files"};
|
private final static String[] DEFAULT_WINDOWS_DIRECTORIES = {"Windows", "Program Files (x86)", "Program Files"};
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.ALL_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
@Value("${webgoat.server.directory}")
|
||||||
|
private String webGoatHomeDirectory;
|
||||||
|
@Autowired
|
||||||
|
private WebSession webSession;
|
||||||
|
@Autowired
|
||||||
|
private Comments comments;
|
||||||
|
|
||||||
|
@RequestMapping(method = GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AttackResult createNewUser(@RequestBody String userInfo) throws Exception {
|
public Collection<Comment> retrieveComments() {
|
||||||
User user = parseXml(userInfo);
|
return comments.getComments();
|
||||||
if (checkSolution(user)) {
|
}
|
||||||
|
|
||||||
|
@RequestMapping(method = POST, consumes = ALL_VALUE, produces = APPLICATION_JSON_VALUE)
|
||||||
|
@ResponseBody
|
||||||
|
public AttackResult createNewComment(@RequestBody String commentStr, @RequestHeader("Content-Type") String contentType) throws Exception {
|
||||||
|
Comment comment = null;
|
||||||
|
if (APPLICATION_JSON_VALUE.equals(contentType)) {
|
||||||
|
comment = comments.parseJson(commentStr);
|
||||||
|
comments.addComment(comment, true);
|
||||||
|
}
|
||||||
|
if (MediaType.APPLICATION_XML_VALUE.equals(contentType)) {
|
||||||
|
//Do not show these comments to all users
|
||||||
|
comment = comments.parseXml(commentStr);
|
||||||
|
comments.addComment(comment, false);
|
||||||
|
}
|
||||||
|
if (checkSolution(comment)) {
|
||||||
return trackProgress(success()
|
return trackProgress(success()
|
||||||
.output("xxe.simple.output")
|
.output("xxe.simple.output")
|
||||||
.outputArgs(user.getUsername()).build());
|
.outputArgs(webSession.getUserName()).build());
|
||||||
}
|
}
|
||||||
return trackProgress(failed().build());
|
return trackProgress(failed().build());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static User parseXml(String xml) throws Exception {
|
private boolean checkSolution(Comment comment) {
|
||||||
JAXBContext jc = JAXBContext.newInstance(User.class);
|
|
||||||
|
|
||||||
XMLInputFactory xif = XMLInputFactory.newFactory();
|
|
||||||
xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, true);
|
|
||||||
xif.setProperty(XMLInputFactory.IS_VALIDATING, false);
|
|
||||||
|
|
||||||
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;
|
String[] directoriesToCheck = OS.isFamilyUnix() ? DEFAULT_LINUX_DIRECTORIES : DEFAULT_WINDOWS_DIRECTORIES;
|
||||||
boolean success = true;
|
boolean success = true;
|
||||||
for (String directory : directoriesToCheck) {
|
for (String directory : directoriesToCheck) {
|
||||||
success &= userInfo.getUsername().contains(directory);
|
success &= comment.getText().contains(directory);
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
75
webgoat-lessons/xxe/src/main/resources/css/xxe.css
Normal file
75
webgoat-lessons/xxe/src/main/resources/css/xxe.css
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/* Component: Posts */
|
||||||
|
.post .post-heading {
|
||||||
|
height: 95px;
|
||||||
|
padding: 20px 15px;
|
||||||
|
}
|
||||||
|
.post .post-heading .avatar {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
display: block;
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
.post .post-heading .meta .title {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.post .post-heading .meta .title a {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
.post .post-heading .meta .title a:hover {
|
||||||
|
color: #aaaaaa;
|
||||||
|
}
|
||||||
|
.post .post-heading .meta .time {
|
||||||
|
margin-top: 8px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
.post .post-image .image {
|
||||||
|
width:20%;
|
||||||
|
height: 40%;
|
||||||
|
}
|
||||||
|
.post .post-description {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
.post .post-footer {
|
||||||
|
border-top: 1px solid #ddd;
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
.post .post-footer .input-group-addon a {
|
||||||
|
color: #454545;
|
||||||
|
}
|
||||||
|
.post .post-footer .comments-list {
|
||||||
|
padding: 0;
|
||||||
|
margin-top: 20px;
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
.post .post-footer .comments-list .comment {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
.post .post-footer .comments-list .comment .avatar {
|
||||||
|
width: 35px;
|
||||||
|
height: 35px;
|
||||||
|
}
|
||||||
|
.post .post-footer .comments-list .comment .comment-heading {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.post .post-footer .comments-list .comment .comment-heading .user {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
display: inline;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.post .post-footer .comments-list .comment .comment-heading .time {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #aaa;
|
||||||
|
margin-top: 0;
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
.post .post-footer .comments-list .comment .comment-body {
|
||||||
|
margin-left: 50px;
|
||||||
|
}
|
||||||
|
.post .post-footer .comments-list .comment > .comments-list {
|
||||||
|
margin-left: 50px;
|
||||||
|
}
|
@ -1,5 +1,8 @@
|
|||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
|
<script th:src="@{/lesson_js/xxe.js}" language="JavaScript"></script>
|
||||||
|
|
||||||
|
|
||||||
<div class="lesson-page-wrapper">
|
<div class="lesson-page-wrapper">
|
||||||
<!-- reuse this lesson-page-wrapper block for each 'page' of content in your lesson -->
|
<!-- 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,
|
<!-- include content here, or can be placed in another location. Content will be presented via asciidocs files,
|
||||||
@ -15,54 +18,53 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="lesson-page-wrapper">
|
<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>
|
<div class="adoc-content" th:replace="doc:XXE_simple.adoc"></div>
|
||||||
<!-- if including attack, reuse this section, leave classes in place -->
|
<link rel="stylesheet" type="text/css" th:href="@{/lesson_css/xxe.css}"/>
|
||||||
<div class="attack-container">
|
<div class="attack-container">
|
||||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||||
<!-- using attack-form class on your form, will allow your request to be ajaxified and stay within the display framework for webgoat -->
|
|
||||||
<!-- using attack-form class on your form will allow your request to be ajaxified and stay within the display framework for webgoat -->
|
<div class="container-fluid">
|
||||||
<!-- you can write your own custom forms, but standard form submission will take you to your endpoint and outside of the WebGoat framework -->
|
<div class="panel post">
|
||||||
<!-- of course, you can write your own ajax submission /handling in your own javascript if you like -->
|
<div class="post-heading">
|
||||||
<form class="attack-form" accept-charset="UNKNOWN" prepareData="register" method="POST" name="form"
|
<div class="pull-left image">
|
||||||
action="/WebGoat/XXE/simple" contentType="application/xml">
|
<img th:src="@{/images/avatar1.png}"
|
||||||
<script th:src="@{/lesson_js/xxe.js}"
|
class="img-circle avatar" alt="user profile image"/>
|
||||||
language="JavaScript"></script>
|
</div>
|
||||||
<div id="lessonContent">
|
<div class="pull-left meta">
|
||||||
<strong>Registration form</strong>
|
<div class="title h5">
|
||||||
<form prepareData="register" accept-charset="UNKNOWN" method="POST" name="form" action="#attack/307/100">
|
<a href="#"><b>John Doe</b></a>
|
||||||
<table>
|
uploaded a photo.
|
||||||
<tr>
|
</div>
|
||||||
<td>Username</td>
|
<h6 class="text-muted time">24 days ago</h6>
|
||||||
<td><input name="username" value="" type="TEXT"/></td>
|
</div>
|
||||||
</tr>
|
</div>
|
||||||
<tr>
|
|
||||||
<td>E-mail</td>
|
<div class="post-image">
|
||||||
<td><input name="email" value="" type="TEXT"/></td>
|
<img th:src="@{images/cat.jpg}" class="image" alt="image post"/>
|
||||||
</tr>
|
</div>
|
||||||
<tr>
|
|
||||||
<td>Password</td>
|
<div class="post-description">
|
||||||
<td><input name="email" value="" type="TEXT"/></td>
|
|
||||||
</tr>
|
</div>
|
||||||
<tr>
|
<div class="post-footer">
|
||||||
<td></td>
|
<div class="input-group">
|
||||||
<td align="right"><input type="submit" id="registerButton" value="Sign up"/></td>
|
<input class="form-control" id="commentInput" placeholder="Add a comment" type="text"/>
|
||||||
</tr>
|
<span class="input-group-addon">
|
||||||
</table>
|
<i id="postComment" class="fa fa-edit" style="font-size: 20px"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<ul class="comments-list">
|
||||||
|
<div id="comments_list">
|
||||||
|
</div>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
<br/>
|
|
||||||
</form>
|
|
||||||
<div class="attack-feedback"></div>
|
<div class="attack-feedback"></div>
|
||||||
<div class="attack-output"></div>
|
<div class="attack-output"></div>
|
||||||
</div>
|
</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>
|
||||||
|
|
||||||
<div class="lesson-page-wrapper">
|
<div class="lesson-page-wrapper">
|
||||||
@ -77,8 +79,6 @@
|
|||||||
<!-- of course, you can write your own ajax submission /handling in your own javascript if you like -->
|
<!-- 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"
|
<form class="attack-form" accept-charset="UNKNOWN" prepareData="registerJson" method="POST" name="form"
|
||||||
action="/WebGoat/XXE/content-type" contentType="application/json">
|
action="/WebGoat/XXE/content-type" contentType="application/json">
|
||||||
<script th:src="@{/lesson_js/xxe.js}"
|
|
||||||
language="JavaScript"></script>
|
|
||||||
<div id="lessonContent">
|
<div id="lessonContent">
|
||||||
<strong>Registration form</strong>
|
<strong>Registration form</strong>
|
||||||
<form prepareData="registerJson" accept-charset="UNKNOWN" method="POST" name="form" action="#attack/307/100">
|
<form prepareData="registerJson" accept-charset="UNKNOWN" method="POST" name="form" action="#attack/307/100">
|
||||||
@ -137,8 +137,6 @@
|
|||||||
<!-- of course, you can write your own ajax submission /handling in your own javascript if you like -->
|
<!-- 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"
|
<form class="attack-form" accept-charset="UNKNOWN" prepareData="register" method="POST" name="form"
|
||||||
action="/WebGoat/XXE/blind" contentType="application/xml">
|
action="/WebGoat/XXE/blind" contentType="application/xml">
|
||||||
<script th:src="@{/lesson_js/xxe.js}"
|
|
||||||
language="JavaScript"></script>
|
|
||||||
<div id="lessonContent">
|
<div id="lessonContent">
|
||||||
<strong>Registration form</strong>
|
<strong>Registration form</strong>
|
||||||
<form prepareData="register" accept-charset="UNKNOWN" method="POST" name="form" action="#attack/307/100">
|
<form prepareData="register" accept-charset="UNKNOWN" method="POST" name="form" action="#attack/307/100">
|
||||||
|
BIN
webgoat-lessons/xxe/src/main/resources/images/cat.jpg
Normal file
BIN
webgoat-lessons/xxe/src/main/resources/images/cat.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.9 KiB |
@ -1,16 +1,45 @@
|
|||||||
webgoat.customjs.register = function () {
|
$(document).ready(function () {
|
||||||
var xml = '<?xml version="1.0"?>' +
|
$("#postComment").unbind();
|
||||||
'<user>' +
|
$("#postComment").on("click", function () {
|
||||||
' <username>' + 'test' + '</username>' +
|
var commentInput = $("#commentInput").val();
|
||||||
' <password>' + 'test' + '</password>' +
|
$.ajax({
|
||||||
'</user>';
|
type: 'POST',
|
||||||
return xml;
|
url: 'xxe/simple',
|
||||||
|
data: JSON.stringify({text: commentInput}),
|
||||||
|
contentType: "application/json",
|
||||||
|
dataType: 'json'
|
||||||
|
}).then(
|
||||||
|
function () {
|
||||||
|
getComments();
|
||||||
|
$("#commentInput").val('');
|
||||||
}
|
}
|
||||||
webgoat.customjs.registerJson = function () {
|
)
|
||||||
var json;
|
})
|
||||||
json = '{' +
|
getComments();
|
||||||
' "user":' + '"test"' +
|
})
|
||||||
' "password":' + '"test"' +
|
|
||||||
'}';
|
var html = '<li class="comment">' +
|
||||||
return json;
|
'<div class="pull-left">' +
|
||||||
|
'<img class="avatar" src="images/avatar1.png" alt="avatar"/>' +
|
||||||
|
'</div>' +
|
||||||
|
'<div class="comment-body">' +
|
||||||
|
'<div class="comment-heading">' +
|
||||||
|
'<h4 class="user">USER</h4>' +
|
||||||
|
'<h5 class="time">DATETIME</h5>' +
|
||||||
|
'</div>' +
|
||||||
|
'<p>COMMENT</p>' +
|
||||||
|
'</div>' +
|
||||||
|
'</li>';
|
||||||
|
|
||||||
|
function getComments() {
|
||||||
|
$.get("xxe/simple", function (result, status) {
|
||||||
|
$("#comments_list").empty();
|
||||||
|
for (var i = 0; i < result.length; i++) {
|
||||||
|
var comment = html.replace('USER', result[i].user);
|
||||||
|
comment = comment.replace('DATETIME', result[i].dateTime);
|
||||||
|
comment = comment.replace('COMMENT', result[i].text);
|
||||||
|
$("#comments_list").append(comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
== Let's try
|
== Let's 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
|
In this assignment you will add a comment to the photo, when submitting the form try to execute an XXE
|
||||||
username field. Try listing the root directory of the filesystem.
|
injection with the comments field. Try listing the root directory of the filesystem.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user