callbacks with for loop

When I play some ctf games, usually I need to bruteforcing some interface like post a certain length of string which contains numbers and letters.

Let's say we have a url www.example.com/hack, we need to get the information after post correct token. We already know the token's length is three, containing numbers.

Now we may write payload like this.

var bruteforcing = '0123456789';
var request = require('request');
var url = 'www.example.com/hack';

for (var i = 0; i < bruteforcing.length; i++) {
  for (var j = 0; j < bruteforcing.length; j++) {
    for (var k = 0; k < bruteforcing.length; k++) {
      request.post(url, {form:{ token: i + j + k }}, function (err, res, body) {
        if (body.indexOf('key') !== -1) {
          console.log(i + j + k);
          console.log(body);
        }
      })
    }
  }
}

OK, we have our first magical bruteforcing payload ready. Here's what you think will happen:

  1. in a for loop, post token from 000 to 999
  2. if find the respond body with keywords key, print token and body

However, Node is asynchronous. The request post will return before it even starts the post. It will return back to your for loop. And your for loop will move on to the next file. And the next one.

We have to wait for the callback. When it's called, only then do post our next number token. In other words, we need to call another function inside our callback. And this function needs to start post next number token. Hence, maybe we need a recursive function to do this.

A nice little recursive pattern we can use for this case:

var request = require('request');
var url = 'www.example.com/hack';
function bruteforcing(num) {
    if (num >= 000 && num <= 999) {
        request.post(url, {form:{ token: num }}, function (err, res, body) {
            if (body.indexOf('key') !== -1) {
              console.log(i + j + k);
              console.log(body);
            } else {
                bruteforcing(++num);
            }
        })
    }
}
bruteforcing(000);

In short, the pattern can be this:

repeater(i) {
    if (statement) {
        aysnc(function () {
            repeater(++i)
        })
    }
}

Referemce