Tuesday, May 19, 2015

Cross-Site Request Forgery Detection with Burp and Regex

Cross-Site Request Forgery (CSRF) is an attack where a malicious person tries to force an authenticated user to execute some action. This attack can be caused by a GET or POST request where the server doesn’t validate the request is created by the correct authenticated user. To prevent CSRF, OWASP suggests using CSRF tokens by stating “The ideal solution is to only include the CSRF token in POST requests and have actions with state changing affect to only respond to POST requests. If sensitive server-side actions are guaranteed to only ever respond to POST requests, then there is no need to include the token in GET requests.” During web application penetration tests it is very common for only POST requests to modify state, so my goal is usually to find POST requests which execute a state-changing action and doesn’t have any CSRF protection such as a unique token. It’s very possible that even if CSRF protection is implemented, it’s done so incorrectly or in an incomplete manner. I thought of a nice little trick using Burp search and regular expressions (regex) which I think could be very useful in quickly determining if an application is potentially vulnerable.

Inefficient Detection

Burp Suite Proxy does have CSRF detection as an option in the active scanner engine, however I have found it to be inaccurate at times. Burp also has a ‘Generate CSRF PoC’ function which I do use after my regex search, however in a large application it isn’t realistic to manually look at all POST requests and generate a PoC for each one. A third option is Burp’s pro extension ‘CSRF Scanner’ which almost does what I need, as it lets me passively scan a branch in the site map for requests with a negative match on specific strings (such as unique token names). The biggest downside to this is it does not allow me to specify only a POST request, so I end up with a list of hundreds of requests in the Scanner Results tab.

Efficient Detection with Burp Search and Regex

Burp’s built-in Search is decent but lacking in a lot of areas. It doesn’t let users specify things like type of requests (GET, POST, etc.), ignore duplicate resources, multiple strings in one request, etc. However, Burp’s search does allow us to use regex which means a lot of this functionality we can do and it will help us detect potential CSRF.
Starting with a simple regex search to get an idea of how it works, we see an expression which matches an entire request/response pair:

So let’s create a regex which will help us find potential CSRF. We want a list of all POST requests which don’t have a unique token called ‘CSRF_Token’. To do this we use the regex ^POST((?!CSRF_Token).)*$

Excellent! We now have a comprehensive list of POST requests without a ‘CSRF_Token’ parameter. This will be sufficient for most applications. But what if there are multiple parameters or cookies used to protect against CSRF? Just make a simple modification to the regex and use ^POST((?!CSRF_Token|Cookie: CSRF_Cookie=).)*$. We can add as many keywords to do a negative match against as we want. Just add a pipe ‘|’ character followed by the keyword. To wrap this up here are some quick steps you can do to use this method:

  1. Map out an application by spidering as much of it as you can.
  2. Use Burp’s automated form submission spider option or manually submit forms throughout the application to get as many POST requests in your site map as possible.
  3. Figure out which CSRF defenses are being implemented. Usually I just see one POST parameter as a unique token but sometimes cookies, headers, viewstate, etc. are also used.
  4. Search your target from the sitemap:
  5. Select the regex checkbox and input your desired expression based on step 3. Here is an example format:
  6. Look at the list of requests to confirm they are candidates for CSRF. Find a request with a high impact (ex: Add an administrative user) and use Burp’s ‘Generate CSRF PoC’ function in Engagement tools.
  7. Open and submit the CSRF PoC as the authenticated victim and confirm if the action completed successfully.

Done! Hopefully this post helps you identify potential CSRF candidates. If you have any questions or comments please feel free to share.