How to get around Authy's two factor authentication with ../sms

Original author: Egor Homakov
  • Transfer
image

Using simple input ../sms, you could bypass the second factor on sites using 2FA through authy.com ( and there are quite a few of them ).

The most interesting thing is that such an annoying vulnerability appeared not through Authy's fault, and I found this whole chain of bugs with great luck.

So, the process of working with authy is simple and consists of two API calls: api.authy.com/protected/json/sms/AUTHY_ID?api_key=KEY to request a new token and api.authy.com/protected/json/verify/SUPPLIED_TOKEN/ AUTHY_ID? Api_key = KEY to verify the received token from the user. Both calls should return 200 status, then the request is considered successful.

1. It all started with checking their SDK libraries. Everything looked good except authy-node, which did not encode the token before inserting it into the URL at all - this._request ("get", "/ protected / json / verify /" + token + "/" + id, {}, callback, qs );

You could simply insert VALID_TOKEN_FOR_OTHER_AUTHY_ID / OTHER_AUTH_ID # in the token field and rewrite the API request so that it always returned 200 status, which was considered as confirmation of the second step and allowed the attacker to enter the account. The fact is that everything after # is considered a fragment and is not sent to the server, and a request like / protected / json / verify / VALID_TOKEN_FOR_OTHER_AUTHY_ID / OTHER_AUTH_ID will return 200 and it cannot be distinguished from ordinary requests.

2. Then an interesting bug was noticed in authy-python: urllib.quote encoded all the signs except for the slash (I don’t understand why). Hmm, what can be done with the slash? Maybe try to insert /../? As you know, /../, /% 2e% 2e / and even /% 252e% 252e / means "go up one directory" in browsers. But servers are absolutely not required to have such a function. However, I decided to send ../sms for the sake of the test and it worked! I still have no idea why, but now inserting ../sms we turned / verify the call into a / sms call (/verify/../sms/authy_id) which returned 200 and let us into the account.

3. And then I remembered reading Daniel’s interviewon Authy architecture just recently. It said that Authy uses Sinatra, which drags a rack-protection, which, as I recall, had a module called path_traversal.

And here the most interesting - it turned out that for some reason path_traversal decoded path back and killed directories before /../. Well, in theory, this was supposed to protect developers from potential path traversal vulnerabilities. In practice, this has become the reason for such a serious vulnerability.

So, in order:

1. I enter ../sms in the token field

2. The client encodes this as ..% 2fsms and makes a request to api.authy.com/protected/json/verify/..%2fsms/authy_id

3. path_traversal decodes the resulting URL at an early stage inapi.authy.com/protected/json/verify/../sms/authy_id , divides everything by / and removes the / verify

4. directory . Now the application itself gets a modified path api.authy.com/protected/json/sms/authy_id which sends SMS to the victim and returns 200 status and the response {"success": true, "message": "SMS token was sent", "cellphone": "+ 1-XXX-XXX-XX85"}

5. Our client who wanted to check our the token sees 200 status and concludes that the token is correct. Even if a custom implementation of the API is used, the client is most likely looking for success = true, which is also present in our answer.

Simply put by entering ../sms in the token field, you could bypass two factor authentication at all sites using Authy.

There is another wonderful text about a similar vulnerability with circumvention of the first factor through the insertion of the symbol | in another popular 2FA provider Duo Security , but I'm too lazy to translate it.

There was a link that we were looking for hackers, but it was deleted. Please write in a personal email if you find this kind of vulnerability during morning exercises.

Also popular now: