Web App assessments are probably one of the most popular penetration tests performed today. These are so popular that public bug bounty sites such as Hacker One and Bug Crowd offer hundreds of programs for companies wanting to fix vulnerabilities such as XSS, SQL Injection, CSRF, etc. Many companies also host their own bounty programs for reporting web vulnerabilities to a security team. Follow us in our 4-part mini series of blog posts about web security:

In a continuation of our portal protections series, we’re going to walk through an “obscured” vulnerability we discovered that gave us super admin privileges to the application we were testing.

From Wikipedia:

“security through obscurity (or security by obscurity) is the reliance on the secrecy of the design or implementation as the main method of providing security for a system or component of a system. A system or component relying on obscurity may have theoretical or actual security vulnerabilities, but its owners or designers believe that if the flaws are not known, that will be sufficient to prevent a successful attack.”

The application containing this vulnerability allows a company administrator to edit users in their company, but does not allow them to edit the site admin “superusers” or other company’s users.

Our company admin user account can only see 10 accounts when accessing the “User Management -> User Profiles” page. All accounts outside of the company are hidden from the user

When we want to edit a user, we can click on their entry in the user’s table above and the application visits the page path: “/Admin/UserEdit.aspx?ContactId=<someid>”. Here we show the user accessing the silentadmin user’s profile page using a contactId of 5J37580Km66K015. I wonder where this “contactId” is coming from, is it really as randomly generated as it appears to be?

The ContactId for each user can be made visible by deleting the HTML style directive “display:none” from the page’s HTML . The EncryptedId is the ContactId used to access the user’s profile page.

Three separate page loads on the user view were performed and the resulting EncryptedId field values were compared in order to determine if the encryption code could be identified. The encryption scheme was found to use 15 characters: The first five and last five were the same for every user each time the page was loaded, but the middle 5 characters appeared to be tied specifically to the user’s account and never varied.  This is exciting because it’s much more possible to guess 5 characters than it is to guess 15, but that still left the issue of determining how the application was generating/using the extra 10 characters in our EncryptedId field to identify each user.

On the hunch that perhaps it didn’t really matter what the first and last 5 characters were, we tried accessing a user’s account with zeros as the first and last 5 characters in the contactId.  The application dutifully loaded the user’s profile page and was ready for editing!

We quickly created 1,000 test accounts in order to determine if there was a pattern or sequence to the “encryptedId” character positions assigned to each user. A quick analysis on the resulting encryptedId strings was performed and it was determined that only specific character sets were being used in generating the characters in each of the 5 important character locations (characters 6 through 10). The following result sets were identified in each of these positions:

6 set([‘l’, ‘3’, ‘5’, ‘4’, ‘7’, ‘6’, ‘8’])

7 set([‘K’, ‘M’, ‘L’, ‘1’, ‘0’, ‘3’, ‘2’, ‘5’, ‘4’, ‘6’])

8 set([‘I’, ‘H’, ‘K’, ‘J’, ‘M’, ‘L’, ‘1’, ‘0’, ‘3’, ‘2’])

9 set([‘m’, ‘l’, ‘3’, ‘2’, ‘5’, ‘4’, ‘7’, ‘6’, ‘9’, ‘8’])

10 set([‘m’, ‘l’, ‘o’, ‘n’, ‘p’, ‘5’, ‘7’, ‘6’, ‘9’, ‘8’])

Burp Intruder was given a specialized payload where each position contained the identified characters and a brute-force guessing attack was performed to see if any EncryptedId strings could be guessed for user accounts not normally visible to the requesting user. Nearly 100,000 character combinations were tested, and several site administrator accounts were identified as being accessible and editable.

After conducting our brute-force contactId guessing attack, 20 previously “inaccessible” accounts were identified as being editable by our company administrator

The site’s ASP Administrator account was accessible for editing by our test account using the discovered contactId character sequence. This meant that we could switch their email address and then submit a password reset request that would be sent to us so that we could gain full login access to the new account.

This is a classic example of “security through obscurity” that did not prevent the vulnerability from being discovered and exploited.  A 15 character sequence containing truly random letter/number combinations would contain 120,932,352 possible combinations if using only lowercase a-z and 0-9, but our digging revealed that the limited randomization of the 5 significant characters only contained 140,000 possible combinations and was able to be brute-forced in just a few hours.  This also serves as a good example of why you should never write your own encryption algorithms.