Intruder and CSRF-protected form, without macros
In these days, CSRF tokens are more and more prevalent in Web applications. As a consequence, managing tokens within an intercepting proxy is a very common task for pentesters and bug hunters alike. From what I read online, most users of Burp Suite Pro tend to use Macros and Session handling rules as soon as CSRF tokens are involved, and that may be a pure waste of time and effort. We consider a narrow but common scenario where macros aren’t needed: brute-forcing a CSRF-protected login form via Intruder.
First things first: we need a target. In order to allow readers to follow along at home, I selected an off-the-shelf vulnerable-by-design web app, DVWA (Damn Vulnerable Web Application) running on Docker. The following command 1) downloads the ‘web-dvwa’ container created by ‘vulnerables’ 2) runs it locally under the name ‘dvwa’ 3) accepts TTY interactions, like ^C 4) removes any modifications at shutdown.
$ docker run --rm -it --name dvwa vulnerables/web-dvwa
The output should contain the IP address affected to the container. In doubt, use ‘docker inspect’ to get it:
$ docker inspect dvwa --format="{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}"
Supposing the container uses ‘172.17.0.3’, we verify that the app is reachable:
$ curl -v http://172.17.0.3/
Got a 302 response with a redirect to login.php? All good! Time to finalize the configuration. In a browser going through Burp Suite, access setup.php, don’t mind the frightening red messages, and simply click on the ‘Create / Reset database’ button at the bottom:
After successful completion (and a 5-second delay), you should be redirected to the login page. In order to be closer of a real-life scenario, we consider that we don’t know what the password for user ‘admin’ is (in fact, it’s simply ‘password’). As a consequence, we also consider that we don’t know what the workflow looks like for a successful connection.
- Analyzing unsuccesful attempts
Submit a few invalid credentials (here four) and go to ‘Proxy > HTTP history’ (here sorted in reverse chronological order). Observe the calls for setup.php (grey, #2265 to #2267), then the initial GET request for login.php (green, #2268), followed by a recurring sequence appearing four times (one for each attempt, from #2269 to #2276):
– POST to login.php, with status code 302 and a redirect to itself (blue)
– GET to login.php, with status code 200 and a