A while back I was tasked with performing a Red Team engagement on a tech company with a mature security program. Aside from all the normal technical testing, I wanted to run a phishing campaign to see if I could find a way to gain access to some of their highest value assets. The company has a talented, engaged, and proactive security team with a public bounty program boasting one of the highest payout tables around.
Scrolling through their company-wide security Slack channel and seeing tons of engagement from all teams posting security related articles, technical blogs, and discussions, it was clear security is ingrained in their culture far beyond the security team. At that point I realized that phishing experienced, tech savvy, and security aware employees was going to take something a little more creative than your run-of-the-mill campaign. Here’s how I managed to leverage their own application’s logic to gain access to some of their most critical assets.
Note: I use “example.com” throughout this post as a reference to this organization.
Single Sign-On
As with most companies they’re reliant on an identity provider for authentication, in this case Okta. It’s a double edged sword. Great for access control/logging/removing passwords etc. but risky in the sense that if an employee’s Okta account gets compromised it’s basically game over. Naturally that makes it the top contender for my campaign.
Creating a page
First we want to develop a replica Okta login page capable of stealing full sessions. Easy thanks to the incredible work of Kuba Gretzky in developing EvilGinx.
Choosing a domain
Hosting the page on a convincing domain isn’t as straightforward as you might expect. Google automatically looks for and blocks suspicious domains which mimic popular services. I had a killer phishing domain that included the word “okta” in it, and within 40 minutes it was completely blocked on all browsers. Aargh!
Not only that. If a company uses a brand monitoring service such as MarkMonitor, that will also trigger alerts. So you need to find something that’s believable, won’t get flagged by Google, and won’t trigger any monitoring services. The best way to do this is to completely leave the company name and “Okta” out of the domain.
Doing some recon I noticed the internal domains were often variations of shortened domains with the brand initials. This made things easy as I was able to register a domain that nobody had seen before, but one that users would assume is legitimate because of the existing variety of internal domains.
Add the word “secure” and “okta” as subdomains because that means it’s legitimate of course! The full domain looks like “secure.okta.exmpl.com”.
Make sure any domain you register for your campaign you visit in multiple browsers, and wait at least a day before using it to make sure it doesn’t get hosed. A real tragedy would be sending out your campaign and having Google block it shortly after.
Getting the link into an inbox
The next step was by far the most difficult and the meat of the post. Remember, this isn’t some corporate phishing exercise where all the user has to do is click a link. We need a high number of employees to visit our page and hand over their full Okta credentials without thinking twice.
The challenges:
- Google will likely identify an unsolicited email with a link as a phish or spam. They’ve gotten pretty decent at this and throw enough warnings where I would consider this a failure. You might get someone, but our goal is to compromise as many high value accounts as possible.
- Companies often add [EXTERNAL] tags or labels to emails coming from non-whitelisted domains, putting users on heightened alert.
- Having a call to action (CTA) convincing enough to get savvy users to enter these credentials might be a little tricky.
The solution — Leverage the application
The way we can bypass all these restrictions is by sending an email from the company itself. Most applications send emails on various actions. Sign up, password reset etc. Can we hijack any of them?
The application I was testing had a section for SAML authentication. Not to get into the details of SAML; but at a high level, the Service Provider (SP) redirects to the Identity Provider (IdP) such as Okta for authentication. This is referred to as SP initiated auth.
When an organization sets up SAML on their account they choose the URL for the IdP. This is so when a user visits example.com to login, they can enter their email and get redirected to the IdP which authenticates them, and then POSTs the SAML response back to example.com to authenticate them without a password. The key part here is that the IdP URL is user defined. If I make my IdP URL my Okta phishing page, now users will be expecting to go to a legitimate IdP but land on my malicious page instead.
This gives us an open redirect from the company site to the phishing page, which we now need to get into a user’s inbox. Luckily a common flow is to allow organizations to invite other users, which sends an email to them with a CTA such as “[Company] has invited you to their organization, click here to join”. In this case we can name our malicious organization something convincing such as “[Target Company] testing”, or “[Target Company] experiments”.
Using this feature we can have a legitimate email come from the company itself into employee inboxes with the primary CTA being a link to a phishing Okta page. This allows us to send targeted phishing links to individual employees, but can we do better?
Posting to internal mailing lists using Google’s intended behavior
There’s an unexpected and kind of dangerous behavior with the way Google handles mailing lists (Google Groups) which can allow outsiders to post to them using application logic. It’s the fact that Google allows managed domains to post to internal Groups from any email address on the domain, regardless of if they are a defined user in the organization. For example: If the Google Group allows the “Entire Organization” to post (default when creating), an email such as non-existent@example.com or a managed non-existent@sub.example.com can post internally to any group under example.com. I reported this to Google and they closed the report as intended behavior.
Putting it all together
Since the organization invite emails were being sent from a no-reply@mail.example.com, I was simply able to invite common mailing lists such as engineering@example.com as users into my organization. Doing so would end up posting to the internal group and send out the malicious organization invite to hundreds of employees. Few things will look more legitimate to a user than an email to them from their own company posting to an internal mailing list. In a short time frame I managed to capture a bunch of full Okta sessions, with the first victim minutes after sending out the invite.
Bypass to launch MFA protected apps
The Okta instance was set up such that sensitive apps prompt MFA to launch. This can be an effective security measure as the attacker doesn’t have access to your MFA device, and you cannot add another factor without confirming an existing one. The caveat in the implementation is that after authenticating there’s a couple minute window where MFA is not prompted again to add a new factor. This means that after stealing an Okta session, the attacker can quickly visit the user settings page and add their own factor without being prompted for the existing one. Afraid they’ll see an email notification that a new factor was added? Use Okta to login to their email and delete it. Once an attacker adds their own factor they can launch protected apps and authenticate freely into the account with the captured password.
Takeaways
As convincing as it was, not everyone fell for the phish. Here are some of the users I was unable to capture:
- The users with their second factor being a FIDO device, which cannot be phished.
- The users with a sharp eye who noticed the login page is not actually on their Okta domain.
- Some of the users that were using password managers and noticed auto-fill wasn’t coming up, after which they then noticed the domain was fake.
Those users were quick to alert the IT team to investigate the issue who then had the ability to purge it from inboxes.
Phishing is still one of the leading causes of breaches and I believe attacks will continue to evolve past the basic training we’re all given. In this case I was able to compromise highly technical, smart, and well trained individuals by using an attack which leverages the application itself. A few technical solutions can be used to prevent this and similar types of attacks.
- Require FIDO as a secondary factor and disable other factors.
- Do not allow user defined links or redirects inside of emails sent from the application.
- Send emails from a different domain so internal mailing lists cannot be posted to, or only allow posting from “Group Members”.
Who else is vulnerable?
I would say most companies which have SSO and a similar organization invite structure. I can think of a bunch of high profile services off the top of my head I would love to test. Unfortunately, phishing is almost always out of scope for bug bounties and public security testing.
Thanks for reading and I hope you can use this information to secure your organization’s assets!