Beyond Passwords: Decoding the Vulnerability of Identity Tokens
Many applications that we use all the time to communicate and collaborate such as MS Teams, Slack, LinkedIn, Google Workspace, Microsoft Office 365, Salesforce and so on are to greater or lesser extent based upon the ‘modern web architecture’. All of these applications make numerous API calls to cloud hosted services. This architecture is really powerful and allows for interactive collaboration with other users in ways that could never be possible in a traditional ‘desktop application’ that only runs and executes on a single computer with a single user. However this power comes with a complication. Your identity.
If you’ve watched any of our UpSight Security demos we often include a step where an attacker reads credentials from one or more applications a user is using and then demonstrates the attacker using those same credentials to login to the same application from another machine as the original user. All without needing the username or your password of the original user!
And it's certainly not just UpSight doing demos! One of the more prevalent types of malware that we see in our detonation lab are members of the ‘Redline Stealer’ family of credential stealers. Redline has been used by threat actors in a lot of campaigns, but its primary objective is to steal authentication tokens and exfiltrate them back to the attacker. But redline is just one of many credential stealers.
I’m going to try and explain in more detail why this works and what you can do about it. Of note, this is not a blog about password strength, 2FA, YubiKeys… It's about why none of that really matters if you don’t protect your tokens.
What are tokens and why do we need them?
A traditional desktop application needed to know very little about you, the computer operating system managed your identity with your ‘login’ and tracked what files and applications you own using file system metadata. Applications interacted with data through APIs provided by the operating system directly to gain access to data. The web changed this radically. Since cloud applications are shared across many different users and organizations, it is very important that the application itself knows your identity and informs the cloud APIs of your identity so that you only work with data you have access to and interact with other users you know.
Each cloud API could individually ask for your user name and password before allowing your application to make use of the data it provides. However, this is highly inefficient and would require each individual cloud service to understand the highly complex topic of identity and authentication. Instead cloud applications use what are called ‘tokens’.
Tokens are created by specialized cloud authentication services that process your username, password, and possibly requests an additional authentication step like a SMS code, YubiKey, or MFA code. There are open standards like OAuth that allow for 3rd party services to provide this authentication service to many cloud applications. This is what is happening when you see those ‘login with google’ etc. options.
Tokens frequently are issued in a fairly standardized format (RFC 7519) called a ‘Java Web Token’ or ‘JWT’ for short. JTW tokens are just short text strings of encoded data. The decoded token data includes a list of key/value pairs of ‘authenticated data’ that the authentication service creates and then are signed by the authentication service. The authenticated data typically contains some information about you as a user such as your name, but also includes information about what rights and roles you have within the application.
The application cloud APIs then only need to understand how to validate the signature on the token and read whatever information the API needs from the list of authenticated data (much of which are also defined by open standards). This nicely encapsulates the identity problem for the cloud application.
So what is the problem with tokens? Why can they be abused?
A really important thing to understand about JWT tokens is that these are the _result_ of authentication. They happen _after_ the user has logged in. As such these are called ‘Post authentication credentials’. Post authentication credentials are in many ways very similar to a driver's license… but without a photo. It lists some basic data about you such as your name and age, and your driving privileges as well as an expiration date.
Now about that ‘like a drivers license… without a photo’ bit. This is where tokens differ from most forms of identification! Anybody with the token can use it! Unlike a drivers license there are no obvious ways to tell if the caller of a cloud API is using a stolen token! The cloud API can’t see your computer and know that it's been taken over by malware and passed all of your tokens off to some dark web dealer who sold them onto another actor to impersonate you.
You might have the most obtuse password complexity and expiration policies along with FIPS certificated hardware 2 factor authentication in place… It all doesn’t matter even a little bit if the attacker can gain access to the post authentication token. In fact once your token is stolen it often does not help even if you change your password, your password is only used when getting a new token.
Tokens do expire, but keep in mind how long you go when using an application between it prompting you to sign in again, it is typically anywhere from hours to, weeks, to never. Any of those time spans is a very very long time for a computer. There are also what are called ‘Refresh’ tokens that can be exchanged periodically for a new token with a new expiration date so long as they are exchanged before the refresh token expires. Refresh tokens are intended to allow an application to keep running after the initial authentication token expires without needing to ask the user to login again.
Some authentication providers do some other smart things like including the ip-address geo-location they observed when they issued the token, the cloud API could check this against the ip-address geo-location it observes. Token issuers can ‘revoke’ a token if they detect suspicious use of the token, but these schemes are not widely adopted, and such checks place more burden on each individual cloud API again; imagine if every time you showed your driver's license in a store they called the DMV to see if it was valid….
The problem is that you have to keep your tokens safe and secret!
It's a bit of a tall order to place on your shoulders, but the web depends on it, and I bet you didn’t really understand that this was your responsibility!
The good news is that your mobile phone was designed for the web and thought about this problem. On your mobile phone the underlying architecture of the mobile OS provides each ‘app’ a private storage space that is only accessible to that specific app where it can store tokens. This is one of the many reasons why you are warned against ‘rooting’ your mobile device, app specific storage is no longer private on a rooted device.
The bad news is that desktop operating systems like Windows or OSX were designed long before the internet existed to run desktop applications. Cloud applications running on a desktop operating system store data just like any other desktop application - they don’t have a concept of identity when they store data! They just store it and the operating system notes that the data belongs to the user, not the specific application. Which means any _other_ application, including malware, a user happens to be running can read it as well. If a user accidentally runs malware such as the highly prevalent Redline stealer, all of the stored tokens are readable.
Each desktop operating system does have some facilities to store data more privately, but these are not widely used by applications - and even when they are, typically the logged in user still has easy access and they essentially are just ‘more hoops to jump through’ for something like redline stealer. If the data is worth stealing, it will be stolen.
How does UpSight Security keep tokens safe?
This is an UpSight Security Blog, so let's look at how UpSight handles tokens. UpSight’s AI model keeps track of attacker behavior and can interpret it a bit like a story. UpSight is able to distinguish between an application reading its tokens and a malicious application because they have different histories that tell very different stories.
Key to how UpSight AI works in fact is making predictions about how a story might end, and a frequent prediction that the UpSight AI makes is ‘credential theft’. These predictions are based on observing thousands of variations of malware running in our UpSight Detonation lab, including a very healthy population of the aforementioned RedLine Stealer. When UpSight observes a process with a history involving suspect behavior with a prediction that the next step might be credential theft; UpSight knows to stop the theft and evict the attacker.
The green nodes are behaviors that were observed that attackers often make, but on their own are not malicious. UpSight treats these as words in the attacker’s sentence and starts to make predictions about how it might end.
In this case the green nodes represent a process executing from a filename that is not normally associated with an executable file (.bat specifically), the process then sets up a persistence mechanism by creating a entry in the windows registry to run a copy of itself on setup, it reads in data from an alternate data stream, and manipulating its file properties to remove its ‘Mark of the web’ origin, and then launches itself a second time. At which point it gets down to the business of stealing post authentication credentials.
The orange node is UpSight stopping an attempt to steal stored usernames and passwords from Google Chrome. The red node is UpSight terminating the process since it attempted a second credential theft attempt - this time going after windows authentication tokens.
You might be thinking, but how did the malicious application get so far without being stopped by my anti-virus? That is an entirely different blog… but the short answer is - it is very easy to trivially change malware detected by AV so that it isn't detected by AV anymore. It is much harder for the malware to change its behavior… afterall to steal tokens, they must be read, which is why the UpSight AI is not fooled.
What you can do
Run UpSight Security!
Keep the validity of tokens to sensitive applications short - in particular anything tied to money directly or indirectly.
Decline offers to ‘Trust this device’ since that just extends the life of a token to ‘forever’. Unfortunately the post authentication token life cycle is rarely in your direct control since the token expiration is set by the authentication service.
Completely sign out of services like google or banking on all devices periodically since that does invalidate tokens.
Seriously, I can’t think of another, run UpSight!