DEF CON 29 - Matthew Bryant - Hacking G Suite: The Power of Dark Apps Script Magic

Aug 5, 2021 17:39 · 8857 words · 42 minute read

- Thank you all for coming. This is Hacking G Suite: The Power of Dark App Script Magic.

00:09 - A little bit of background on myself, I’m Matthew Bryant, I go often by my handle mandatory, I currently lead the Red Team Effort at Snapchat, and also outside of work, I also post occasionally about security on Twitter @IAmMandatory.

00:22 - And additionally, I also do hacking write-ups and research posts at my website, thehackerblog. com.

00:31 - So, to start us off with some context and background sort of give a base to what we’ll be talking about today.

00:37 - So Google Workspace, for those of you who aren’t familiar, essentially, this is the new name that they’ve given to G Suites.

00:42 - I know it can be tough to keep up with all of Google’s ever changing brand guidelines and stuff.

00:47 - I will still be referring to this as G Suite throughout the talk, just because I think most people are more familiar with G Suite than Google Workspace, but we know what G Suite is essentially, is it’s sort of the suite of Google services that people use, things Gmail, Drive, Calendar, all that stuff.

01:04 - This is available both for regular users, personal individuals as well as companies, enterprises.

01:10 - And this allows people to sort of if it’s a company, for example, they can collaborate online to get work done using all of the various Google services.

01:19 - And at the time of this research, they were boasting over 2 billion users.

01:24 - So a ton, a ton, a ton of people use this stuff.

01:29 - So for those of you who aren’t familiar with Apps Scripts, apps script is essentially this, basically JavaScript language that is just used to write these server-less JavaScript apps that run on Google infrastructure.

01:39 - And it’s kind of this custom way to build apps where it’s highly optimized for automating Google services.

01:46 - It comes with a lot of really useful libraries when it comes to automating everything from Google docs, to Gmail, to any sort of Google service you can think of.

01:54 - And on top of having all these prebuilt libraries it has the seamless integration with Google’s app registration system and sort of their OAuth system.

02:01 - So normally when you set up a new OAuth app with Google, you have to set up a callback URI, and can figure your app to work with it and all sorts of these, all sorts of these things.

02:13 - But when you use Apps Script, that’s all sort of magically done for you.

02:16 - All this authorization stuff is just sort of handled and it sort of automatically takes care of it.

02:23 - So it also offers a variety of triggers that you can use to start your little scripts that you write.

02:28 - So everything from somebody hits the web endpoint that kicks off the script to that they’ve opened a Google Doc and something’s running at the beginning of that to schedule a cron, sort of cron-style things.

02:39 - where you have scheduled execution jobs and stuff of that nature.

02:46 - This is an example of a screenshot of the Apps Script Editor.

02:49 - You can see it’s actually pretty full ID environment.

02:53 - It has everything from code completion to breakpoints, debugging, all the stuff that you’d kind of expect from your regular dev.

03:04 - So Google’s OAuth system is very similar to a lot of the OAuth systems out there.

03:09 - Essentially the idea is, it’s a system that’s built to sort of allow these third-party apps built by whatever individuals to request access to resources that Google users have in their account.

03:21 - So for example maybe I have some Google Docs in my account and I wanna automate something for these Google Docs using a third-party app.

03:29 - This allows me to basically delegate access to my Google Docs to this third party app to do that for me.

03:36 - So these permissions to these resources, they’re essentially known as scopes and there’re over 250 of them.

03:43 - And so these are for all of the various Google services that you can think of, right? So everything from BigQuery, Gmail, Google Docs, stuff like that.

03:52 - The way that it works, right, is you sort of your app will redirect them to an authorization prompt that gives them a brief summary of what you’re requesting permission-wise.

04:01 - And the user can kind of think it over and decide, “Yep, I’m gonna allow that” or “No, I’m gonna reject that”.

04:05 - And if they allow it, essentially your app gets handed some tokens, which you can then use to talk to these APIs, authenticate as the user.

04:16 - So as I mentioned that prompter, this is what that looks like.

04:19 - You have sort of a human-readable little summary here in this case, this example app, it has “Hey, this is gonna request access and if you allow it, it will have access to your Gmail stuff, it’ll have access to Google Cloud and everything in it. ” And also it’s asking for permission to sort of run when you’re not present.

04:36 - So it’s not just a one-time thing, in the future it could just keep running, indefinitely.

04:45 - So tying all these concepts together and thinking about things at a higher level, and this becomes a pretty effective option when it comes to targeting organizations or companies that are sort of on the G Suite stack, Apps Script becomes pretty attractive option for things like phishing, targeted spear phishing, as well as say you’ve already compromised, an individual employee account in a G Suite org.

05:08 - It becomes a very attractive option for backdooring that account as well.

05:11 - And the reason why it’s an attractive option is because, if you have an Apps Script implant, it’s actually sort of outside of the eyes of all the regular machine-monitor controls that run people’s end machines and their laptops and stuff so regular antivirus, their endpoint detection tooling, and sort of on device monitoring, none of that’s really effective here, because again it runs completely enclosed infrastructure.

05:33 - It’s like a total service environment, so that they don’t have any visibility into that at all.

05:38 - And even better, you have your victim wipes their laptop for some reason, your implant is completely unaffected, just totally remains with full access to their account.

05:50 - So another thing that’s interesting, if you think about some of these companies that have sort of these extremely hardened environments Apps Script becomes an interesting option even then.

06:00 - So when I’m talking, when I say hardened environments, what I mean is companies with things like mandatory hardware, U2F on logins, so places where traditional credential phishing just isn’t gonna work because they have a hardware key that they actually have to hit in order to login.

06:16 - Things like they have hardened Chromebooks with lockdown enterprise policy.

06:20 - So you don’t have things, you can’t get a binary implant running on there.

06:24 - You got to key in even to get to the Chrome extensions, potentially if they have lockdown enterprise policy and they have hardware attestation and all that other good stuff, right.

06:31 - So super-lockdown environments. And so getting around these measures we’ve got to think a little bit more clever than your average attacker.

06:38 - This isn’t like the casual Windows Networking style pen tests that are potentially more common.

06:43 - This is a completely sort of unique environment.

06:46 - And so we’ll have to be a little bit more unique in how we think about and how we approach these things.

06:55 - So I’m gonna go into some historical precedent here.

06:57 - One thing that I think is a particularly interesting example is the attack that happened a few years ago, which was essentially basically built around using, Google’s OAuth and API system.

07:11 - Some of you may recognize this screenshot here, if you were one of the individuals that was affected by this, but essentially this was what was later dubbed as the Google Doc worm.

07:23 - So the way that this worked is it would essentially this worm would basically send these phishing emails, looking like this.

07:30 - And you know, this would be from somebody you personally knew coming from their actual email address.

07:34 - And it would say, “Hey, your friends has invited you to view a document. ” And it would give you this button to, sort of like, “Okay, let’s open that document”, but when you actually went and did that, it would actually present you with this OAuth prompt here.

07:47 - And it says, “Hey Google Docs wants to have access to read, send, delete and manage your email, and also access all your contacts. ” Now of course, for security people watching this, they’re like, “I would never approve that prompt”, but for the average user, they’re sort of looking at this and they’re like, “Okay, Google docs wants access to my Gmail and contents.

08:07 - Yeah, I mean, I thought they would already have that, sure, why not?” right.

08:11 - And they would probably go through and just go ahead and approve this.

08:14 - So it’s sort of very, very convincing attack for a lot of the regular computer users.

08:20 - Of course, if they did do that and they did authorize this app to have access to their Google account, what would it immediately then go do is it would use the contact access to essentially get their a thousand most recent contacts.

08:31 - Their emails, their friends and coworkers and stuff like that.

08:35 - And it would send out this exact same phishing email, as them, to all of their friends and contacts.

08:41 - And this would basically repeat the cycle where they would then get that phishing email that we saw before, right.

08:47 - The impact of this attack was actually pretty impressive.

08:50 - It ended up spreading like wildfire and essentially it actually affected over a million Google users.

08:56 - And this is everything from your personal Google users, like you and me, to sort of the big enterprise business users, sort of the G Suite organizations.

09:06 - And Google sort of rapidly responded to this actually they had really good response time.

09:10 - They did everything from like killed the emails that were spreading around, killed off all the apps and stuff like that.

09:16 - And they did all of this in a couple hours and after doing some post-mortem analysis on basically the JavaScript that was used to control and run this attack, it turns out the coding for it, was actually pretty amateur, right? It wasn’t this advanced crazy nation state thing that most people assume.

09:34 - And it essentially it looked like it was only collecting email addresses.

09:38 - So all things considered this attack could have been, much, much worse.

09:42 - It almost seemed as if, you know somebody said it was actually like unfinished.

09:48 - So yeah, let’s break down this attack into its kind of core components here.

09:51 - One, I would say fairly advanced trait that they did was they did think ahead and they had multiple rotating apps.

09:58 - They’ve registered multiple OAuth apps ahead of time and they sort of randomized them along with different domains, to essentially prevent the easy case of Google just blocking their app or blocking given domain, right.

10:09 - They had to instead track on all of the apps and all the domains and block all of them to prevent this from spreading.

10:15 - It made use of some Unicode characters. Yeah, I saw it earlier, the app name was actually called Google Drive.

10:20 - That was because they were basically evading some filters, which no way prevented you from setting stuff like Google in the name of the app by using Unicode characters, which look exactly the same as their ASCII equivalents, so it was like Google with maybe a Swedish O, for example.

10:35 - And of course, use the social engineering and the phishing scheme that we saw, which was quite convincing to people.

10:40 - And it actually it self-propagated and sort of the old-school email spam style, right? So infect somebody, send to all of their contacts, some of your friends end up falling for it and then they’d send it to all their contacts as well, except, unlike all the email worms of old, this used some of the more modern OAuth-style authentication and authorization to actually carry out these attacks, as opposed to old school credential harvesting and stuff like that.

11:11 - So, as you can imagine, this was pretty shocking to a lot of companies and a lot of users.

11:15 - And so Google made some pretty quick changes and mitigations after this happened.

11:19 - Around two months later, they introduced a G Suite Admin Control for sort of administrators of companies to essentially lockdown their orgs.

11:28 - And the way that this would work is essentially it, they could publish it, they could basically set a setting that says none of my employees are allowed to grant access to any of their Google account data for their employee account, unless it’s for one of these explicit OAuth apps that I’ve explicitly allowed.

11:46 - So this would allow you to lockdown to prevent, you know, say this were to happen again.

11:50 - Their place just straight up, would not be able to grant these permissions their account because it would be blocked, unless it was whitelisted under this policy.

11:59 - And Google later introduced what are called sort of Sensitive and Restricted scopes, they basically labeled a bunch of these permissions, as I mentioned before, as either Sensitive or Restricted, depending on the kind of data that they would grant.

12:13 - And in addition to that, they introduced what’s called the Unverified App warning prompt, for some of the smaller apps that require these scopes and they went and they cracked down a lot of these other misleading OAuth apps, right.

12:25 - They beefed up their security around what you can name an OAuth app to prevent sort of the same exact attack we saw before.

12:30 - So they couldn’t mimic Google-style names and stuff like that as well.

12:35 - So just some quick food for thought here, this attack really didn’t utilize a whole lot of crazy Zero-Day bugs or exploits apart from, I guess, some of the Unicode trickery for the name, it was basically kind of using the system as designed.

12:51 - But the impact was actually incredibly substantial, right? So that’s something to really think about here is you don’t necessarily have to have one big bug or one exploit to sort of pull off these crazy attacks.

13:02 - You can simply abuse the system as it was designed.

13:04 - And the design itself can just lend itself to attacks like this.

13:08 - So just something to sort of think about in general with this, that kind of stock.

13:14 - So we talked about the history, let’s go into the latest, right? So we all have mitigations in place, what can we bypass and what can we do in this sort of modern age? So, I talked earlier about the Unverified App prompt.

13:27 - This is for apps, of course, that ask these sensitive scopes and there’s quite a few of them.

13:32 - So what essentially, this is not kind of a light warning.

13:35 - This is a really serious prompt that actually would dissuade users from continuing.

13:40 - It kind of takes, it looks a sort of takes some tips from Google Chrome’s UI for in data as a cell, you know, sites that you visit.

13:46 - And so the way that the user can actually continue is they have to click this little text that says Show Advanced and they have to go down to the bottom and click through and for the regular user, this is just not gonna be a tenable thing, they’re just not gonna be able to get through this.

13:59 - And so it actually poses significant barrier for us as attackers and our, if we want to phish or use OAuth here.

14:08 - So what is a Sensitive or Restricted scope? So that just means any API with the potential to access sort of private data.

14:16 - This is everything from Gmail, BigQuery, Google Cloud, Drive, Calendar it’s basically, it’s actually a large percentage of the scope.

14:24 - So it’s over 120 APIs. And the way that works is essentially if it’s a small app, if it has less than a hundred users, you have this Unverified App prompts and if the app is bigger than a hundred users, you need to go through an even more strict process where you undergo sort of this intense manual review process.

14:40 - And this process is like no joke, there are companies that you have to use these scopes legitimately for real-world services that they provide.

14:47 - And they have written entire postscripts saying, “It’s so hard for us to get past this review process”, So this is the real deal.

14:53 - And it’s definitely not something that we could really cross if we were an attacker trying to publish a malicious app, it’s just not a tenable route for us, but there are some exceptions to this policy.

15:05 - So you take a look at the documentation around this, essentially if you have, if it is the case where you have some Apps Script, or an app, and you use a Sensitive scope and you fall into any of these categories, then either the normal OAuth flow without the Unverified App prompt will happen or the unverified OAuth flow will happen.

15:22 - So one of these is particular, which is the intersection of these two.

15:27 - And essentially what this says is it says Hey, if the publisher of this app is in the same G Suite org as the user who’s authorizing it and running it, then there’ll be no Unverified App prompt.

15:41 - And this sort of makes sense, right? you can imagine you’ve got an employee who works with you, they’ve created this app and they then share it with you and you wanna run it, it doesn’t really, you trust them and it’s an internal action.

15:53 - So it wouldn’t really make sense to have this scary prompt, cause it’s sort of used internal and somewhat implicitly trustworthy.

16:00 - So that’s something interesting if we could abuse that we could essentially get around this.

16:05 - So one other thing to note about Apps Script is when you have an Apps Script app, it can be either a sort of standalone project, a standalone script that runs, or they can be with what’s called bound to a container, and by container this means basically you can bind it to a Google Doc, or a Sheet, or a Slide.

16:22 - And when you do this, this allows you scripting to basically you can manipulate the document, customize the UI, stuff like that.

16:31 - And the way that works is essentially the regular triggers I talked about before, they’ll run for any user who basically has edit access to the Docs, so they have to have edit access to the Doc and then they can kick off any of these Apps Script triggers and sort of run this app.

16:43 - Keeping in mind, of course, they still have to accept the OAuth prompts if they’re requesting any scopes.

16:51 - So if you imagine sort of our average OAuth phishing scenario, right? Say we have a Google Doc with some Apps Script attached to it and we send our victim this link who’s inside of this G Suite org.

17:02 - When they go to actually they open the Doc and they trigger it and prompt spawns, they of course get the “Hey, Google, hasn’t verified this app suppress the Sensitive scopes.

17:13 - And so likely the victims would be like, “Nah, this isn’t for me, I don’t even know how to get through this” and so our attempt is probably gonna fail here, right? So one interesting thing about Google Docs and Sheets and Slides and all this stuff, is that if you change the average URL that you get from edit to copy, instead of just directly opening to this document interface, you’ll actually get this prompt instead, and so this essentially this prompt here says, “Hey, do you wanna make a copy of, in this case, Confidential Org-wide Comp & Promo Details?” And they get a little button that says Make a copy and when they click this, what ends up happening is, it copies the the document, the sheet into their own Google Drive and then they’re immediately taken to the the full UI interface for working with the sheet.

18:01 - And so, going back to the attack I mentioned earlier, so now if we’re an attacker and we send our victim, this copy link, instead of the regular link, when they go through this link, and they click to make a copy of it.

18:12 - They’ll essentially, like it copies into their Google Drive and then when they trigger the Apps Script that’s attached to it, they will get the regular prompt without this Unverified App screen.

18:23 - And the reason why they get this is because if you look at the app itself, you’ll notice that the actual developer behind the app is the victim.

18:31 - And the reason why it’s the victim is because when they copied that doc, what they ended up doing was essentially they became the creator, because they copied the doc, they’re now the creator and owner of the script.

18:42 - And so they’ll actually see that they themselves are requesting the permission from themselves.

18:50 - So there is one problem though, so when you actually copy, a document with Apps Script attached to it, the triggers don’t come along for the ride.

18:58 - So they don’t really have a way to trigger this thing to get this prompt to display.

19:02 - So that’s kind of a pain, so one way that we can get around this problem is Google Sheets have what are called macros.

19:10 - And this is sort of something made to compete with Microsoft Excels VB script style stuff to manipulate and automate spreadsheets.

19:18 - But what’s useful about the Google Sheets version is they can call out arbitrary Apps Scripts.

19:23 - And what’s even more useful, is you can actually, if you have an image or an item in your Google Sheets, you can assign a macro, so when somebody clicks on the image, it will automatically run this macro, which by proxy runs any arbitrary Apps Scripts that you want.

19:38 - So this basically it’s a great way to sort of trigger your Apps Script to payload.

19:44 - So I’ve got a little demo here where you can see the victim and they go in here and they click, Make a copy, of this Google Sheets and after they’ve clicked that button, you take them directly to your copied sheets.

19:54 - And you see this beautiful image of this goose with this butter knife looking totally not threatening at all.

19:59 - And when they go to click on that, they get the authorization prompts and when they click Continue, you can see they have the regular OAuth prompt, no warnings at all.

20:08 - So essentially bypass that whole restriction around Unverified Apps, but that’s not actually all that we bypass.

20:15 - So in addition to bypassing the Unverified App screen, we’ve also, I mentioned earlier this, a little bit earlier in the talk, but that G Suite Admin setting that allows you to basically lockdown your organization to prevent third party OAuth apps from requesting permissions on your employee’s accounts.

20:33 - This actually gets around that as well. This entire system is essentially bypassed.

20:38 - And the reason for that is exactly the same reason as the reason for bypassing the Unverified App prompts because the app is owned by, it’s basically when the copy is made into the Google Drive of the the victim and they’re inside the org, essentially it means that the OAuth app itself, instead of the new owner, it’s an internal app.

20:58 - So it’s not a third-party app. It’s actually first-party, it’s inside the org and so this doesn’t apply.

21:02 - This block on all third-party API access, it doesn’t apply, so this is bypassed as well.

21:10 - So another fun tip for sort of defeating both the third-party app restrictions and the Unverified App prompt is that if you go through the Docs, you realize that the doc that’s attached to the Apps Script and vice versa, they have the same owner.

21:28 - And so what’s interesting about this is saying you have somebody who’s created a new Google Sheets or Doc or whatever, inside of their G Suite domain, when they’ve created that that’s actually a kind of a bypass wanting to happen, because if they share edit access with anybody outside of the organization, that person where their edit access can actually go in and they can then create some Apps Script for that document.

21:50 - And the owner is still the person that created the doc, the sheet in the first place, right? So since that sticks, now you can essentially use that to start off your phishing or whatever attempt, right? Because that will bypass all of the third-party and Unverified App restrictions that we talked about previously, ‘cause it will be owned by the employee that first created this document.

22:10 - So if you can find one of these, this is a great starting place, where you can sort of skip the whole copy style attack.

22:20 - We talked about how to sort of pierce the perimeter.

22:22 - Now let’s go into sort of once you’ve got some access, you’ve maybe a compromised one employee, a G Suite account, where do you go past then, right? What can you pivot to, how can you escalate privileges? So likely, most companies I’d say probably the most interesting data they have is in Google Cloud and so pivoting to Google Cloud from Apps Script implant seems pretty important.

22:46 - So accessing Google Cloud through Apps Script is not super documented, but you can do it by basically requesting the scope cloud platform.

22:54 - And that actually gives you access to all GCP APIs.

22:57 - So everything from BigQuery to Google Cloud functions, GCE, all of it, as the user who basically authorizes access to your app, right? So the way that you essentially authenticate to these APIs is you use the Apps Script function, ScriptApp. getOAuthToken You take that value and put it in the authorization bearer header, and you can use that to authenticate to all of the APIs, but when you do this, there’s kind of a gotcha.

23:26 - So you’ll notice that when you try to use this for the Google GCP APIs, you’re gonna get this warning that says, “API that you’re trying to access, it’s not been used in this project ID, you know, this number before, either it’s not been used or it’s disabled”.

23:41 - So this request is failed. What’s your more strange is the product number that’s displayed.

23:48 - It’s not gonna be for the product that you’re even trying to access.

23:51 - So what’s the deal with this here? Again, not super-well documented, but essentially when you create a new Apps Script app upon that creation, you’re allocated a sort of hidden Google call project.

24:05 - That’s immediately attached to this Apps Script app associated with it.

24:09 - And so what happens is this implicitly binds your API requests that you make from your access token generated by your implant with this project.

24:18 - So it just sort of, that’s why you have this arbitrary product number it’s for this hidden project.

24:23 - And you, unfortunately, for the hidden project, you can’t access it via the Google Cloud Control Panel or anything that.

24:28 - You can’t enable services on it, use programmatically, like you normally would be able to.

24:32 - And so this is kind of a big problem, right? Well, it turns out that you can actually get around this by specifying the x-goog-user-project header.

24:43 - And you simply specify the product name that you’re trying to query, right? So if you’re going for, you wanna modify a project example, you do this header and then set it to that value.

24:53 - That basically looks this, set your product ID in your API calls and set it in the header.

24:58 - And then you put your authorization bearer header to that script, to the script app that get OAuth token value that I mentioned before.

25:05 - And you can go on and you can talk to all the GCP APIs to your heart’s content, right? It’s the data you’re looking for, it doesn’t happen to be, the good stuff isn’t in Google Cloud, then it’s probably in Google Drive, right? Maybe more financial, different companies, all their stuff is in Sheets and Drive.

25:25 - And so let’s talk about sort of mining Google Drive for the good stuff.

25:30 - We’ll begin with kind of the general overview of how sharing works in Google Drive.

25:35 - So by default in G Suite, there’s essentially these three permission levels, the most restricted sharing settings for a file is that, only people who are explicitly added to the ACL are allowed to access the documents.

25:49 - You’ve just got to go one by one and add other users, and to give them access to it, and if they aren’t on the list, they cannot view the document, right, they can’t access it.

25:57 - So, the second level is anybody who has a link to the document or the file, they can access it, so you said you’re sharing by link.

26:05 - So if they have a link, they can access it, but if they don’t, they can’t, right.

26:09 - And then the widest most open setting is you can even make it so that, hey, anybody who just searches inside of the Drive web page, they can find your internal doc by doing that, right, if they’re also in the company.

26:22 - So yeah, these are the defaults, essentially by default, it has the strictest sharing settings where you have to explicitly add people, one click away from that, the most restrictive settings is share my link with everybody who has the link, they can access the document and then if you do more clicks, you can get it searchable by everybody, right.

26:41 - And of course once somebody view, if it is shared by link, right, and somebody else views it once, it becomes searchable in the future, because the assumption is you have the link, you should be able to find it again, because you were able to visit it once.

26:55 - These unique document URLs are outside of the range of brute forcing.

27:00 - So if somebody does share my link, you’re not gonna be able to brute force the actual link itself, you’re gonna have to actually have it.

27:08 - So we talked about sort of what the default and what the setting system is, but real world usage tends to be quite different than sort of the strictly technical bits, right? So what actually ends up happening? So in my experience, usually what ends up happening is, if a file is important, almost kind of by definition, right? It’s gonna be shared with other people, right? Other people are gonna view this document.

27:27 - They’re gonna maybe make changes, do adjustments to it.

27:29 - And so in the strictest security setting that we mentioned previously the owner of the doc is gonna have to add into individual users one by one.

27:37 - And that’s a very tedious process, especially when you have say you’re doing it 40 people, that’s very time consuming.

27:45 - And you can use Google Groups and sort of put together ACL groups that can be added in bulk together, but it’s still very tedious process, right.

27:52 - So what often ends up happening is people get to a point where they’re just like, they share it with so many people that they’re just like, “Ah, forget it”.

27:59 - Right and they just share by link with a large, anybody who has the link, they’re good to view it.

28:04 - So in practice that tends to be pretty, pretty common.

28:08 - And only a tiny portion ended up being that wide searchable mode that we talked about before, just because of the amount of user interaction required.

28:15 - So, how do we get access to these this big area, which is stuff that’s shared by link? So of course there’s the basic method, which is just a search all the internally shared systems inside of a company, let’s check the chat, let’s check internal forums.

28:31 - You got Internal Q&A sites, your ticket management queues, zero whatever, bug trackers, and try to mine out and try and look for all this Google Doc Drive links.

28:41 - And you can do that, but there’s also another way to do it, which is actually the same way that we do it on the web.

28:47 - How we index and make documents searchable on the web.

28:52 - And so the way this works essentially is, yeah, you can have a script which will simply take some seed, Google Drive links, Google Sheets/Docs links.

29:00 - It will essentially it’ll go through each one of them, so say you give a Google Sheet, it’ll go through that, it’ll parse it.

29:05 - It’ll find all the links inside of a document.

29:07 - And it will recursively crawl all of those documents as well, and look for links inside them and so forth and so on.

29:13 - Until it essentially is able to enumerate all of these other documents, which are sort of indirectly linked to all these other documents, right? So I’ve written an Apps Script Spider that does exactly this, which you can essentially do what I just described, right.

29:27 - Take some seed links, plug it in, it uses a starting point and recursively crawls all this stuff until it’s exhausted all the paths and it gives you along the way it collects metadata about sharing, document context, the authors and stuff like that, so you can essentially, let it run, gather up all these documents and you can then look through the results to see if it has the data that you’re looking for.

29:50 - This is available at this GitHub link here, so feel free to take a look.

29:56 - Another useful thing to do is to basically request Google backaccess for the people API and so what this is essentially a G Suite, it ships with this really neat ability actually, it comes with an internal employee directory.

30:12 - And so with the people API, if you request the directory. readonly scope at a minimum you can access, you can figure out all the other employees in the G Suite org, and you can get everything from names, emails, titles, whatever it is.

30:25 - And it’s becomes extremely useful. Something that you probably wanna collect early on, so say you first compromised the G Suite employee.

30:31 - You wanna use this, to immediately mine all those data out, because say you get revoked by an administrator who catches you, or they basically figure out that you did this phishing campaign and revoke your app, delete all of your implant stuff.

30:46 - So having this data is very, very useful for reentry, because you can make a much, much more well-planned attack now that you have a good idea of their entire organization, via this API, so highly recommend this as an avenue.

31:01 - So let’s talk about escalating our privileges, right? Let’s sort of talk about how we can increase what privileges we have and get access to more things.

31:10 - So, one thing that is a very good source of privilege escalation is legitimate internal Apps Script apps that are developed by people inside of a G Suite organization that are attached to Google Docs/Sheets/Slides, stuff like that.

31:26 - So recall earlier we talked about Apps Script as being able to be, we talked about being bound to a doc or a sheet or a slide.

31:33 - And this file that a script is bound to is called its container.

31:38 - And so one of the things we have to ask ourselves is say you have some Apps Scripts attached to a doc, right? So in this case, do they have separate ACL? So, can you make it so they can only edit the script, but not the doc? How does that, how does that work exactly? So if you read the Google documentation, they actually share their ACL exactly with this container.

31:58 - So if you have a Google Doc with some Apps Script attached, and somebody has edit permission on a doc, they by proxy have edit permission to the script as well.

32:09 - So this leads to some more interesting questions, right? So you recall the edit access is required as I mentioned earlier, to even run the Apps Script, that’s attached to a doc.

32:16 - So they can’t even use your application unless they have edit access to your doc.

32:21 - But if they have edit access to the doc or sheet or slide or whatever, then they also have access to be able to edit the Apps Script that’s attached to it.

32:29 - So how does this work? We have a bunch of people that all sharing the same doc or sheet or slide and using the Apps Script attached to it.

32:37 - So in this given situation, right, you have one app say, this is access to these employees, like Google Drive, BigQuery, stuff like that, it’s automating some process for them.

32:46 - They all have to be granted editor access on the doc in order to be able to use the Apps Script.

32:52 - And they’re all sort of sharing it together.

32:54 - So they’ve all authorized this thing, to access their services on their behalf.

33:00 - And then you have one user that’s malicious, and of course they have editor access in the doc.

33:05 - They go in and use their editor access to modify the Apps Script attached to the doc, to contain instead of the legitimate script, a malicious payload that does something nefarious, right? Maybe it like exfiltrates the docs that they have access to, that the attacker doesn’t have access to something like that.

33:18 - And then when the regular users come along and they trigger the Apps Script, like they regularly do.

33:24 - The malicious code now runs them, so this becomes it’s basically very, very hard to write an app like this securely, because just in the way that the system is designed, you have to get people edit access and when you do that, then you have access to edit the Apps Script and so any shared documents with scripts attached to them, become very exploitable.

33:46 - So we can do actually even do one better than this.

33:48 - So this piece of tech kind of implies that you have to wait around for these people to trigger this Apps Script, that’s attached to the doc.

33:54 - And as attackers, we’re often quite impatient.

33:57 - We’d rather force this to happen right now, so this can be done essentially by, you can force a re-trigger by basically going to the Apps Script and you can publish a web endpoints.

34:07 - And when you publish this, you essentially get a URL.

34:10 - And that URL, if it’s visited by any of these users that have authorized this app, it will immediately trigger the script to execute us then.

34:18 - And this is actually really nice because it doesn’t, it’s not just they have to visit it, in their web browser, they can visit a web page that simply has an image in it that links to this URL.

34:28 - And it will completely, that works completely fine, it will execute the script as them, just from an image that links to this.

34:37 - So the way that you do this is you just go to the Deploy menu in your Apps Scripts, you do New Deployment, you do a deployment type of web app.

34:44 - And you simply say, “Hey, when people hit this endpoint, I want to run as the user who’s accessing the web app and deploy it.

34:53 - When you do that, you get this nice little URL back, and this is what you can basically do you can put this inside of a image tag or something, or somehow get the victim to visit this in their web browser.

35:04 - And this will trigger this script to automatically run as them.

35:10 - So another useful technique for lateral movement inside of a G Suite organization is enumerating and joining open Google Groups.

35:20 - So to talk about Google Groups, right, Google Groups are used for ACL and both Google Cloud in GCP/IAM settings and for a variety of G Suite style services, right? So they’re used extensively in ACL.

35:34 - But in addition to that, they’re by default, when you create a Google Group instead of a G Suite org, they’re openly joinable by everybody internally.

35:42 - So by themselves, neither is an issue, but when you put them together, this is actually not so great, right.

35:49 - something that’s used extensively for ACL’s being by default widely open and insecure.

35:55 - So anybody inside the company can join and basically grant the permissions of this ACL just by joining your group.

36:01 - This is a being kind of basically a factory for endless privilege escalation, right? So oftentimes searching and joining Google Groups is a great way to just escalate your privileges inside of a Google G Suite organization.

36:14 - So what all can be gated by Google Groups? So we mentioned Google Cloud and all the services under it, right? I’ve mentioned Google Cloud functions, but it’s also stuff like Google Drive, Docs/Sheets, whatever things like Google Calendar Data Studio and even G Suite Admin ACL groups.

36:33 - And it could even use for stuff like publishing Chrome extensions.

36:36 - So most Google services have some sort of ACL integration with Google Groups.

36:41 - So tons of places to escalate your privileges.

36:45 - So talking about this in the context of like, if you have an Apps Script implant, unfortunately modifying Google Groups via Apps Script is not as easy as it sounds.

36:54 - For some reason, unlike all the other sort of Google services, the Google Groups API is, which is known as the directory API it’s restricted only to admins.

37:04 - So only G Suite admins can actually utilize the API, but there is another API which is called the cloud identity API, and that is available to all users.

37:13 - So your Apps Script implant could make use of it.

37:15 - And this allows some access to Google Groups via the API.

37:20 - So there’s some stuff that you can do with this is you can list all the Google Groups, they give an organization, you can list the members of the Groups, their roles.

37:26 - And you can also, you can create your own Google Groups.

37:30 - You can update them, delete members, stuff like that.

37:33 - And you can manage stuff that you create. But unfortunately, the one thing you cannot do via this API, is you can’t join an open Google Group, which is super unfortunate.

37:42 - But, if you did have that, if you did have a full level access to the G Suite account, joining open Google Groups is a great way to sort of escalate your privileges.

37:52 - So now we talked about escalation, let’s talk about, sort of stealth and persistence, right? When you get access to a victim, you don’t want point in time, you want persistent access, so you can keep fooling around inside of the organization.

38:06 - We’ll start off by talking about some Gmail trickery.

38:08 - One things that recommend with your Apps Script implant using your API access to Gmail is create filters in Gmail to essentially hide security notifications.

38:18 - So things like the emails that say, “Hey, you just granted access to a new Google App”, those kinds of notifications, you can hide them from the user.

38:27 - You can also create a bunch of filters to hide password reset emails.

38:30 - So you can basically when somebody gets inbound password reset email, you can hide it in either their trash or some other folder so that they don’t see it.

38:39 - And since people’s email accounts tend to be the center of all their security, you can then basically, later on, you can essentially do resets for all these sub-accounts, use the Apps Script to pull the password reset email on them and thus get access to them.

38:54 - Unfortunately, when it comes to creating an forwarding addresses and stuff like this in Gmail, you can’t do this via the API, but we will talk about if you have the full access to their account, if you have the full UI access to Gmail, you can do something that’s called adding a forwarding address.

39:11 - This is super useful for persisting access.

39:13 - Essentially, the way that it works is you can set it so that you have an external mailbox, something@yahoo. com or whatever the external email is, and you can make it so that anything that matches a given filter, or even just every email they receive, a copy of that email will automatically be sent to this other email box, right? So this way you can basically get a copy of all their stuff that’s coming in to them.

39:35 - And you can set this to either delete the email or just make a copy and not make any changes.

39:42 - So this is a super good way to sort of keep persistent access to their stuff.

39:46 - Even if you end up getting revoked or ripped out later on.

39:52 - So one of the things we talked about with this historical campaign where they used an app name of Google Drive, having a deceptive app name is quite useful.

40:01 - So you can tell that you can see here in this little demo, if I try to set my Apps Script app name to Google Docs, when you actually go to the permission prompt there, it shows it won’t actually do it for you, right.

40:13 - It says it’ll basically deny us as still on type of project.

40:17 - It won’t send it to Google Doc, because that’s a misleading name.

40:20 - It knows you’re trying to do something fishy there.

40:22 - So essentially prevents you from setting a app name like that.

40:26 - But and if you look into some of the stuff that they’ve implemented after this Google Doc worm came out all of the sort of like, when they were doing the tricks with the Unicode characters to essentially get the same looking name, to an official Google product, all of that has been pretty well stripped out.

40:44 - they have a good system for preventing you from setting G-Swedish O-O-G-L Docs, all that’s prevented.

40:52 - None of the, no-width-space tricks, any of that works.

40:55 - But I did find that you can use with the magic of what’s called the Right-to-Left Override character.

41:02 - So for those of you that aren’t familiar, what this is, it’s a Unicode character that you can paste in.

41:07 - And when you paste it, all the characters that come after it end up getting put in reverse.

41:12 - And so in this case, you can see, I basically paste the character in and I go on to type in Google Docs backwards.

41:19 - And because this is reversed from right to left instead of left to right.

41:23 - It actually appears in the prompt as Google Docs, right? So we’ve completely bypassed this protection by using this.

41:29 - And when the user actually goes to approve this, they will just see a Google Docs just as they did with the initial sort of Google Docs worm.

41:39 - So in our thing we wanna do right is likely perpetual Apps Script execution.

41:43 - So we want our script to continually have access to their account, we don’t just want like, we authorize it, it runs once, that’s it.

41:50 - We wanna keep access, keep persistence and keep around so we can figure out what’s inside the org and do our thing.

41:58 - So Apps Script has a really useful feature, which is time-based triggers instead of cron-style stuff that I mentioned earlier.

42:03 - And this allows for background execution on a schedule, and this can be run as often as every minute.

42:10 - And it executes, of course, as whatever user was running the script that ended up programmatically creating this trigger, right? So you can see some example code here.

42:18 - We’ve got ScriptaApp. newTrigger. It creates one that runs every minute and this we’ll run our some function call every minute or so.

42:28 - Now, if you read the documentation on this, it says in order to do this in order to run these background scripts, you need to request the specific scope, which is Script. ScriptApp.

42:38 - And this will cause this little thing to come up in your OAuth prompt that says, “Hey, allow this application to run when you’re not present”.

42:44 - So it explicitly warns the user that this is running in the background.

42:48 - It will run continuously even after you’ve approved it once.

42:52 - So it turns out that this is more of a suggestion than it is a hard rule.

42:58 - They say you need to do this, but as it turns out, it’s more of a suggestion, really.

43:03 - You could still create time triggers programmatically without declaring the scope.

43:07 - And as long as you declare some other scope of any type Google Drive, Gmail, whatever it is, as long as they authorize those, you can programmatically create, time triggers all you want, and they’ll execute it just fine.

43:18 - So you can use those to persist indefinitely without any of the OAuth warnings to the user.

43:25 - So more of a guideline than a strict rule. So great.

43:31 - We’ve covered a variety of topics here around how you can sort of do everything from pierce the perimeter, escalate privileges, pivot around, persist and stuff like that.

43:40 - So thank you all for taking the time to see my talk and be happy to answer any questions that you have. .