Trustwave's 2024 Retail Report Series Highlights Alarming E-Commerce Threats and Growing Fraud Against Retailers. Learn More
Get access to immediate incident response assistance.
Get access to immediate incident response assistance.
Trustwave's 2024 Retail Report Series Highlights Alarming E-Commerce Threats and Growing Fraud Against Retailers. Learn More
I've been pentesting applications for nearly two decades now and throughout that time you get to see trends. One of these is the gradual adoption of Single Sign-On (SSO) in the corporate environment for lots of previously isolated applications. These applications would usually have their own user database and the users (the employees) would need to authenticate directly to them with specific 'local' credentials. With this setup comes varying password expiry times, complexity requirements, etc. Multiply this by lots of applications and you suddenly get into a bit of an unworkable mess credential management wise. SSO fixes this problem, allowing the users to authenticate using one set of credentials.
In an attempt to keep up, a lot of these older applications get retrofitted/upgraded with the approach of mapping against domain usernames (used as part of the SSO to authenticate) or newer applications specifically designed to only ever support SSO also via the mapping of domain usernames in this way.
I won't go into the specifics of the SSO authentication in this setup/story/adventure I'm about to go into but I will just say it is done via the 'Authorization' header in each HTTP request and uses a Bearer token with a signature, so we're not able to just simply replace the username at this level for account take over and clock off early. Oh no, not today! Grab a seat.
In this example, the SSO has taken care of the authentication but it is the application which still holds the keys (and the logic) with regards to the authorisation. It is between these two things (chilling out at different places) where we pitch up our tent and abuse the trust.
Let me set the scene for you. Beautiful blue sky, fluffy clouds, tones of bird song in the air - think Windows XP background. That's outside. You’re inside (because pentester life...), today you're the admin user of a sandboxed application, AdminLand. Lots of applications exist on this server which you don't have access to. We know nothing about the other applications but we know of their existence and that we're in a sandbox on the server.
People log into this application through SSO, using their domain account to authenticate, via goodness in the 'Authorization' header already mentioned.
In AdminLand, users can log in and 'user', admins can log in and 'admin', just a normal day.
As an admin, we can add new users to the application, by providing the user's domain account username and assigning them one of two roles from a drop-down menu: 'user' or 'admin'.
All looks well. That is, until we stumble upon something while looking through the JavaScript code.
randomjavascriptcode.js:
...
assigned_role: "adminplusplus",
...
With this knowledge, we put our black hacker hoody on whilst simultaneously jumping to the ‘edit’ user functionality within the application with the speed resembling that out of a Tom & Jerry scene.
We immediately select our own user, click ‘edit’, change the role from ‘admin’ to 'user’ using the drop-down menu (to trigger enabling the 'save' button), click ‘save’, intercept the underlying HTTP POST request (using Burp) and change the ‘assigned_role’ parameter from ‘user’ to ‘adminplusplus’ and send the modified request on its way. However, a problem - an "Access Denied" message is returned. Perhaps there is some logic to stop us from doing it on our own user? Perhaps the application will allow us to edit another user? The problem with the latter is that because of SSO we would need to know their domain account password to then log in as them.
It then dawned on me that perhaps this system maps users to those already created in another system, that it maps the usernames over and that the passwords are dealt with elsewhere. This is the introduction or pretext I gave at the start. For the purposes of this story I am able to change the ordering (to give further context to you, the lovely reader), but obviously I didn't know this right away until I started exploring the application a little bit. As pentesters we don't always get to know or see the full architecture/inner workings of an application until we come to play with it.
So, we have a little bit of a problem. We are currently being trolled by a JavaScript file alerting us to the fact that a super admin role (‘adminplusplus’) possibly exists, that's great news, however, we can't edit our own user to assign the role (because of the “Access Denied” message). We also can't add or edit other users with this role as we'd need to then know their domain account password to log in as them as previously mentioned.
I theorised something, a little crazy, but it may just work. I wonder, could I abuse the logic here and re-use my own account mapping? That rubbish bin icon next to my username allowing me to delete my own user account, looking like it is waving my way. Would it be possible to delete and then add back my own account, but with the role of ‘adminplusplus’? There is a chance that once I click on that rubbish bin that everything breaks, I'm logged out, that I go directly to jail, do not pass GO and do not collect $200, etc. There is also the chance that due to authentication happening via SSO that I can stay logged in and it all gets a bit messy and that I can add myself back mapping wise, at the application level, which is dealing with authorisation.
It is at this point I have to pull the ol' Morpheus Matrix quotes out: "You take the blue pill... the story ends, you wake up in your bed and believe whatever you want to believe. You take the red pill... you stay in Wonderland, and I show you how deep the rabbit hole goes."
I took a deep breath in, moved the cursor over the rubbish bin icon next to my user, closed my eyes and clicked on it.
Eyes back open, a prompt is asking me to confirm... grrr... cursor repositioned, eyes closed again. *CLICK*
Eyes open, the user list is refreshed, with my username missing from the party. I'm a digital nomad. I’m also still logged into the application, demonstrated by the user list being refreshed no problemo.
Quickly (because I sense we may need to be quick here because it's got so messy, race conditions and all that, etc.), quickly, I click on the 'add' user button, fill in our domain account username and select ‘admin’ from the drop-down menu in the UI and click ‘add’. I intercept the underlying HTTP POST request and change the ‘assigned_role’ parameter from ‘admin’ to ‘adminplusplus’ and send it on its way as before.
The user list refreshes, and there I am, the newest member of the adminplusplus club. Nothing in the UI has changed though, looks and feels exactly the same, no superpowers. No Neo flying around in the sky stuff. This probably needs a logout and log back in to give me all the goodies.
I close the browser, re-open it and request the application URL... let the SSO do the authentication work under the hood, not quite sure what the application will make of the new (but not new) user and my new souped-up role mapping.
The page starts loading. Lots of colours populating the browser screen which I didn't have before. Menu items appearing out of nowhere with lots of names like ‘Applications’, ‘Settings’, ‘Configuration’ and ‘System’.
Our work here is done. Welcome to AdminPlusPlus Land, enjoy your stay.
Thanks for reading.
Trustwave is a globally recognized cybersecurity leader that reduces cyber risk and fortifies organizations against disruptive and damaging cyber threats. Our comprehensive offensive and defensive cybersecurity portfolio detects what others cannot, responds with greater speed and effectiveness, optimizes client investment, and improves security resilience. Learn more about us.
Copyright © 2024 Trustwave Holdings, Inc. All rights reserved.