I have decided to re-write this intro, because I was recently informed that this attack narrative was confusing at best. This blog post will be talking heavily about the Anti-CSRF protections that web applications use, but the steps included are not meant to be used for a CSRF attack. This is meant to be used when testing input points for possible injection vulnerabilities. For example, a tester might need to test the login page for potential SQL injection, but automated tools might have trouble due to the Anti-CSRF protections.
So, what is Cross-Site Request Forgery (CSRF)? CSRF is an attack that forces an end user to execute unwanted actions on a web application in which they're currently authenticated. CSRF attacks specifically target state-changing requests, not theft of data, since the attacker has no way to see the response to the forged request. With a little help of social engineering (such as sending a link via email or chat), an attacker may trick the users of a web application into executing actions of the attacker's choosing. If the victim is a normal user, a successful CSRF attack can force the user to perform state changing requests like transferring funds, changing their email address, and so forth. If the victim is an administrative account, CSRF can compromise the entire web application.

There are several methods being used to protect web application attacks, the most common method is using Anti-CSRF Tokens. During web application penetration tests, CSRF can often be used correctly and might deter security testers from properly testing injection points. Popular tools such as SQLmap have built in CSRF bypass methods, but recently I found an issue where it wasn't reading the CSRF token from within the body of the response. Therefore, with the help of others I was able to learn how to use Burp Suite to properly bypass these Anti-CSRF protections.
To begin I am using the Vulnerable Web Application Test Environment that was blogged about in 2018. Specifically I will be using the Damn Vulnerable Web App, or more commonly referred to as DVWA , to demonstrate this anti-CSRF bypass. As you can see from the screenshot below, this is our baseline request when submitting a password reset when authenticated to the DVWA.

In the request above you can note from one of the cookies that the security is currently set to Impossible. Inside the DVWA you can change the difficult rating in order to attempt different exploits against web applications. For this post I will be using either the Impossible or High. Which both have Anti-CSRF tokens generated. The screenshot below is the response from the web server when submitting the password reset. Unfortunately, at the impossible security level you are required to submit the current password as well. In order to see if we can get a successful response, we will lower the security rating to High so we will not need the previous password.

In the screenshot below you will see that SQLmap is being used to test a parameter. The -r
option allows for the user to pass a Burp Request that has been saved to the file system without having to specify multiple flags. Also, it appears that SQLmap has recognized the user_token
parameter and asks if we want to use CSRF bypass methods. Even though this method could be used in the instance of DVWA, for this blog post I will not be using the SQLmap CSRF bypass method.

Not every web application penetration test will allow the engineer to have full insight into what his happening, but luckily for us the DVWA gives the option at looking at the source code. Which we can see from the screenshot below at the bottom the final line will generateSessionToken()
. This will generate an Anti-CSRF token which will then be passed in the response. The web server will then expect that exact session token upon the next request.

Even though we do not need to know how the CSRF token is being generated it is a good idea to review the function that is being called. Or we might be able to just create our own unique CSRF token that would be valid.

One of the more advanced features of Burp Suite is the ability to create macros that will trigger based on specific requests and responses. For the purpose of this blog I will be walking through the steps I use to bypass anti-CSRFtokens located within the body of a web application.
Additionally, it should be noted that these screenshots were taken while using the Burp Suite community edition which is free to use. Looking at the screenshot below we will begin by navigating to the Project Options
tab and then into Sessions
.

From here Burp Suite defines what Session Handling rules are, and gives some options for how the rules operate. Such as, adding, editing, or if you need a particular to execute before another. For this blog post we will be clicking Add
to create a new session handling rule.

Burp Suite will open a new menu called the Session handling rule editor
. This allows you to define the description and different rule actions that need to be taken. Once we have added a description, we can click the Add
button to specify a new rule.

Burp Suite will drop down a menu with different rule actions that can be taken. For example, if you need to use a cookie that is already located in Burp's cookie jar you could utilize that here. Or you could perform a check on every request to check and make sure the session is valid. Since these rule actions could be an entire blog post in itself, we will focus solely on Run a macro
for this use case.

Again, Burp Suite opens another menu which is the Session handling action editor
followed by the name we provided in the menu above. Here we can Add or Edit existing macros. If you wanted to define a macro that could be used across all web applications being tested you could simply choose that one here. However, since we are using a fresh copy of Burp Suite's community edition, we will select the Add
button.

Burp Suite will open yet another two windows (For those keeping track, that is four windows not including the main application). The window that should be at the top layer at this point is the Macro Recorder
. This menu gives you the option to pick out previous requests from the Proxy history tab and specify which requests will be triggering the macro. For the instance of this blog we will be sending a POST request to the DVWA application, and specifically targeting the user_token
. We will select two subsequent requests for our Macro Recorder. The first is the initial request to the page which will request a user_token
and then the second will be to send the password change request using the previous response. The second request will be removed, but for testing we will need to make sure we get a 200 response.

As you can see in the screenshot above the user_token
is located within the body of the HTML in a hidden input type. Once we select the two requests from Burp Suite's Macro Recorder we will get another window that will allow us to fine tune the Custom Parameters
. By highlighting the exact token value we need, Burp Suite will automatically generate a regex end delimiter. You can leave the pre-generated regex that Burp Suite defines. Or you could just enter a single '
in the End at delimiter field. This will tell Burp where our token starts and stops for every response.

In the screenshot below you will see that the Parameter handling
section will ask us what we want to do with the data that we have captured in our macro. For example, we will want to leave the preset values for the password_new
and password_conf
that way any data that is passed in will not be changed. The section that needs to be changed is the user_token
and we want to use the data from Response 1
. Ignore the section about Change
because that value should never change. It is in fact a variable telling the backend what action to take.

In the screenshot below we are setting the Scope
tab's parameters. This can be important by defining exactly which tools Burp Suite will trigger these macros for. For example, the Proxy
option is not checked by default, but if we are planning to use Burp Suite in tandem with SQLMap, we will need to make sure that box is checked.

Burp Suite also provides a very helpful tool known as the Sessions Tracer
. This will help track if the macros that were created above are being processed correctly and what the final request will look like. This is very helpful as it keeps you from having to spend a significant amount of time debugging your macros with the repeater or intercept tool.

Once you open the sessions tracer you will can try changing another password in the DVWA web UI. Once you submit the requests should show in the session tracer. The request actively being view will be highlighted in orange shown in the top half of the screenshot below. The bottom half of the screenshot is the Events
section. Which is where the actual debug events are. As you can see working form the top to the bottom Burp is triggering the Test CSRF
session handling rule we have created. Once that rule triggers, Burp knows to run Macro #5 (It is #5 because I messed up 4 Macros before that). Highlighted in yellow is the Macro request which shows that on the next line will process the item with the full URL including parameters. Then in green is the new values that will be used for the parameter user_token
. Finally, it will issue the macro request. The final line which is also highlighted yellow shows that the password change request we have left in for testing was issued. We can inspect the response from the POST request to see if the password change was submitted correctly using the updated user_token
.


Once our debugging is finished, we will remove the second request or Burp Suite will attempt to send two password resets every time we try to test the input field. Now we can move back to SQLmap and use the same request as before, and send it through the proxy for further testing. As you can see in the screenshot below SQLmap again recognizes the user_token
parameter and asks if we want to use anti-CSRF bypass methods. However, since we are using Burp Suite to do the macro processing, we will simply say no.

Finally, we can inspect our Burp Suite HTTP history to see that the requests are successfully being exchanged based on the prior request and response.

Now we can further test our input fields knowing that Burp Suite will handle any anti-CSRF protections the web application will throw at us. There are further fine tuning that can be done with Burp Suite to make sure the macros only execute on the exact requests, but that will be for another time. Until next time keep on side-skirting common security protections!
Credits and Inspiration:
- https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project
- https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)
- https://www.acunetix.com/wp-content/uploads/2013/04/csrf.png
- https://www.owasp.org/index.php/Anti_CSRF_Tokens_ASP.NET
- https://jsblog.insiderattack.net/anti-csrf-tokens-to-prevent-cross-site-request-forgery-csrf-79b9d7a5c079
- http://www.dvwa.co.uk/