Google Calendar is one of the many features provided to those who sign up for a Google account along with other popular services such as Gmail and Google Drive. Following email, the calendar is probably the second most used pieces of productivity software in an enterprise. It allows employees to schedule out the work week so that things can actually get accomplished. Google has an interesting feature that automatically adds various events to your calendar. If your Google account receives an email stating you have booked flights, reservations for a dinner, or even movie tickets, Google will automatically add these events to your calendar.
Black Hills Information Security took a deeper look at how these events were being generated. BHIS discovered that it was not required to send an email to a target to create an event on their calendar. Additionally, there are security controls that can be enabled on a Google account that attempt to prevent this from happening, but BHIS discovered bypasses to these controls. In this post BHIS will discuss this “Event Injection” vulnerability, the risks associated with it, and how to exploit it using MailSniper.
Black Hills Information Security reported this issue to Google. See the section titled “Timeline of Disclosure” below for details.
We were working on a red team assessment for a customer that we knew was going to be tough. It was discovered that this customer was utilizing G Suite For Business, which is one of Google’s offerings for enterprise customers who would like to have their enterprise email and other services hosted by Google. Knowing this, we wanted to take a different approach to how we were going to attempt red teaming the environment.
A few months earlier one of us had something interesting happen. A Google event notification popped up on the calendar stating that a booked flight was departing in 10 minutes. This was not a flight that the BHIS employee had booked. Opening up the event and checking where the source of the event creation came from, it was discovered that the event was generated from an email that had been sent. A coworker had sent their flight itinerary in an email, and Google thought these details were a different BHIS employee’s itinerary, and automatically added it to their calendar.
In researching how these events were being generated it was discovered that an email wasn’t even necessary to create an event in someone’s calendar. This can be very easily done manually through the Google Calendar UI. When you create an event and add guests, Google will ask you whether you would like to send invitations to the guests after saving it. Simply selecting “Don’t Send” will save the event to the guest’s calendar if it is a Google account and not send them an email.
BHIS thought this could provide a very interesting situation for phishing users of a G Suite environment. As most users have been trained to spot phishing links in emails, and Google itself has a few protections against phishing Gmail users, we thought focusing on social engineering users through Calendar event may be more successful.
Event Injection & Social Engineering
Possibly the most interesting element of the calendar is that it can create a sense of urgency simply by alerting a user to something. Perhaps the user completely “forgot” they had a meeting scheduled. If someone has their Google account linked to their phone it is possible to generate an alert for an event directly on their phone as well as email to their account. When it comes to the ruse that is used the skies are limitless. One ruse we had great success with for this particular red team assessment was an “All Hands Meeting” that was happening in 10 minutes. In the body of the event we included text pointing the victim to an agenda that was required to be read before the meeting.
The site linked in the body of the event hosted a fake Google authentication page that captured their credentials and redirected the user to the fake agenda (more on that fake authentication page using CredSniper in part II of this post). This method proved to be highly successful.
Invoke-InjectGEvent & Invoke-InjectGEventAPI
New modules have been added to MailSniper for injecting events into target calendars. The first method (Invoke-InjectGEvent) only requires a set of Google account credentials. The second method (Invoke-InjectGEventAPI) we’ll discuss involves connecting directly to the Google API. To use MailSniper to inject events into a Google calendar first import MailSniper.ps1 (https://github.com/dafthack/MailSniper) into a PowerShell session.
PS C> Import-Module MailSniper.ps1
Next, you will need a Google account. If you are attempting to social engineer an organization, a potential idea would be to perform some reconnaissance on the target organization, find an employee of high rank, and sign up for a Gmail account under a similar name. This way when the target sees the event pop up in their calendar the organizer’s name looks somewhat familiar. Those credentials can then be used with the Invoke-InjectGEvent module as follows:
PS C> Invoke-InjectGEvent -EmailAddress ‘firstname.lastname@example.org’ -Password ‘attackerpassword’ -EventTitle ‘Title of Event’ -EventLocation ‘https://global.gotomeeting.com/join/123456890’ -EventDescription ‘Summary of the event... Maybe include link to a fake Google Auth Page’ -StartDateTime 20171031T160000 -EndDateTime 20171031T163000 -Targets ‘email@example.com’
This will create an event in the target’s calendar provided they haven’t disabled the “automatic event add” feature that we’ll discuss more in a moment.
There are a few settings that can be set within Google Calendar to prevent events from automatically being added to the calendar. The first setting is called “Events from Gmail” and there is a checkbox called “Add automatically”. If this checkbox is checked then Google will automatically add events from emails sent to a Gmail account (similar to the flight itinerary mentioned above).
The second setting is called “Automatically add invitations to my calendar”. There are three options here including:
- Yes, but don’t send event notifications unless I have responded “Yes” or “Maybe”
- No, only show invitations to which I have responded.
With the first setting this only prevents events from being added if the sender actually sends you an email invitation. Simply performing the manual steps listed earlier to create a calendar entry without sending a notification still works there. The second setting is a bit more interesting. There is an option that states “No, only show invitations to which I have responded”. This prevents the first method of injecting events from working. However, BHIS found that it is possible to set the target’s response status to “Accepted” using the Google API. This effectively bypasses this security setting.
A module called Invoke-InjectGEventAPI has been added to MailSniper for injecting these types of events via the Google API. In order to connect to the Google API there are a few steps that must be taken first to get an API Access token.
A. Login to Google using the account you want to inject the event as.
B. Go to https://console.developers.google.com/flows/enableapi?apiid=calendar&pli=1.
C. Create/select a Project and agree to ToS and continue.
D. Click “Go to Credentials”.
E. On the “Add credentials to your project” page click cancel.
F. At the top of the page, select the “OAuth consent screen” tab. Select an Email address, enter a Product name if not already set, and click the Save button.
G. Select the Credentials tab, click the Create credentials button and select OAuth client ID.
H. Select the application type Web application, under “Authorized redirect URIs” paste in the following address: https://developers.google.com/oauthplayground”. Then, click the Create button.
I. Copy your “Client ID” and “Client Secret”.
J. Navigate here: https://developers.google.com/oauthplayground/.
K. Click the “gear icon” in the upper right corner and check the box to “Use your own OAuth credentials”. Enter the OAuth2 client ID and OAuth2 client secret in the boxes.
L. Make sure that “OAuth flow” is set to Server-side, and “Access Type” is set to offline.
M. Select the “Calendar API v3” dropdown and click both URLs to add them to scope. Click Authorize APIs.
N. Select the account you want to authorize, then click Allow. (If there is an error such as “Error: redirect_uri_mismatch” then it’s possible the changes haven’t propagated yet. Just wait a few minutes, hit the back button and try to authorize again.).
O. You should now be at “Step 2: Exchange authorization code for tokens.” Click the “Exchange authorization code for tokens button”. The “Access token” is item we need for accessing the API. Copy the value of the “Access token”.
Now that you have a Google account that can access the Google API you can use the MailSniper module Invoke-InjectGEventAPI to inject an event bypassing the security settings mentioned previously. Take note that the “Access token” expires after 3600 seconds. A module for refreshing this token is planned to be added into MailSniper soon, but simply clicking the “Refresh access token” button shown in the previous screenshot will generate a new one.
After importing MailSniper into a PowerShell session as previously shown the following command can be used to inject an event into a target’s calendar using the Google API.
PS C> Invoke-InjectGEventAPI -PrimaryEmail firstname.lastname@example.org -AccessToken 'Insert your access token here' -Targets "CEOofEvilCorp@gmail.com,CTOofEvilCorp@gmail.com,CFOofEvilCorp.com" -StartDateTime 2017-10-22T17:20:00 -EndDateTime 2017-10-22T17:30:00 -EventTitle "All Hands Meeting" -EventDescription "Please review the agenda at the URL below prior to the meeting. https://definitelynotmalicious.com" -EventLocation "Interwebz"
The reason this bypasses the security setting is due to the fact that the Google API has a writable property on events called attendees.responseStatus that can be set to ‘accepted’. Setting this when creating an event effectively makes it appear that a target has already accepted the event.
As of the date this blog was posted it is possible to inject events into Google calendars without a victim being able to prevent it. Additionally, it is not necessary for an email invitation to be sent for that event, so it’s possible to directly inject events into a Google user’s calendar without them ever receiving a notification. This presents a very unique opportunity for social engineering Google users. Black Hills Information Security reported this issue to Google. See the section titled “Timeline of Disclosure” below for details.
Stay tuned for part II of this post where we discuss CredSniper, a brand new framework for phishing Google users including the capture of various two-factor authentication tokens.
Timeline of Disclosure
- Oct 9 – BHIS discloses event injection with and without Calendar API to Google
- Oct 9 – Google sends automated response
- Oct 10 – Google triaged report
- Oct 17 – Google release Calendar update (silently adds Calendar setting to disable injection)
No updates to BHIS initial report
- Oct 27 – BHIS publicly discloses event injection at WWHF
- Oct 31 – Google responds stating it’s a feature and the settings provide users the ability to disable
- Oct 31 – BHIS updates Google with step-by-step procedures to bypass settings