PortSwigger Labs: Username Enumeration with ZAP Scripts

Posted 618 Words

In this post we will see how to use Zest scripts which are a really powerful and big part of ZAP, and then we will use the Fuzzer for brute-forcing the password of an account.

Note that if you know Burp but are new to ZAP you may wish to checkout the Burp to ZAP Feature Map page now available.

Lab Instructions

This time we will try solve this lab, here’s the description:

This lab is vulnerable to username enumeration. It uses account locking, but this contains a logic flaw. To solve the lab, enumerate a valid username, brute-force this user’s password, then access their account page.

Finding the Username

For enumerating usernames, and finding the one we need, we will use Zest scripts. We will surround the POST request with a File loop and repeat this POST 5 times. If we hit the right username the account will be locked and we can see it in the response body.

  1. We need to open ZAP and launch the Browser with the lab URL and make an attempt to login, we will see in our POST:login()(password, username) in the Sites tree

    Sites Tree

  2. We then need to resend the GET:login2 request to force the system to generate a verification code for Carlos. Sites -> GET:login2 -> right click -> Open/Resend with Request Editor…

  3. Right click on the POST, select Add to Zest Script -> New Zest Script… and choose a name for your script

    Add Zest Script

    This is how the new script should look: Zest Script

  4. Expand the POST, Double Click on Assert - Length… and set the length to 3011, which is the Response body size for an incorrect password or username.

    Edit Assertion

  5. Now we will set the File loop around the POST. Right Click on the POST, select Surround with … -> Loop File. You will need to set a Variable Name (in my case it is “fuzz”) and File Locations with the file in which you saved the usernames.

    Add Zest Loop

  6. Now we need to set this variable name (“fuzz”) in our post, so the script can replace the username in the POST request with our username from the file. To set this variable, double click on our POST and add “{{variable_name}}” after username=

    Edit Zest Request

    Now, If we run our script it will make one request per username from our file. We’ll need to make the same request 5 times.

  7. To do this, we can just copy and paste the POST 4 times (we could also do this in another inner loop)

    Duplicate Requests

  8. Now we can Run our script and we are looking for differences in Size Resp. Body:

    Check body sizes

  9. If we open this request (or also select another request and compare the response bodies) we can see that the response is “You have made too many incorrect attempts. Please try again in 1 minute(s).”

    Diff body

    This indicates to us that this username exists! We can open the response and see our username:

    Manual Request Editor

    In this example, it’s “accounting” but when you try, it will likely be a different one.

Brute-forcing the Password

So now we have a username and all we need to do is brute-force the password of this account with the Fuzzer.

  1. Go back to Sites tree and Right Click on our POST:login()(password, username) select Attack -> Fuzz… and set the username to the one we just found and highlight value for the password:


  2. Add our passwords to Fuzzer, Add… -> Add Select Type: Strings and paste all passwords and click Add

    Add Payload

  3. Click Start Fuzzer

    Start Fuzzer

In the example, it is a super strong password 😉 “1234567” and if we open the response of this request we can see the lab was successfully solved and we are logged in as “accounting”!

Manual Request Editor Result

ZAP rocks! 🤘