 So please join me in welcoming Carla. Hello, everyone. I hope you enjoyed Eleanor's keynote this morning about complex systems and the way they interact with humans in particular. So today I'm going to talk about everyone's favorite security interaction with humans, which is fishing. A little bit of background for me just to recap. As I said, I do a lot of internal fishing at Stripe. It's actually a side project for me. I typically defend our users, and internal fishing is more about defending the company, but I've actually run a bunch of these tests in the past, and they've been scarily successful, so I wanted to share the things that I learned from doing that, and hopefully we can help improve the industry as a whole. So let's chat about what fishing really is, just again as a recap. It's a pretty big space, and there are a lot of different targets and a lot of different actors. There's been a couple of historical, very large fishing campaigns. You've probably heard about them. One RSA was actually fished via social media. They had a flash malware bug in Excel that they exploited, and they used that to compromise the secure ID 2FA database. So those RSA tokens, the physical ones that you have, they compromised the master keys for that. You can see how this could be a problem for security as a whole. In 2014, ICANN had their centralized zone data system spearfished. The admin credentials for that were stolen, so that kind of compromises a lot of the integrity of the internet. And also in 2014, Sony had some Apple ID fishing via email verification for Apple ID, and that's what led to the whole North Korea, the interview, that kind of hack. And that's very interesting to me, because that's actually why Stripe started doing these campaigns in the first place. We took payments for that movie, and given that we had the potential for North Korea to be fishing us, we thought maybe we should do some fishing of our own. So for this talk, I'm going to cover a specific set of cases, and that's those where you control the platform of your targets. So normally in my job, I would worry about our users being fished, but for this talk, I'm talking specifically about employees being fished. These are cases where you have more control over the person who's actually being targeted. And I'm also going to talk about targeted attacks. So I'm not talking about the lowest common denominator, like those emails you get with spelling mistakes. We're going to talk about emails that are specifically targeting the company that you're trying to protect. And we're going to do this in three sections. First of all, I'm going to talk about the psychology of fishing, why people fall for it. Then I'm going to talk about fishing at Stripe, what we learned, what we did. And finally, I'm going to talk about some solutions and things you can do to prevent fishing at companies you care about. But this is kind of your stereotypical fishing email. You know, a Nigerian prince really wants to offer you a large sum of money. And these type of emails, they make attackers and defenders really lazy, right? Attackers get forbidden from fishing because it's, you know, it's a given. The standards train their users to detect this sort of email, and then they say that their job is done, right? Like, if the user doesn't believe that a Nigerian prince is out to help them, you've done everything within your power. This is pretty dangerous because just because you say that fishing is inevitable, it's going to train your employees once a quarter across your fingers and hope that they don't click. That doesn't actually make the risk go away. It's still a problem. And it really encourages this us and them mentality and security. You know, I am the security expert. I would never fall for a fishing campaign. But those people who do, you know, they didn't spot the smelling mistake. They didn't spot the obvious link. They didn't spot the psychology of what was going on. And I think that's wrong. So I want to talk about why people fall for fishing campaigns in the first place. Daniel Kahneman's written a really interesting book about this. It's actually specifically about how humans process information. And he posits that there's two different modes we use to process information. System one and system two. And system one is below what we'd consider to be the level of conscious thought. You've been driving on the highway and the car in front of you stops suddenly and you swerve or slam on the brakes. You didn't think about the fact that you were going to swerve or slam on the brakes before you did it. It just happened. That's your system one mode of thinking. It's fast and it's instinctive. On the other hand, if you've made a large investment, you've made a list of pros and cons, you've tried to decide which list is longer than the other. That's system two. It's much slower and more methodical. And system one is really important because it operates very fast. And if you're on a highway, you don't want to weigh up the pros and cons of swerving. You just want to do it because you don't have enough time to spend on that processing. But the problem with system one is it's pattern based, which makes it emotional and it's gullible. And those patterns aren't within our control. It's just whatever your subconscious decides is important. System two, on the other hand, is much more rational and skeptical because you consciously think through the decisions that you're making. So I want you to think about how many emails you read in a day. I know about you, I get maybe 100, 150 emails I have to read in any given day. I don't think I have time to read them with my system two brain. I have to get other work done. And I'm not alone in that. Most people are trying to read a lot of email. They're trying to process it very quickly. And that means they're using this fast and instinctive mode of processing. And the thing is that phishing training, anything you do to try and teach someone to be skeptical, that's all affecting their system two brain, which means it's not very effective if someone isn't already thinking slowly. And you can't train someone to think that an email that looks exactly like every other email they've received from a service is faked. You can convince them that Nigeria and Prince is a little out of the ordinary, that the spelling mistake is a little unusual. But if something looks exactly the same as every other email, they're not going to spot it. And this is something we're all vulnerable to. So given that, I want to put a new spin on how we classify phishing. And rather than focusing on the victims or talking about whaling or spear phishing, depending on exactly who was targeted, I want to focus on the attack vector that's being used. And I think there's three cases here. First of all, there's action-based phishing. This is where your end goal is just to get some significant action taken. Maybe you convince someone on the finance team to wire $10 million offshore. That's your end goal. You don't want anything else. There's exploit-based phishing, which is where you maybe use flash malware and Excel, other sorts of malicious attachments containing malware. You use those to get code execution on a machine. And from there, you pivot to whatever you actually want to do. And finally, there's credential-based phishing. This is where you email a user. You convince them to go to your fake website, type in their credentials, and then you use that information to, in turn, get more valuable things. And each of these different attack vectors require a different type of defense. For action-based phishing, maybe you do something like, say, if you're wiring a bunch of money offshore, two people have to sign off on that. But exploit-based phishing, if you control the endpoint, like you do for employees of your company, you can require that people only install certain software, or you can restrict installation of software you're unfamiliar with. You can patch machines very quickly. But we don't really have a great solution for credential-based phishing. How do you stop someone from typing their password into some random site? It's pretty challenging to do. So I'm going to focus on how we can fix that in this talk. And just an overview of how credential-based phishing campaigns usually work is kind of three stages. First of all, you have a hook, so this is the email. You want the email to seem very ordinary, but it needs to contain a call to action. You know, if you don't do this, your credentials will stop working. If you don't do this, you'll lose some pay, that sort of thing. But it needs to look exactly like normal, because you need to keep someone within that system one mode of processing. For the phishing site that you then see, that's where you redirect someone to, where you collect their credentials. You want the domain to be similar to the original, again, all that system one processing. And interestingly enough, you really want to do it over HTTPS, because it turns out users are really good at looking for the green lock now. But that's okay, because we have let's encrypt, so it's not too difficult. And finally, you need some kind of trail out. You need to convince the user that everything has gone exactly as usual, because if they give you their password, but then they immediately reset it because they're suspicious, it's not worth very much. What you need to do is convince them that everything's gone fine, whatever action you put in your email, it's succeeded, and everything is now okay. So that's enough theory. Let's talk real world examples. This is an email that went out to the entire company before we did any phishing training. I want you to sit and think to yourself whether you think this email is legitimate, okay? How about this email? Just to put them side by side in case it's difficult to compare when they're on different slides. You'll notice here that the email is from NoReply at Slack.com in both cases. The footer trunk hates a little differently, but that's just to make them the same height on the slide. It would actually be identical. Both of these have calls to action. Both of them seem pretty normal. In this case, the right email is real and the left one is fake, but there's no way for you to know based on the information in this slide. Short of knowing exactly which email Slack sends. And it turns out to send this email, I actually had to get permission from LVP of Engineering. If you fish the whole company, usually you want to make sure you're not going to get fired for doing so. Kind of helpful. So I told them, I said, hey, you asked me to send, like, to build a phishing campaign. I've just built one. I just sent it to you. Let me know what you think. Is it okay for me to send? He looks at it. He clicks the link and he goes, wait, I know what this is. He knew that I was going to send him a phishing email and he still saw the email and clicked on it. He's the VP of Engineering. He knows full well what a phishing email should look like. He's quite technical. And this kind of leads to a really interesting point that I don't think we talk enough about as an industry, but the easiest way to build a phishing email, just clone a real one. Why write your own from scratch? People send you all this beautiful looking HTML just modify it to point somewhere else. I built this entire campaign in less than a day because we had a bit of time crunch for this particular situation. Now the actual end-to-end conversion rate on this wasn't very high because I hadn't figured out the whole HTTPS thing, so people got really skeptical when they got redirected to an HTTP site. But the email itself was quite effective. But an interesting thing here is that this exact campaign isn't actually possible anymore. Many companies, including Slack in this case, have started to adopt domain protections which make it harder to spoof email from them. In this case, they actually have SPF turned on. I'm not going to go into too many details on these policies, but essentially they restrict the IPs that can send mail from Slack.com. They also have Deakin signing turned on, so they use public key cryptography to sign their emails, but they don't have a DMARC policy, which makes the Deakin not that useful. Essentially, DMARC lets you enforce the emails from your domain assigned, and they're not doing that. But the most important takeaway is we have these policies and maybe they make it harder to spoof email from a given domain, but the recipient's mail server needs to know to check for them. They're not built into the protocol, and that's not the case for all recipient mail servers by any stretch. Let's go back to some real-world examples, though. Well, fast forward several months. There's been some more time. Everyone's seen a phishing campaign before. I wanted to say, well, you know, it's not some information from Slack, but code exec would be way more interesting. Why don't I try and phish for GitHub credentials? If I have GitHub credentials, I can add code to the code base and hopefully get it deployed by some engineer later on. So the interesting question here was, is this message legitimate or not? It's actually a legitimate message that GitHub will show you. It tells you you need to re-approve your SSH key in certain situations, but it's not an email that they'll ever send. You'll usually see it when you try and commit code. However, the SSH key fingerprint here, that is real. It really was any given person's public SSH key fingerprint. And people told me that they used this to determine that the email was legit. No one else would know their fingerprint, so the email must be real. But GitHub have an API for pulling public keys. We can just generate fingerprints based on that. It's quite important that you pay attention to which pieces of information in an email are actually authenticated, which things you think are secret are not really. And the email presented an interesting challenge from a scientific perspective. Should I send it in plain text or in HTML? GitHub send all of their transactional emails in plain text. They send some marketing emails in HTML because typically people like pretty emails, but their transactional ones are entirely in plain text. And this was a really interesting thing for me. Should I try and get the highest conversion I can using HTML, or will people be skeptical that this email looks different to all the other emails that they get from GitHub? So I ran an AB test. 50% got plain text, 50% got HTML. We saw about 10% conversion on the plain text email, and we saw closer to 50% conversion on the HTML one. Turns out all those marketers are right. People really like pretty things. And those emails, I cloned them to look like GitHub's website. So they still didn't look that out of the ordinary, but I thought it was pretty interesting that emails don't need to look like the real emails from a service to be effective. This was the phishing page that I used to harvest credentials in this case. So there's the two of them side-by-side. Both of them are really hosted by GitHub. The one on the left is obviously the real one, and the one on the right is a phishing page. It's logln.github.io, in case it's hard to see from the back. And this is because github.io is GitHub pages. It's user-hosted content. And at the time, food.github.com, if it didn't exist, would redirect to food.github.io for historical backwards compatibility reasons. So if you hovered over the link in the email, it looked like it went to logln.github.com. That's pretty hard for a user to detect. And that subtle domain difference.io is user-hosted content, and .com is real content. That's really hard for users to know. How am I, as someone who never uses GitHub pages, maybe, supposed to know that .io is user-hosted content? You really need to make it obvious to your users whether or not they can trust a given domain. And I decided to do some more science on this campaign as well. So I had quite detailed analytics I knew when people opened emails, when they typed things into the password field, and when they submitted it. And this was cool because I could tell whether or not someone was typing into the field or pasting into the field, like they would if they used a password manager. And in fact, we installed password managers on every employee's machine when they started Stripe. We trained them to use them. We tell them to use them. 50% of the people who fell for this campaign copy-pasted credentials into this page. They went to a page, they were told by their password manager that it wasn't the right domain, and they ignored that advice and did it anyway. And it's not that surprising. If you think about the number of times you've seen Chrome say, I've disconnected from one password. Can't really help you now. You need to restart your browser. That's painful for users. And they walk around it by just ignoring what their password manager says after that. And finally, for completeness' sake, this is the trail-out page that I had. This is hosted on real GitHub. It's a page that's related to the email you'd have seen. It shows that your keys are okay, and it'll have the same fingerprints as the one that was in the email. And at this point in time, people start to mention 2FA to me. You know, you're phishing, but I'm safe, because I have two-factor authentication turned on. There's no way you could get me. So if you use TOTP 2FA, that's Google Authenticator, AutiStyle. I can just fish for that as well. It's just another piece of credential. Oh, it's just another credential. Sure, I'm only going to be able to log in once, but that's probably enough for me to pull any information I need. And if you use SMS 2FA, well, here's a great screenshot from a couple of days ago from someone called Rachel Toback. In case it's hard to read, the general gist of it is someone texting someone else saying, hey, I used to have your number, and I need to get a 2FA code. Do you just respond with the code that I need to log in? People do it. People want to be helpful. So someone responds. But to be fair, I wouldn't need to know your phone number to do that, because any services don't reveal it. Instead, I just pop proxy a live login request to the service that I'm trying to fish. They'll send you a text message. I ask you for the code, and then I submit it to the real site. You'll never know the difference. SMS 2FA is not going to help you any more than TOTP in this case. It just requires it to be a little more live. And this is the thing. 2FA is a really valuable thing to have, and it gives the value of one-timeness. A given set of login credentials are only valid once. But it's really trying to solve a different problem. It's trying to solve the problem of shared credentials between different sites, password dumps from a site that's been hacked. It is incidentally making fishing a bit more difficult. But it's only by a little bit, and it's really not what it's intended for. Now, at this point in time, I was starting to become pretty skeptical of the value of fishing training. We've been doing fishing training. People have been following the sites. How effective is our training, really? So I had this really great idea. I thought I would show a fishing campaign during our training. I wanted people to pay attention, and it was a really dangerous target. I'll pick, like, Amazon. So, you know, if you get enough Amazon credentials, you can probably get root on a sub. It's honestly better than CodeExec. And I wanted to show this campaign to people, wait a couple of months, and then actually send it, and see who picked up on it. Our fishing training is interactive. It's quite similar to what we've done today. Show examples of different sites, have people guess which ones are fishing, and then tell them what they could have looked at to tell whether or not something actually was fishing. Amazon AWS IAM login page. This is what enterprise users see when they're trying to log into AWS, typically. And you can see the URL here is very complicated. It's very hard for you to tell that it's legitimate by eye, because it's quite long. And so the lesson that I wanted to get across to people here, and the lesson we emphasized was, complicated URLs are easy to fish. Be careful if you see a long URL. I smoothed an email from the head of our security team. I used a Gmail bug to bypass some of the SPF and DQM protections that we would usually have in our own domain. And in the email, I sort of waved away password managers not working. You know, it's a beta site, don't worry about it too much. Because, you know, given a plausible enough attack, users will just copy credentials out of their password manager. So I just needed to give them some pretext for why they weren't seeing what they'd expect to see. In this case, I fished for both password and 2FA credentials to demonstrate that you could do so. And I had a lot of analytics again. So I knew that given that you opened the email, 40% of people clicked the link in it. Given that you saw this page, 2 thirds of people entered their credentials. I sent this email to the entire engineering department. So you can imagine how many people this is and how bad it would be for these credentials to get out there. And interestingly enough, those 2 thirds of people, they included two of my friends who helped me build the campaign. They didn't know exactly what the campaign was going to be, but they knew that I was running something pretty sketchy in the next week and that they should be on guard. So this leads us to a pretty depressing industry state, right? We have SPFTKM and DMARC and they give some protection of spoofing your domain in an email, but it's really not perfect. It only protects some people and male clients don't always enforce it. We can encourage the use of password managers, but users will just ignore what their password manager says a lot of the time. And we can mandate 2FA, but it's just making it more difficult. I'm all for realistic solutions rather than perfect, but some of these things are difficult to overcome. They're not even technically difficult, they just require a little bit of motivation. And this leads to a sense of hopelessness, right? Security teams start to say, well, phishing is inevitable, what's the point? We'll train users, we'll do our best, but in the end, something bad is going to happen. And that's really dangerous because you can't do incident response sufficiently quickly to protect yourself against this type of attack. It takes you 5 or 15 minutes to get to a pager. Let's say in the best case scenario where a user knows immediately afterwards, think of the amount of data I could pull with a script in that time. And I can write a script ahead of time because I'm just using public services, so I can test them on my own accounts first. And in the end, this is because any protection that relies on a human making a reasonable decision is going to fail. Humans are fallible, they're easy to convince of, like, anything, what you really want is a technical solution to this problem. So let's go back to the beginning. Let's go back to how authentication works. There are different types of authentication that we usually talk about. So we've got something you have, like a 2FA device, something you know, like a password, and something you are, say biometric data. Usually when we talk about 2FA on the Internet, we're talking about something you have and something you know, because web standards for biometric data are not super set in stone, and often we have a bit of a debate as an industry about whether biometric data is a username or a password, given that it can't be changed. We have one of these factors away to the wrong side. In practice, that usually means tying a credential to a service cryptographically. Often you do it with something you have. And we do this at Stripe. We use SSL client certificates to authenticate almost all of our internal services. These are like cookies, but they use public-private key crypto, so your machine has a secret. When you try to access a service, you get a nonce, you sign it, and you respond, but the service can tell that you are who you say you are because they have a copy of that public certificate. And this is really great for a couple of reasons. One of them is it's really hard for a user to accidentally leak this because they'd have to go into, like, the certificate store to extract the certificate and then send it to someone else. It would seem very unusual. And it's also a really great user experience for non-technical users. They just go to a site. It just works. They don't have the type of password in. But unfortunately, it's similar to a password in that it's often very long-lived. Someone gets access to a client certificate ever. Maybe they have access to your machine somehow. That's catastrophic. And there's no way to detect it. What we really want to do is add one timeness to this system. We want the same property that a given set of credentials are single-use, but we still want them to have cryptography because otherwise you can fish for those credentials, too. And luckily, this protocol exists. There's a protocol called U2F. You've probably seen it before in the form of YubiKeys. And essentially, the way this works is when you try to 2FA using a YubiKey on a given website, your browser sends down a challenge to this USB key that you've got plugged in. It contains the domain name that's asking for a 2FA credential. The key signs a response that's valid just for that domain and then sends it back to the browser who provides it to the web page. So even if I as a fisherman manage to convince you on evil.com to tap your key, you get a credential that's only valid for evil.com, not Google or Facebook or any of the other services that I could be trying to fish. It's really cool. Google actually let you mandate the use of security keys on your domain these days. You can forbid other types of 2FA. And there's a lot of other services that you can support, particularly more tech-focused companies, Dropbox, Facebook, GitHub and Stripe also support it. And Intel's been building support into their recent chips, so you don't even necessarily have to have a dedicated USB key. But that doesn't provide a solution for all of those legacy platforms that you need to integrate with that don't have the time to implement this. Luckily, a lot of them do implement a protocol called SSO, which is essentially a way of delegating authentication from one site to another. We build our own U2F authentication provider internally, and then bootstrap any other services we use through that for authentication. And this means when you log into a site, you don't even have a password. If someone asked for the password to a domain or to a service that we use at Stripe, users mostly wouldn't know what to provide because they don't have that credential at all. They just have their machine and a USB key, and that's how we're doing a lot of authentication. Of course, like every trade-off or like every engineering decision, there are some downsides. It's quite difficult to use from a lot of mobile devices, and particularly from iOS, which is a bit more locked down. And that means that you usually need to allow users to fall back to another type of 2FA. But the hope is that if a user has to stand up from their machine and walk over and get their phone from the other side of the room, that's enough time for them to think about what they're really doing and whether or not this is a choice they actually want to make. That's enough time to trigger their system-to-thinking. And it's also subject to protocol vulnerabilities. So back in March at OffensiveCon, two researchers, Marcus Vervier and Michele Roux, actually abused the new web USB protocol that exists in Chrome to send requests to a UBKE that weren't really from the browser. They weren't from a trusted context. They were just pretending that they were from a trusted context. And that let people get these U2F credentials anyway. At least this is something we as a security community can address, though. This is not a hard-to-fix human problem. This is a technical restriction. And the final thing is U2F really only protects authentication flows that ask for 2FA credentials. Not all phishing needs a password. So who remembers the Google Docs attack from about a year ago? There was a worm that went round. Everyone got to discover what HHH at mailinated.com was. Essentially what would happen is you'd get an OAuth request, you'd click yes, it would take a look at all your contacts, and then send to all of your contacts an email saying, hey, would you like to access this Google Doc? People would click yes, and then the worm would spread. In this case, we're very lucky that this was just someone who was basically a script kitty. I think it was ever really exploited, and it technically affected a very small percentage of Google Docs users, though I still think the absolute number was quite large. But it was pretty cool, because we weren't affected by this at all. Stripe didn't have this problem. And that's because I ran the same campaign a year earlier internally. We don't use Google Docs a lot internally. We use a service, or at the time we use a service called Quip for document sharing. This was the hook email I sent. It looks very similar to real emails sent from the service, otherwise it's pretty similar to the Google Docs one, except it's sent directly to you, rather than to HHHHatMailinator.com. And I thought this campaign would be way too cliched. You know, the CEO is emailing you about compensation, the sender of the email isn't right, because SPF and Deakin were set up correctly on this service. We actually saw kind of terrifying conversion rates. This is the prompt that users would have seen. It was hosted on Google.com, the real Google.com. It's for a spoofed application, but there's almost no indication that that's the case. And if you granted access, you'd get some kind of 404. We saw extremely high conversion rates on this, higher than I've seen on any other phishing campaign that I've run, because users just didn't have enough time to slow down and think about what they were doing before they clicked the allow button. They didn't even have to think about what their password was. And just as a demonstration that really anyone can fall for this, I have a friend on the security team who usually reviews my phishing emails because I want to make sure they don't have spelling mistakes and that there's nothing that obviously gives them away. So I'd asked him ahead of time, you know, is it unethical to fish for a while if I think this will be too easy? And also, could you invite me to a document on Quip? It'd be really useful. He's like, cool, sure, sends me an email. A couple of days later, I send him a phishing email back and I say, hey, let me know what you think of this. It's kind of late at night, so I wait till the following day, still no response, wait till lunchtime, enter the business day. I'm like, okay, you've heard like eight hours now, like that's enough time to review a phishing email. It really doesn't take very long. He goes, oh, I didn't get it. Like, technically that's possible, but I think it's pretty unlikely. Here's the subject, he's like, nah, nah, I can't find it. Took like three goes for me to finally convince him that he had received the email. He'd in fact gotten it, he clicked the link, he'd seen the permissions it was asking for, he'd said, that seems really sketchy. I was in the process of writing a really nasty email for the service provider about how they shouldn't be asking for these permissions. This is someone on the security team who knows which campaign I'm going to send, when I'm going to send it, and what it's going to look like. They still fell for it. This is something that affects all of us. I'm just going to wrap up. Well-crafted phishing campaigns, they pose a real danger to organizations. And if you ban them from your red team exercise, you're just totally ignoring one scary problem to focus on another one. And that phishing training we do that we say is really important, it is, but it's only going to help users in a very limited set of situations. Situations where the email is pretending to be, is asking you to do something that's very unusual. They're asking you to confirm your email address. People do that all the time for all kinds of services. And it's going to be very difficult for you to convince a user that that's not or that that is phishing. And finally, it is possible to protect your users without them even knowing that you're doing it. And you should, because if you don't, you're doing everyone a disservice. Because most of all I want you to remember that anyone can fall for phishing. Because in the end, we're all human.