Changed XXE lessons to use photo comment example
This commit is contained in:
parent
05f6fb226f
commit
6f0f71b131
@ -6,6 +6,8 @@ import org.apache.commons.lang.exception.ExceptionUtils;
|
|||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
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.beans.factory.annotation.Value;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
@ -51,11 +53,15 @@ import java.util.List;
|
|||||||
* @version $Id: $Id
|
* @version $Id: $Id
|
||||||
* @since November 18, 2016
|
* @since November 18, 2016
|
||||||
*/
|
*/
|
||||||
@AssignmentPath("XXE/blind")
|
@AssignmentPath("xxe/blind")
|
||||||
public class BlindSendFileAssignment extends AssignmentEndpoint {
|
public class BlindSendFileAssignment extends AssignmentEndpoint {
|
||||||
|
|
||||||
@Value("${webgoat.user.directory}")
|
@Value("${webgoat.user.directory}")
|
||||||
private String webGoatHomeDirectory;
|
private String webGoatHomeDirectory;
|
||||||
|
@Autowired
|
||||||
|
private WebSession webSession;
|
||||||
|
@Autowired
|
||||||
|
private Comments comments;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
@ -70,10 +76,11 @@ public class BlindSendFileAssignment extends AssignmentEndpoint {
|
|||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.ALL_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.ALL_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AttackResult createNewUser(@RequestBody String userInfo) throws Exception {
|
public AttackResult createNewUser(@RequestBody String commentStr) throws Exception {
|
||||||
String error = "Parsing successful contents not send to server";
|
String error = "Parsing successful contents not send to server";
|
||||||
try {
|
try {
|
||||||
//parseXml(userInfo);
|
Comment comment = comments.parseXml(commentStr);
|
||||||
|
comments.addComment(comment, false);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
error = ExceptionUtils.getFullStackTrace(e);
|
error = ExceptionUtils.getFullStackTrace(e);
|
||||||
}
|
}
|
||||||
@ -83,9 +90,9 @@ public class BlindSendFileAssignment extends AssignmentEndpoint {
|
|||||||
boolean solved = lines.stream().filter(l -> l.contains("WebGoat 8 rocks...")).findFirst().isPresent();
|
boolean solved = lines.stream().filter(l -> l.contains("WebGoat 8 rocks...")).findFirst().isPresent();
|
||||||
logFile.delete();
|
logFile.delete();
|
||||||
if (solved) {
|
if (solved) {
|
||||||
return success().output("xxe.blind.output").outputArgs(Joiner.on('\n').join(lines)).build();
|
return trackProgress(success().output("xxe.blind.output").outputArgs(Joiner.on('\n').join(lines)).build());
|
||||||
} else {
|
} else {
|
||||||
return failed().output(error).build();
|
return trackProgress(failed().output(error).build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
package org.owasp.webgoat.plugin;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import static org.springframework.web.bind.annotation.RequestMethod.GET;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author nbaars
|
||||||
|
* @since 5/4/17.
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("xxe/comments")
|
||||||
|
public class CommentsEndpoint {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private Comments comments;
|
||||||
|
|
||||||
|
@RequestMapping(method = GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
@ResponseBody
|
||||||
|
public Collection<Comment> retrieveComments() {
|
||||||
|
return comments.getComments();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,14 +1,17 @@
|
|||||||
package org.owasp.webgoat.plugin;
|
package org.owasp.webgoat.plugin;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import org.apache.commons.exec.OS;
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
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.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ************************************************************************************************
|
* ************************************************************************************************
|
||||||
@ -39,37 +42,56 @@ import java.io.IOException;
|
|||||||
* @version $Id: $Id
|
* @version $Id: $Id
|
||||||
* @since November 17, 2016
|
* @since November 17, 2016
|
||||||
*/
|
*/
|
||||||
@AssignmentPath("XXE/content-type")
|
@AssignmentPath("xxe/content-type")
|
||||||
@AssignmentHints({"xxe.hints.content.type.xxe.1", "xxe.hints.content.type.xxe.2"})
|
@AssignmentHints({"xxe.hints.content.type.xxe.1", "xxe.hints.content.type.xxe.2"})
|
||||||
public class ContentTypeAssignment extends AssignmentEndpoint {
|
public class ContentTypeAssignment extends AssignmentEndpoint {
|
||||||
|
|
||||||
|
private final static String[] DEFAULT_LINUX_DIRECTORIES = {"usr", "opt", "var"};
|
||||||
|
private final static String[] DEFAULT_WINDOWS_DIRECTORIES = {"Windows", "Program Files (x86)", "Program Files"};
|
||||||
|
|
||||||
|
|
||||||
|
@Value("${webgoat.server.directory}")
|
||||||
|
private String webGoatHomeDirectory;
|
||||||
|
@Autowired
|
||||||
|
private WebSession webSession;
|
||||||
|
@Autowired
|
||||||
|
private Comments comments;
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.ALL_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.ALL_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AttackResult createNewUser(@RequestBody String userInfo, @RequestHeader("Content-Type") String contentType) throws Exception {
|
public AttackResult createNewUser(@RequestBody String commentStr, @RequestHeader("Content-Type") String contentType) throws Exception {
|
||||||
User user = new User();
|
|
||||||
AttackResult attackResult = failed().build();
|
AttackResult attackResult = failed().build();
|
||||||
if (MediaType.APPLICATION_JSON_VALUE.equals(contentType)) {
|
Comment comment = null;
|
||||||
user = parseJson(userInfo);
|
if (APPLICATION_JSON_VALUE.equals(contentType)) {
|
||||||
|
comment = comments.parseJson(commentStr);
|
||||||
|
comments.addComment(comment, true);
|
||||||
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);
|
String error = "";
|
||||||
attackResult = failed().feedback("xxe.content.type.feedback.xml").build();
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (checkSolution(user)) {
|
|
||||||
// attackResult = success().output("xxe.content.output").outputArgs(user.getUsername()).build();
|
|
||||||
// }
|
|
||||||
return attackResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
private User parseJson(String userInfo) {
|
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
|
||||||
try {
|
try {
|
||||||
return mapper.readValue(userInfo, User.class);
|
comment = comments.parseXml(commentStr);
|
||||||
} catch (IOException e) {
|
comments.addComment(comment, false);
|
||||||
return new User();
|
} catch (Exception e) {
|
||||||
|
error = org.apache.commons.lang.exception.ExceptionUtils.getFullStackTrace(e);
|
||||||
}
|
}
|
||||||
|
attackResult = failed().feedback("xxe.content.type.feedback.xml").output(error).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkSolution(comment)) {
|
||||||
|
attackResult = success().build();
|
||||||
|
}
|
||||||
|
return trackProgress(attackResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkSolution(Comment comment) {
|
||||||
|
String[] directoriesToCheck = OS.isFamilyUnix() ? DEFAULT_LINUX_DIRECTORIES : DEFAULT_WINDOWS_DIRECTORIES;
|
||||||
|
boolean success = true;
|
||||||
|
for (String directory : directoriesToCheck) {
|
||||||
|
success &= comment.getText().contains(directory);
|
||||||
|
}
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ public class Ping extends Endpoint {
|
|||||||
public String logRequest(@RequestHeader("User-Agent") String userAgent, @RequestParam(required = false) String text) {
|
public String logRequest(@RequestHeader("User-Agent") String userAgent, @RequestParam(required = false) String text) {
|
||||||
String logLine = String.format("%s %s %s", "GET", userAgent, text);
|
String logLine = String.format("%s %s %s", "GET", userAgent, text);
|
||||||
log.debug(logLine);
|
log.debug(logLine);
|
||||||
File logFile = new File(webGoatHomeDirectory, "/XXE/log.txt");
|
File logFile = new File(webGoatHomeDirectory, "/XXE/log.tdxt");
|
||||||
try {
|
try {
|
||||||
try (PrintWriter pw = new PrintWriter(logFile)) {
|
try (PrintWriter pw = new PrintWriter(logFile)) {
|
||||||
pw.println(logLine);
|
pw.println(logLine);
|
||||||
|
@ -1,24 +1,20 @@
|
|||||||
package org.owasp.webgoat.plugin;
|
package org.owasp.webgoat.plugin;
|
||||||
|
|
||||||
import org.apache.commons.exec.OS;
|
import org.apache.commons.exec.OS;
|
||||||
|
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
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.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
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.RequestHeader;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import static org.springframework.http.MediaType.ALL_VALUE;
|
import static org.springframework.http.MediaType.ALL_VALUE;
|
||||||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||||
import static org.springframework.web.bind.annotation.RequestMethod.GET;
|
|
||||||
import static org.springframework.web.bind.annotation.RequestMethod.POST;
|
import static org.springframework.web.bind.annotation.RequestMethod.POST;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,35 +61,22 @@ public class SimpleXXE extends AssignmentEndpoint {
|
|||||||
@Value("${webgoat.server.directory}")
|
@Value("${webgoat.server.directory}")
|
||||||
private String webGoatHomeDirectory;
|
private String webGoatHomeDirectory;
|
||||||
@Autowired
|
@Autowired
|
||||||
private WebSession webSession;
|
|
||||||
@Autowired
|
|
||||||
private Comments comments;
|
private Comments comments;
|
||||||
|
|
||||||
@RequestMapping(method = GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
|
||||||
@ResponseBody
|
|
||||||
public Collection<Comment> retrieveComments() {
|
|
||||||
return comments.getComments();
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(method = POST, consumes = ALL_VALUE, produces = APPLICATION_JSON_VALUE)
|
@RequestMapping(method = POST, consumes = ALL_VALUE, produces = APPLICATION_JSON_VALUE)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AttackResult createNewComment(@RequestBody String commentStr, @RequestHeader("Content-Type") String contentType) throws Exception {
|
public AttackResult createNewComment(@RequestBody String commentStr, @RequestHeader("Content-Type") String contentType) throws Exception {
|
||||||
Comment comment = null;
|
String error = "";
|
||||||
if (APPLICATION_JSON_VALUE.equals(contentType)) {
|
try {
|
||||||
comment = comments.parseJson(commentStr);
|
Comment comment = comments.parseXml(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);
|
comments.addComment(comment, false);
|
||||||
}
|
|
||||||
if (checkSolution(comment)) {
|
if (checkSolution(comment)) {
|
||||||
return trackProgress(success()
|
return trackProgress(success().build());
|
||||||
.output("xxe.simple.output")
|
|
||||||
.outputArgs(webSession.getUserName()).build());
|
|
||||||
}
|
}
|
||||||
return trackProgress(failed().build());
|
} catch (Exception e) {
|
||||||
|
error = ExceptionUtils.getFullStackTrace(e);
|
||||||
|
}
|
||||||
|
return trackProgress(failed().output(error).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkSolution(Comment comment) {
|
private boolean checkSolution(Comment comment) {
|
||||||
|
@ -48,13 +48,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="post-footer">
|
<div class="post-footer">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input class="form-control" id="commentInput" placeholder="Add a comment" type="text"/>
|
<input class="form-control" id="commentInputSimple" placeholder="Add a comment" type="text"/>
|
||||||
<span class="input-group-addon">
|
<span class="input-group-addon">
|
||||||
<i id="postComment" class="fa fa-edit" style="font-size: 20px"></i>
|
<i id="postCommentSimple" class="fa fa-edit" style="font-size: 20px"></i>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<ul class="comments-list">
|
<ul class="comments-list">
|
||||||
<div id="comments_list">
|
<div id="commentsListSimple">
|
||||||
</div>
|
</div>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -68,111 +68,112 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="lesson-page-wrapper">
|
<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="adoc-content" th:replace="doc:XXE_changing_content_type.adoc"></div>
|
||||||
<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 -->
|
<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="registerJson" method="POST" name="form"
|
<div class="pull-left image">
|
||||||
action="/WebGoat/XXE/content-type" contentType="application/json">
|
<img th:src="@{/images/avatar1.png}"
|
||||||
<div id="lessonContent">
|
class="img-circle avatar" alt="user profile image"/>
|
||||||
<strong>Registration form</strong>
|
</div>
|
||||||
<form prepareData="registerJson" accept-charset="UNKNOWN" method="POST" name="form" action="#attack/307/100">
|
<div class="pull-left meta">
|
||||||
<table>
|
<div class="title h5">
|
||||||
<tr>
|
<a href="#"><b>John Doe</b></a>
|
||||||
<td>Username</td>
|
uploaded a photo.
|
||||||
<td><input name="username" value="" type="TEXT"/></td>
|
</div>
|
||||||
</tr>
|
<h6 class="text-muted time">24 days ago</h6>
|
||||||
<tr>
|
</div>
|
||||||
<td>E-mail</td>
|
</div>
|
||||||
<td><input name="email" value="" type="TEXT"/></td>
|
|
||||||
</tr>
|
<div class="post-image">
|
||||||
<tr>
|
<img th:src="@{images/cat.jpg}" class="image" alt="image post"/>
|
||||||
<td>Password</td>
|
</div>
|
||||||
<td><input name="email" value="" type="TEXT"/></td>
|
|
||||||
</tr>
|
<div class="post-description">
|
||||||
<tr>
|
|
||||||
<td></td>
|
</div>
|
||||||
<td align="right"><input type="submit" value="Sign up"/></td>
|
<div class="post-footer">
|
||||||
</tr>
|
<div class="input-group">
|
||||||
</table>
|
<input class="form-control" id="commentInputContentType" placeholder="Add a comment" type="text"/>
|
||||||
|
<span class="input-group-addon">
|
||||||
|
<i id="postCommentContentType" class="fa fa-edit" style="font-size: 20px"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<ul class="comments-list">
|
||||||
|
<div id="commentsListContentType">
|
||||||
|
</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>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="lesson-page-wrapper">
|
<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_overflow.adoc"></div>
|
<div class="adoc-content" th:replace="doc:XXE_overflow.adoc"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="lesson-page-wrapper">
|
<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_blind.adoc"></div>
|
<div class="adoc-content" th:replace="doc:XXE_blind.adoc"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="lesson-page-wrapper">
|
<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_blind_assignment.adoc"></div>
|
<div class="adoc-content" th:replace="doc:XXE_blind_assignment.adoc"></div>
|
||||||
<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 -->
|
<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/blind" contentType="application/xml">
|
<img th:src="@{/images/avatar1.png}"
|
||||||
<div id="lessonContent">
|
class="img-circle avatar" alt="user profile image"/>
|
||||||
<strong>Registration form</strong>
|
</div>
|
||||||
<form prepareData="register" accept-charset="UNKNOWN" method="POST" name="form" action="#attack/307/100">
|
<div class="pull-left meta">
|
||||||
<table>
|
<div class="title h5">
|
||||||
<tr>
|
<a href="#"><b>John Doe</b></a>
|
||||||
<td>Username</td>
|
uploaded a photo.
|
||||||
<td><input name="username" value="" type="TEXT"/></td>
|
</div>
|
||||||
</tr>
|
<h6 class="text-muted time">24 days ago</h6>
|
||||||
<tr>
|
</div>
|
||||||
<td>E-mail</td>
|
</div>
|
||||||
<td><input name="email" value="" type="TEXT"/></td>
|
|
||||||
</tr>
|
<div class="post-image">
|
||||||
<tr>
|
<img th:src="@{images/cat.jpg}" class="image" alt="image post"/>
|
||||||
<td>Password</td>
|
</div>
|
||||||
<td><input name="email" value="" type="TEXT"/></td>
|
|
||||||
</tr>
|
<div class="post-description">
|
||||||
<tr>
|
|
||||||
<td></td>
|
</div>
|
||||||
<td align="right"><input type="submit" value="Sign up"/></td>
|
<div class="post-footer">
|
||||||
</tr>
|
<div class="input-group">
|
||||||
</table>
|
<input class="form-control" id="commentInput" placeholder="Add a comment" type="text"/>
|
||||||
|
<span class="input-group-addon">
|
||||||
|
<i id="postCommentBlind" class="fa fa-edit" style="font-size: 20px"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<ul class="comments-list">
|
||||||
|
<div id="commentsListBlind">
|
||||||
|
</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>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="lesson-page-wrapper">
|
<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_mitigation.adoc"></div>
|
<div class="adoc-content" th:replace="doc:XXE_mitigation.adoc"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
BIN
webgoat-lessons/xxe/src/main/resources/images/avatar1.png
Normal file
BIN
webgoat-lessons/xxe/src/main/resources/images/avatar1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
@ -1,22 +1,73 @@
|
|||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$("#postComment").unbind();
|
$("#postCommentSimple").unbind();
|
||||||
$("#postComment").on("click", function () {
|
$("#postCommentSimple").on("click", function () {
|
||||||
var commentInput = $("#commentInput").val();
|
var commentInput = $("#commentInputSimple").val();
|
||||||
|
var xml = '<?xml version="1.0"?>' +
|
||||||
|
'<comment>' +
|
||||||
|
' <text>' + commentInput + '</text>' +
|
||||||
|
'</comment>';
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: 'xxe/simple',
|
url: 'xxe/simple',
|
||||||
data: JSON.stringify({text: commentInput}),
|
data: xml,
|
||||||
contentType: "application/json",
|
contentType: "application/xml",
|
||||||
dataType: 'json'
|
dataType: 'xml',
|
||||||
|
complete: function (data) {
|
||||||
|
$("#commentInputSimple").val('');
|
||||||
|
getComments('#commentsListSimple')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
getComments('#commentsListSimple');
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
$("#postCommentBlind").unbind();
|
||||||
|
$("#postCommentBlind").on("click", function () {
|
||||||
|
var commentInput = $("#commentInput").val();
|
||||||
|
var xml = '<?xml version="1.0"?>' +
|
||||||
|
'<comment>' +
|
||||||
|
' <text>' + commentInput + '</text>' +
|
||||||
|
'</comment>';
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: 'xxe/blind',
|
||||||
|
data: xml,
|
||||||
|
contentType: "application/xml",
|
||||||
|
dataType: 'xml'
|
||||||
}).then(
|
}).then(
|
||||||
function () {
|
function () {
|
||||||
getComments();
|
getComments('#commentsListBlind');
|
||||||
$("#commentInput").val('');
|
$("#commentInput").val('');
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
});
|
||||||
|
getComments('#commentsListBlind');
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
$("#postCommentContentType").unbind();
|
||||||
|
$("#postCommentContentType").on("click", function () {
|
||||||
|
var commentInput = $("#commentInputContentType").val();
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: 'xxe/content-type',
|
||||||
|
data: JSON.stringify({text: commentInput}),
|
||||||
|
contentType: "application/json",
|
||||||
|
dataType: 'xml'
|
||||||
|
}).then(
|
||||||
|
function () {
|
||||||
|
getComments('#commentsListContentType');
|
||||||
|
$("#commentInputContentType").val('');
|
||||||
|
}
|
||||||
|
)
|
||||||
|
});
|
||||||
|
getComments('#commentsListContentType');
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
getComments();
|
getComments();
|
||||||
})
|
});
|
||||||
|
|
||||||
var html = '<li class="comment">' +
|
var html = '<li class="comment">' +
|
||||||
'<div class="pull-left">' +
|
'<div class="pull-left">' +
|
||||||
@ -31,14 +82,14 @@ var html = '<li class="comment">' +
|
|||||||
'</div>' +
|
'</div>' +
|
||||||
'</li>';
|
'</li>';
|
||||||
|
|
||||||
function getComments() {
|
function getComments(field) {
|
||||||
$.get("xxe/simple", function (result, status) {
|
$.get("xxe/comments", function (result, status) {
|
||||||
$("#comments_list").empty();
|
$(field).empty();
|
||||||
for (var i = 0; i < result.length; i++) {
|
for (var i = 0; i < result.length; i++) {
|
||||||
var comment = html.replace('USER', result[i].user);
|
var comment = html.replace('USER', result[i].user);
|
||||||
comment = comment.replace('DATETIME', result[i].dateTime);
|
comment = comment.replace('DATETIME', result[i].dateTime);
|
||||||
comment = comment.replace('COMMENT', result[i].text);
|
comment = comment.replace('COMMENT', result[i].text);
|
||||||
$("#comments_list").append(comment);
|
$(field).append(comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -8,11 +8,11 @@ Our WebGoat server by default has an /xxe/ping endpoint which we can use. *This
|
|||||||
|
|
||||||
[source]
|
[source]
|
||||||
----
|
----
|
||||||
curl -i http://localhost:8080/WebGoat/XXE/ping
|
curl -i http://localhost:8080/WebGoat/XXE/ping?text=HelloWorld
|
||||||
|
|
||||||
will result in:
|
will result in:
|
||||||
|
|
||||||
GET curl/7.45.0
|
GET curl/7.45.0 HelloWorld
|
||||||
----
|
----
|
||||||
|
|
||||||
at the server side.
|
at the server side.
|
||||||
@ -33,12 +33,12 @@ Now submit the form and change the xml to:
|
|||||||
----
|
----
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<!DOCTYPE root [
|
<!DOCTYPE root [
|
||||||
<!ENTITY % remote SYSTEM "http://localhost:8080/WebGoat/plugin_lessons/XXE/attack.dtd">
|
<!ENTITY % remote SYSTEM "http://localhost:8080/WebGoat/XXE/attack.dtd">
|
||||||
%remote;
|
%remote;
|
||||||
]>
|
]>
|
||||||
<user>
|
<comment>
|
||||||
<username>test&ping;</username>
|
<text>test&ping;</text>
|
||||||
</user>
|
</comment>
|
||||||
----
|
----
|
||||||
|
|
||||||
Now if we check our server log we will see:
|
Now if we check our server log we will see:
|
||||||
@ -48,7 +48,8 @@ Now if we check our server log we will see:
|
|||||||
GET Java/1.8.0_101 HelloWorld
|
GET Java/1.8.0_101 HelloWorld
|
||||||
----
|
----
|
||||||
|
|
||||||
So with the XXE we are able to ping our own server which means XXE injection is possible.
|
So with the XXE we are able to ping our own server which means XXE injection is possible. So with the XXE injection
|
||||||
|
we are basically able to reach the same effect as we did in the beginning with the curl command.
|
||||||
|
|
||||||
[NOTE]
|
[NOTE]
|
||||||
In this case we use http://localhost:8080/WebGoat/plugin_lessons/XXE/test.dtd to fetch the dtd but in reality this will
|
In this case we use http://localhost:8080/WebGoat/plugin_lessons/XXE/test.dtd to fetch the dtd but in reality this will
|
||||||
|
Loading…
x
Reference in New Issue
Block a user