GhostToken – Exploiting GCP application infrastructure to create invisible, unremovable trojan app on Google accounts

GhostToken – Exploiting GCP application infrastructure to create invisible, unremovable trojan app on Google accounts

On June 19, 2022, Astrix’s Security Research Group revealed a 0-day flaw in Google’s Cloud Platform (GCP) which affects all Google users. The vulnerability, dubbed “GhostToken”, could allow threat actors to change a malicious application to be invisible and unremovable, effectively leaving the victim’s Google account infected with a trojan app forever. Google has officially released a patch for the GhostToken vulnerability on April 7th, 2023. 

Why is the GhostToken vulnerability severe

Today’s workforce is fueled by an entirely new level of productivity hacks as employees seek to increase efficiency and simplify daily processes. This is made possible thanks to thousands of applications, ones that employees can easily install from the Google Marketplace or other websites. Once authorized, the application receives a token, granting access to the employee’s Google Account. 

By exploiting the GhostToken vulnerability, attackers can hide their malicious application from the victim’s Google account application management page. Since this is the only place Google users can see their applications and revoke their access, the exploit makes the malicious app unremovable from the Google account. The attacker on the other hand, as they please, can unhide their application and use the token to access the victim’s account, and then quickly hide the application again to restore its unremovable state. In other words, the attacker holds a “ghost“ token to the victim’s account.

It’s important to note that, since the application is entirely hidden from the victim’s view, they are prevented from even knowing their account is at risk in the first place, and even if they do suspect it – they can’t do anything but create a brand new Google account.

How can a GhostToken be used

Depending on the permissions victims give the malicious app, attackers may be able to read the victim’s private correspondences in Gmail, gain access to their personal files on Google Drive and Google Photos, view planned events on their Google calendar, track their location via Google Maps and grant access to the victim’s Google Cloud Platform services. 

In even worse cases where users provide sensitive permissions, attackers may be able to delete files from Google Drive, write emails from the victim’s Gmail account to perform social engineering attacks, steal sensitive data from Google Calendar, Photos or Docs and more. 

The GhostToken vulnerability

One day, while running our usual analysis process, a tokens.list API call had returned an odd result – a token of an OAuth application which had its displayText identical to the clientId field.

An odd tokens.list result
An odd token result (image is for demonstration purposes only)

Curious, we delved deeper. 

Initially, our best guess was that this is what happens when an OAuth application client is deleted, as probably the API backend has no place from which to retrieve the display name. But if that’s the case, why wouldn’t the token immediately get revoked (and consequently not returned in the tokens.list API call at all) once the client is deleted?

To find out the cause for the displayText field’s odd behavior, we tried deleting a client of an OAuth application which held a token to one of our users, directly from the Credentials page of the application’s owner. As we guessed, this indeed caused the displayText to be identical to the clientId in the API response. When we tried to use the token or re-authorize the application, we got an error:

OAuth client deleted error
An error after client ID deletion

Given that any access tokens granted to this application will be invalid within the hour, and the refresh token and no-consent authorization are unusable, we should be safe. Right? 

Well, not quite. As it turns out, there’s another way to delete an OAuth application client. 

Pending a breach

To understand how the GhostToken vulnerability works, some background is required: OAuth application clients in Google are associated with a GCP project. In order to create an OAuth application, the developer must go through the process of creating a GCP project, and within it the consent screen of their to-be application. This means that every application offered to Google users in the Google Marketplace or via other websites, is associated with a single GCP project (specifically, the project’s identifier appears in the beginning of the application client identifier).

Seemingly unrelated, a GCP project can be deleted by any user with appropriate management permissions in the Manage resources page, alongside all the resources contained in the project, part of which are the OAuth application clients belonging to the project.

Once the owner deletes a project, the project enters a limbo-like, pending deletion state, and stays that way for 30 days until it’s fully purged and deleted. All the projects that are in this state can be viewed on the Resources pending deletion page. This feature was designed to allow project owners to stop the deletion and restore the project completely.

Deleting the malicious project
Shutting down a project, with a 30 day schedule

Back to our case, the same displayText field odd behavior occurred immediately when our project entered a pending deletion state, probably since the OAuth application client resource is deleted in the process. Most importantly, we noticed at this point that the access of an OAuth application client that belongs to a pending deletion project is not shown in the Apps with access to your account page.

At this point our spidey-senses were tingling and we wondered what would happen to the OAuth application client if we restore the project. So, we initiated the restore process.

A moment of curiosity from our Slack
A moment of curiosity (from our research Slack)
Restoring the malicious project
Restoring the pending-deletion project

Alas, once the project was restored and out of pending deletion state, the old refresh token (that was created before the deletion process was originally initiated), had been re-enabled. This means we were able to use the refresh token in order to get an access token, and use the access token to successfully retrieve user data.

Refreshing a GhostToken
The old refresh token is then re-enabled and can be used to get a new access token.
Using a ghost access token
The new access token is used to access the user data.

Attack Scenario

This foregoing primitives, can be compiled to the following attack scenario:

  • Setup: A Victim authorizes an innocent-looking 3rd-party OAuth application. The application is either owned or taken over by an Attacker, which receives a refresh token 1//<refresh> for the victim’s Google account.
  • The attacker initiates the attack loop:
    1. The Attacker deletes the project associated with the authorized OAuth application, which now enters a pending deletion state. As mentioned, this makes the application hidden and unremovable from the Victim’s perspective.
    2. Whenever the Attacker wishes to get access to the victim’s data they restore the project, use the same refresh token 1//<refresh> to get an access token, and use it to access the Victim’s data.
      The moment that this is done, the attacker returns to step 1 to re-hide the application from the Victim.
GhostToken Attack Scenario
Attack Scenario: The setup phase, The attack loop

Additional notes

There are a few things to consider when it comes to the impact of the attack scenario:

  1. The attack loop must be executed periodically, and at least once before the refresh token expires (6 months for a verified application). Verifying an application in this context is not an issue since it can be made to look legitimate even if the vulnerability is exploited.
  2. Besides the Apps with access to your account management page, there is generally no way for a user to remove a 3rd-party integration. However, if the initial authorization done by the user includes any of the Gmail-related scopes, the refresh token will be revoked if the victim changes their password. To be clear, in the case of other sensitive scopes (such as access to Google Drive, Google Calendar, GCP, etc.), changing the account’s password won’t revoke the token.
  3. During step 2 of the attack loop, the access re-appears in the Apps with access to your account page, which means the victim may technically remove the application’s access in this time window. However, it’s an attacker-controlled, very short time frame, which lasts until the attacker executes step 1 of the attack loop again.

Disclosure timeline

  1. June 19th, 2022 – Astrix Security finds the vulnerability and discloses it to Google.
  2. June 23rd, 2022 – Google initial response, identifying the vulnerability as Abuse Risk.
  3. August 18th, 2022 – Nice catch! Google accepted the report.
  4. April 7th, 2023 – A global patch fixing the issue was rolled-out by Google. As per our coordination efforts, the patch included adding tokens of OAuth applications in a “pending deletion” state to the user’s app management screen.

Mitigation and conclusion

As mentioned before, the only way Google users could remove the access of an OAuth application is through the Apps with access to your account page. 

This means that while the vulnerability wasn’t patched, all Google users were essentially unable to remove malicious applications exploiting GhostToken.

The patch released by Google makes it so that applications that are in a “pending-deletion” state are still displayed in the Apps with access to your account page, and thus can be removed by the user just like any application. Astrix recommends users to go to this page and verify that they are familiar with all authorized third-party apps, and that each has the minimal needed permissions.

As part of our work at Astrix, we actively search for and identify tokens and access that are allegedly expired or deleted. To deal with such cases, our strongest recommendation is to adopt a Zero-Trust approach as part of the organizational interconnectivity security, and revoke their access. 

Although (or maybe because) such security concerns are less known and rarely discussed, they are crucial. In today’s world of commonplace attacks, complicated threat scenarios and exponentially increased attack surfaces, routine security checks that clear out any unnecessary, unused, or over-privileged 3rd-party access must also look for GhostToken-like vulnerabilities.

Follow us on Linkedin to stay updated with future publications and research.

Sign up for a 30 min demo with Astrix security experts to learn how we secure non-human identities and third-party app connections.

This site is using cookies for various purposes (analytics, marketing, user experience). You can read more in our privacy policy.

Request a demo

See how Astrix can help you take
control of your third-party integrations.

This will close in 0 seconds

Contact us

This will close in 0 seconds