May 1, 2019

Vulnerabilities in Web App Account Creation Process

Vulnerabilities in the account creation process can be quite severe and lead to inadvertent access to company resources.

Vulnerabilities in Web App Account Creation Process

Recently on a web app penetration test I came across a vulnerability in the account creation which was interesting.  Account verification, and password reset processes are something that many consultants gloss over in favor of hunting for esoteric XSS that can only be triggered by an authenticated POST request on the third blood moon of the year.  I don't know why.  For real world attacks, these areas are the bread and butter for account takeovers.

As an example:
https://www.theverge.com/2016/3/8/11179926/facebook-account-security-flaw-bug-bounty-payout

Facebook paid 15k for this account reset vulnerability which was not protected by a web application firewall and allowed for password resets via a 6 digit PIN that could be brute forced.

Moving on then, this is the gist of what I found. I have changed the details and in the real vulnerability the code was 2 digits longer which is currently at the edge of any brute force capabilities for GET requests.

The web application grants users access to resources based on the domain of the registering users email address.  For example, [email protected] would be granted access to the companies instance of the cloud services, which would differ from the access that [email protected] has.

How does the web application make sure that you are in fact working for that company? It sends a unique email to the account you specified which must be clicked on before your account is "verified".  The webapp doesn't have any sort of lookup with the companies to see if it is a valid user, and they aren't monitoring an inbox to see if an email is bounced back to the webapp during registration.  The logic can be boiled down to the following statement.  LINK CLICKED = YOU WORK AT COMPANY

Naturally, we could go after a company and do something like password spray users till we can compromise an account and then register it with the site.  That would be successful for most companies that do not deploy MFA on email.  However, that was out of scope on this pentest, and would demonstrate a vulnerability with company1.com and not the web app owners who paid for the test.  Cash Rules Everything Around Me - Wu-Tang.  

The first thing any tester does is find out if there is the ability to register a guest account so that a response can be proxied and analyzed.

After creating an account and checking the inbox, I find something like this:

https://webapp.com/api/v1/register_verify?id=UkVHMjIzNDEyLTA5NjcyMQ%3D%3D

At a glance that looks long enough, but it immediately stood out that it was URL encoded and not just a unique ID. After URL decoding, you get something ending in == which almost always indicates you also need to Base64 decode the text. At the end if the rainbow the id value is equal to

REG223412-096721

At this point my interest was piqued... Next I registered two new accounts at nearly the same time.  I personally use the throwaway service @yopmail.com since signing up for gmail has become a slow process to thwart scammers.  Anyhow, I repeat the process of registering accounts and then URL and Base64 decoding.  I then have the following tokens.

REG223562-793563
REG223563-048921

The big takeaway here is that the whole first section was incremented and thus, attacker controlled.  In practice, we have now reduced the account authorization "code" that looked long and strong:

UkVHMjIzNDEyLTA5NjcyMQ%3D%3D

.....to 6 digits...  Face palm.

It should be pretty apparent how this attack goes down at this point, but in case you were snoozing, it goes as follows.

The attacker registers an account to the email address he/she owns, and within a second registers a second account to [email protected] which the attacker does not control. (Note: If an attacker is worried about someone slipping in a registration between the two attacker requests it would make sense to do the attack during abnormal business hours for the webapp clientele.)

Then the attacker goes and decodes the id code from his/her email account.  The id for the company1.com domain is simply the other number +1, then the 6 digit pin code.

6 digits  = 10^6 = 1,000,000 requests

At this point the attacker just needs to take the known code, increment by 1, and then create a Burp Intruder attack which brute forces 6 digits and then base64 and url encodes the value before putting it in the GET request.

Pseudo code would be:

https://webapp.com/api/v1/register_verify?id=(URL_ENCODE(B64_ENCODE(REG223563-XXXXXX))

The simple payload processing chain in Burp Intruder would be:

Payload processing Burp Intruder

As long as the IP address of the Burp Intruder attack is not being blocked the correct id will be hit in several hours and grant the attacker access to the company resources.

Math on speed: 3 thread attack, 1 request a second per thread = 3 requests per second

1,000,000 requests /5 (requests/second) = 200,000 seconds ~ 55 hours

Of course, there is no reason why you can't do this for many more fake accounts at the same time to get the job done in a couple of hours if you are not worried about getting your IP banned.