Renamed to lessontemplate

This commit is contained in:
Àngel Ollé Blázquez
2022-07-30 19:51:33 +02:00
parent 26c289d7d4
commit e0a0a80ad9
16 changed files with 13 additions and 13 deletions

View File

@ -0,0 +1,13 @@
--CREATE TABLE servers(
-- id varchar(10),
-- hostname varchar(20),
-- ip varchar(20),
-- mac varchar(20),
-- status varchar(20),
-- description varchar(40)
--);
--INSERT INTO servers VALUES ('1', 'webgoat-dev', '192.168.4.0', 'AA:BB:11:22:CC:DD', 'online', 'Development server');
--INSERT INTO servers VALUES ('2', 'webgoat-tst', '192.168.2.1', 'EE:FF:33:44:AB:CD', 'online', 'Test server');
--INSERT INTO servers VALUES ('3', 'webgoat-acc', '192.168.3.3', 'EF:12:FE:34:AA:CC', 'offline', 'Acceptance server');
--INSERT INTO servers VALUES ('4', 'webgoat-pre-prod', '192.168.6.4', 'EF:12:FE:34:AA:CC', 'offline', 'Pre-production server');
--INSERT INTO servers VALUES ('4', 'webgoat-prd', '104.130.219.202', 'FA:91:EB:82:DC:73', 'out of order', 'Production server');

View File

@ -0,0 +1,111 @@
=== Step 4: Add an assignment to your lesson
With an assignment, a user can practice within a lesson. A lesson can consist of multiple assignments, each assignment
needs to extend the class `AssignmentEndpoint`, let's look at an example:
[source,java]
----
@RestController // <1>
@AssignmentHints({"lesson-template.hints.1", "lesson-template.hints.2", "lesson-template.hints.3"}) // <2>
public class SampleAttack extends AssignmentEndpoint { // <3>
private final String secretValue = "secr37Value";
@Autowired
private UserSessionData userSessionData; // <4>
@PostMapping("/lesson-template/sample-attack") <5>
@ResponseBody
public AttackResult completed(@RequestParam("param1") String param1, @RequestParam("param2") String param2) { <6>
if (userSessionData.getValue("some-value") != null) {
// do any session updating you want here ... or not, just comment/example here
//return failed(this).feedback("lesson-template.sample-attack.failure-2").build();
}
//overly simple example for success. See other existing lesssons for ways to detect 'success' or 'failure'
if (secretValue.equals(param1)) {
return success(this) // <7>
.output("Custom Output ...if you want, for success")
.feedback("lesson-template.sample-attack.success")
.build();
//lesson-template.sample-attack.success is defined in src/main/resources/i18n/WebGoatLabels.properties
}
// else
return failed(this) // <8>
.feedback("lesson-template.sample-attack.failure-2")
.output("Custom output for this failure scenario, usually html that will get rendered directly ... yes, you can self-xss if you want")
.build();
}
----
<1> Every assignment is just a Spring RestController
<2> Each assignment can have a list of hints. The actual text needs to be placed in `WebGoatLabels.properties` in the folder `src/main/resources/{lessonName}/i18n`
<3> Each assignment needs to extend the class `AssignmentEndpoint`, giving you some helpful methods you need when you want to mark an assignment as complete
<4> As the assignment is a Spring-based class, you can auto wire every component managed by Spring necessary for the assignment
<5> Each assignment should at least have one mapping with the method signature (see 6)
<6> When the user tries to solve an assignment, you need return an `AttackResult`
<7> Returning a successful attack result when user solved the lesson
<8> Returning a failed attack user did not solve the lesson
{nbsp} +
As you can see, an assignment is a REST controller which needs to at least have one method with the following signature:
[source]
----
@RequestMapping(method = "...", path = "/lesson-template/solution")
@ResponseBody
public AttackResult solve(String param) {
...
}
----
=== Extra endpoints
Other endpoints can be added in the assignment to support different cases for the assignment, for example:
[source]
----
@GetMapping("lesson-template/shop/{user}")
@ResponseBody
public List<Item> getItemsInBasket(@PathVariable("user") String user) {
return List.of(new Item("WG-1", "WebGoat promo", 12.0), new Item("WG-2", "WebGoat sticker", 0.00));
}
----
=== Adding an assignment to the HTML page
We mentioned a lesson could consist of multiple assignments, WebGoat picks them up automatically, and the UI displays
a navigation bar on top of every lesson. A page with an assignment will be red initially and will become
green when the user solves the assignment. To make this work we need to add to the HTML file:
[source]
----
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:lesson-template-attack.adoc"></div>
<div class="attack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/lesson-template/sample-attack">
<table>
<tr>
<td>two random params</td>
<td>parameter 1:<input name="param1" value="" type="TEXT" /></td>
<td>parameter 2:<input name="param2" value="" type="TEXT" /></td>
<td>
<input name="submit" value="Submit" type="SUBMIT"/>
</td>
</tr>
</table>
</form>
<div class="attack-feedback"></div>
<div class="attack-output"></div>
</div>
</div>
----
So the `action` of the form should match the method which defines the check if the lesson has been solved or not
see `public AttackResult solved()`
That's it. You have now successfully created your first WebGoat lesson, including an assignment!

View File

@ -0,0 +1,36 @@
== Step 1: writing content
Each lesson can consist of multiple pages with content (text) to explain the vulnerability at hand. The content
is written in AsciiDoc[https://asciidoctor.org/docs/asciidoc-writers-guide/] which makes it very easy to write content (if you know Markdown, you know AsciiDoc).
You can find excellent tutorials online for the AsciiDoc syntax. We are just showing a basic overview below.
Below we will describe some constructs often used within WebGoat.
=== Sub-heading
Check AsciiDoc for syntax, but more = means smaller headings. You can *bold* text and other things.
=== Structuring files
You should set up all content to these *.adoc files. The AsciiDoc files reside in the
directory `/src/main/resources/{lesson}/documentation/`.
=== Images
Images can be referenced below, including setting style (recommended to use lesson-image as the style). The root is `/src/main/resources/{lesson}/images`
image::images/firefox-proxy-config.png[Firefox Proxy Config,510,634,style="lesson-image"]
=== Code block
Write code blocks as follows:
```
[source]
----
public class A {
private String test;
}
----
```

View File

@ -0,0 +1,25 @@
=== Database
If the new lesson needs to store or uses a database, you can add a create script in the directory `/src/main/resources/{lesson}/db/migration` folder.
The file name needs to follow a specific convention: `V2019_11_10_1__new-lesson.sql`, so the first part is just the current date.
In this file, you can for example, create tables and insert some data, for example:
[source]
----
CREATE TABLE servers(
id varchar(10),
hostname varchar(20),
ip varchar(20),
mac varchar(20),
status varchar(20),
description varchar(40)
);
INSERT INTO servers VALUES ('1', 'webgoat-dev', '192.168.4.0', 'AA:BB:11:22:CC:DD', 'online', 'Development server');
INSERT INTO servers VALUES ('2', 'webgoat-tst', '192.168.2.1', 'EE:FF:33:44:AB:CD', 'online', 'Test server');
INSERT INTO servers VALUES ('3', 'webgoat-acc', '192.168.3.3', 'EF:12:FE:34:AA:CC', 'offline', 'Acceptance server');
INSERT INTO servers VALUES ('4', 'webgoat-pre-prod', '192.168.6.4', 'EF:12:FE:34:AA:CC', 'offline', 'Pre-production server');
INSERT INTO servers VALUES ('4', 'webgoat-prd', '104.130.219.202', 'FA:91:EB:82:DC:73', 'out of order', 'Production server');
----
Creating a database will automatically allow WebGoat to reset the database to its original state.

View File

@ -0,0 +1,34 @@
=== Step 3: Write glue html page
We mentioned a lesson could consist of multiple assignments, WebGoat picks them up automatically, and the UI displays
a navigation bar on top of every lesson. A page with an assignment will be red initially and will become
green when the user solves the assignment. To make this work we need to add:
[source]
----
<html xmlns:th="http://www.thymeleaf.org">
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:lessons/lessontemplate/documentation/
lesson-template-intro.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:lessons/lessontemplate/documentation/
lesson-template-content.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:lessons/lessontemplate/documentation/
lesson-template-lesson-class.adoc"></div>
</div>
</html>
----
This file needs to be places in: `/src/main/resources/{lesson}/html/`. The name of the file should be the same as
the Java class we created in step 2.
The snippet above will create three separate pages (navigation bar) with the adoc pages we created to create this lesson.
That's it we create a basic lesson with only content. To make it all work, you need to make the lesson available in
WebGoat.
That's it. Start WebGoat, and your lesson will appear in the menu.

View File

@ -0,0 +1,9 @@
This lesson describes the steps needed to add a new lesson to WebGoat. In general, there are four steps:
- Write the content. In WebGoat, we use AsciiDoc as a format.
- Create a lesson class
- Write HTML glue page, so WebGoat knows how to display the content
- Add one or more assignments within the lesson
Let's see how to create a new lesson.

View File

@ -0,0 +1,21 @@
=== Step 2: adding a new lesson class
Each lesson can contain multiple assignments, first. Let's define a lesson class in Java:
[source]
----
@Component
public class LessonTemplate extends Lesson {
@Override
public Category getDefaultCategory() {
return Category.GENERAL;
}
@Override
public String getTitle() {
return "lesson-template.title";
}
}
----
Add the new lesson to a new package under `org.owasp.webgoat.lessons`.

View File

@ -0,0 +1,11 @@
=== Even more content
You can include multiple adoc files in one page, by including them in the same `<div>`:
[source]
----
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:lesson-template-video.adoc"></div>
<div class="adoc-content" th:replace="doc:lesson-template-video-more.adoc"></div>
</div>
----

View File

@ -0,0 +1,7 @@
=== More Content, Video too ...
You can structure and format the content however you like. You can even include video if you like (but may be subject to browser support). You may want to make it more pertinent to web application security than this, though.
video::video/sample-video.m4v[width=480,start=5]
see http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#videos for more detail on video syntax

View File

@ -0,0 +1,77 @@
<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 go in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<div class="adoc-content" th:replace="doc:lessons/lessontemplate/documentation/lesson-template-intro.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<!-- reuse the above 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:lessons/lessontemplate/documentation/lesson-template-content.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<!-- reuse the above 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:lessons/lessontemplate/documentation/lesson-template-video.adoc"></div>
<!-- can use multiple adoc's in a page-wrapper if you want ... or not-->
<div class="adoc-content" th:replace="doc:lessons/lessontemplate/documentation/lesson-template-video-more.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:lessons/lessontemplate/documentation/lesson-template-lesson-class.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:lessons/lessontemplate/documentation/lesson-template-glue.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<!-- reuse the above 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:lessons/lessontemplate/documentation/lesson-template-attack.adoc"></div>
<!-- WebGoat will automatically style and scaffold some functionality by using the div.attack-container as below -->
<div class="attack-container">
<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 -->
<!-- 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 -->
<!-- modify the action to point to the intended endpoint and set other attributes as desired -->
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/lesson-template/sample-attack">
<table>
<tr>
<td>two random params</td>
<td>parameter 1:<input name="param1" value="" type="TEXT" /></td>
<td>parameter 2:<input name="param2" value="" type="TEXT" /></td>
<td>
<input name="submit" value="Submit" type="SUBMIT"/>
</td>
</tr>
</table>
</form>
<!-- do not remove the two following div's, this is where your feedback/output will land -->
<!-- the attack response will include a 'feedback' and that will automatically go here -->
<div class="attack-feedback"></div>
<!-- output is intended to be a simulation of what the screen would display in an attack -->
<div class="attack-output"></div>
</div>
</div>
<!-- repeat and mix-and-match the lesson-page-wrappers with or wihtout the attack-containers as you like ...
see other lessons for other more complex examples -->
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:lessons/lessontemplate/documentation/lesson-template-database.adoc"></div>
</div>
</html>

View File

@ -0,0 +1,11 @@
lesson-template.title=Writing new lesson
lesson-template.hints.1=Hint 1
lesson-template.hints.2=Hint 2
lesson-template.hints.3=Hint 3
lesson-template.sample-attack.failure-1=Sample failure message
lesson-template.sample-attack.failure-2=Sample failure message 2
lesson-template.sample-attack.success=Sample success message

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

View File

@ -0,0 +1,18 @@
// need custom js for this?
webgoat.customjs.idorViewProfile = function(data) {
webgoat.customjs.jquery('#idor-profile').html(
'name:' + data.name + '<br/>'+
'color:' + data.color + '<br/>'+
'size:' + data.size + '<br/>'
);
}
var onViewProfile = function () {
console.warn("on view profile activated")
webgoat.customjs.jquery.ajax({
method: "GET",
url: "/WebGoat/IDOR/profile",
contentType: 'application/json; charset=UTF-8'
}).then(webgoat.customjs.idorViewProfile);
}