Thanks for tuning into our talk. I'm Spencer Cureton, and with me is Alan Sagenovic. We are on the abuse operations team at Heroku, where we keep users from doing bad things on, to, and from the platform. We're like mall cops for our corner of the internet. This talk focuses on abuse and how we hunt for it on Heroku. So Heroku is a platform as a service that was purchased by Salesforce about 10 years ago. It provides an easy interface to quickly go from idea to online application without having to manage and configure the underlying infrastructure. So to put it simply, we run anyone's code on the internet as directed from unknown sources millions of times a day. Okay, we are RCE as a service. The part of Heroku we're talking about is referred to as the free tier, or the common runtime, where all you need is an email address to create an account. Heroku has other offerings that are not like this, but we won't be talking about them today. Our focus will be on how we defend the common runtime from abusive bad actors. So just defining abuse is a challenge within itself. We define abuse as the unintended monetization of anything. So if you have a free service, a free trial, or any offering that has an angle to extract value, somebody is already trying to figure out a way to make money off of it. It's a very fine line between a business trying to get off the ground and an abuser trying to take advantage of your services. Sometimes it's obvious, like theft of resources. Other times it's not so clear. For example, think about a social media poll. It's intended for honest input, but it's gameable because it's not one person, one vote. It's one account, one vote. So the person in control of the most accounts wins. The problem isn't new, the scams aren't new, but we see them leveraging more and more of the cloud. And we feel like we have a unique perspective that we would like to share. So in a more practical layer, we see a portion of this bigger abuse picture realized through misuse, malice, and crime on our platform. Legal documents like the Acceptable Use Policy, the AUP, provide a list of prohibited content and prohibited actions. So it's the list of don'ts for users to follow, and also acts as a set of guidelines for our team to uphold. Obviously, this can't cover every type of abuse activity. And even if it did, it would act as a laundry list for an abuser to know what kind of badness could be performed from the platform. Let's look at how we group violations of the AUP. There are unintentional and intentional violations. Now, unintentional could be a customer that deploys a poorly written app that consumes more than its share of resources, and now they've become a noisy neighbor. So think about like a runaway web scraper. Not malicious, but kind of like they were accidentally jerks. Then we have the intentional abusers, and these are the folks that make this job really interesting. They have skills that range from script pity to rogue advanced developer, which we call our apex actors. Skids will be skids and deploy code found on GitHub, YouTube, or whatever their buddy gave them to run. At times, we'll get what feels like a swarm of abuse centered around a particular app, like a proxy kit or a peer-to-peer app. Then there are the quick and loud abusers that could care less about being detected and will attempt to stand up a DDoS farm and attack a target as quickly as possible. Now, the actors that are patient, skilled, and criminal are the more dangerous group. These actors attempt to iterate past our detection capabilities. They may try to social engineer support staff in order to gain insight into how they were detected after being suspended, and will try anything to maximize their use of the platform. Now, these users are not exploiting technical vulnerabilities within the platform. They take advantage of gaps in business logic. So technically, everything's working as designed. The majority are not too advanced, but are very persistent. So if you like to think about APT, small lowercase a, big capital P. And again, financially motivated. Now, persistent here means that after an account has been suspended, the same actor will try to create a new account with a different email address or a sub-inbox variant of the original email address. We'll cover a few campaigns during the show and tell section of this talk. Overall, we define our team, Abuse Operations, as a specialized DFIR team that requires a wide view across the business as shown in this slide. Our goal is to push bad actors from the platform and put a spotlight on abuse patterns for engineering teams and the business to address. In order to identify those bad actors and stay on top of them, we need to be proactive and hunt. Now I'll hand it over to Alan to discuss the art of the hunt. Alan? Hi, thank you, Spencer. I'm Alan. I'm Akam on the Discord, if you want to find me later. Now, we're quickly going to breeze through this, how we hunt, mostly just to give better context around the next section, which is really going to be the meat of it. Now, there's a lot on these slides. I'm not going to talk about every point. Just kind of the more interesting stuff, the more pertinent stuff. If you want to hear the philosophy behind this, go look at the talk that we did at that other conference that happened a little earlier this week. Besides, I think that you guys at the Blue Team Village probably do some semblance of this already. So we gather suspicious indicators from any of a number of different places, as you can see listed. For example, an app with an abnormally high CPU would generate some sort of event-based alarm that would give us a hint to go look at it. On the slide, as you can see, there's a short list of some of the indicators that we collect of the various places we collect them from. Now, because we're highly instrumented, and because Heroku runs on Heroku, this is how we can actually gain home-field advantage, by putting these internal and external indicators together. Now, for this moment, just understand that the indicators that we're getting are considered really low-value. By themselves, they don't have any kind of context, or rarely enough context to actually make a decision. Now, given a starting suspicious indicator or two, we form some sort of hypothesis about the intent of the actor. We start looking at related indicators and try to prove or disprove that hypothesis. Now, each of these indicators is not proof of intent of any kind individually, but as you can see by this list, you can see that they collectively start making a really strong case. Collection of low-value indicators does become a very good footprint of malicious activity. To increase the confidence of what we're looking at, we keep asking that question, what else you got? For instance, a face-rolled email address, like the one shown, is a pretty good indicator that the user doesn't really value the account. Same with app names, if they got a face-rolled app name, too. Rumor is a great indicator of badness, though, because it could be just for discarding it. Test, discard. However, a face-rolled email address with a collection of face-rolled app names, in addition to multiple attempts to verify a credit card, is worth a deeper look. We try to establish intent. There are two goals here. One is to determine what the actor is trying to do. And the other is to determine what the actor is trying to do before they do it. Now, the key piece here is that goal number two is something that we reserve for actors that we've actually seen before. Actors that have tried to do something bad before. This is how we avoid a situation of doing pre-crime. We don't want to necessarily kick people off the platform before they've done bad. But if we have indicators that they are a same returning actor that has already been declared persona non grata, then maybe we want to know as early as possible. Now, there is an exception to this. There is software that we don't let people deploy to the platform. But we're not talking about that in any great degree, although we'll mention it later in contrast to other things. Now, making the decision and taking the action is kind of the crux of the matter. We've collected a bunch of indicators that give us a good idea of what they're trying to do. So we take the action. If the intent is bad, then the action is suspension, evidence collection, so on and so forth. If it's not bad, watch lists, allow lists, or false positive checks. And sometimes it's not easy to determine what the intent is, in which case we'll throw it back out of the stack. We'll examine it again should it pop up again in a fresh alert. We investigate for more indicators. Now, really the question here is, have we found all the accounts that are associated with the badness? And have we found all the indicators associated with all the accounts that point to the badness? We cycle this a couple of different times to make certain that we've got as big a view as possible, even retroactively, so we can pick up early starts, early campaigns, so on and so forth. And this is all done to strengthen our ability to do automation. Automation is... we're doing it because, obviously, we never want to see the same abuse again, and this is how we reduce all the toil of all the things that we do. The automation of the footprint includes the alerting and the actioning on a subset of indicators, including what we call a partial match. And then we do it all over again. Now, some of that requires a little bit more. But in a nutshell, if you're a visual learner, here's what the loop looks like. Okay? Let's go next. Within our tooling, we have... is where our codified indicators live. So we take the indicators that we've identified, and it could be something as simple as a substring match on a registration of an email address. Or it could be something more complex, like a Levenstein distance to a particular word, or any of these kinds of things. And we codify them as, literally, as code into any of these tooling. Now, the column on the left, we have an event collection agent, similar to a classic SEM. We have database query tools that'll run automatically or manually when we need to check stuff. And we have malware analysis tools. So we'll do our queries within those tools so that we can actually get these indicators, these codified indicators out. Now, we also have, as everybody, we have a ticket system. Now, the ticket system is not normally considered part of the tooling in a lot of cases. We like to consider it part of the tooling because our ever-increasing goal to reduce Toro means that we also have to automate ticketing where it makes sense or where it's possible as well. And we have our suspension tools. Suspend at various levels, but the really important thing there is that they're set up in such a way that they have business rules and guardrails so that we don't accidentally suspend the entire world if we make a mistake. Now, we track two general types of activities. We track campaigns and prohibited softwares, as we previously said. Campaigns track actors, or sometimes they're victims, whatever makes more sense. And it also tracks the custom software that they might write to be able to do the things that they're trying to do. Whereas prohibited software is tracking malware, tracking C2, tracking known abusive software, including the stuff that has a deploy to Heroku button sitting in GitHub. Now, ultimately, we're looking to track actors. There doesn't seem to be a great way to do this, and we're building up towards more of that. But what we found is that actors really do end up being a collection of TTPs codified as a constellation of indicators, and we call that a footprint. Now, footprints can overlap, partially or fully. And how we implement footprint detection is how we detect actor behavior changes, and multiple actors doing the same thing. Tracking footprints is kind of difficult, though, and we're looking to be improving the process as we go on this year so we can speed up this whole loop. But even today, with what we have, we can detect pivots. A pivot is what we call a change to a TTP of a returning actor. Now, different from a pen tester pivot. If a footprint is a collection of indicators, then given enough of them, a partial match usually indicates a change in behavior of the same actor. Actors are people, too. When an actor gets suspended, they do have this tendency to test how by isolating for variables and making very small changes over time until they get it working again. So from a threshold detection, like shown, works really well as an accurate way to detect their return and still take some action. Then updating the footprint with the new indicators, reflecting the change, just keeps that footprint accurate. And this is designed to make it difficult for a persistent actor to regain that foothold. And it frustrates the heck out of them, and that's always a pleasure. We also have what we call a splash. When we block a particular actor under a footprint, sometimes what we'll see is that we'll see a whole bunch of different footprints or different partial footprint matches against that actor's footprint. And we call this a splash. It's like slapping a mud puddle. It's a whole bunch of different actors that are suddenly trying to get back onto the platform that have actually all been hiding under the same TTP umbrella, the same footprint. Sometimes they don't even know that they're doing it. Now, they're trying to... often it turns out that they're sharing TTPs, they're sharing techniques of doing things on the platform through everything from YouTube videos to forums to whatever. And sometimes when we find the source of those, if they're doing really particular badness, you know, phishing attacks and stuff like that, and watching them discuss how they're going to make changes, if we can keep on top of those changes and add them to the footprint before they're actually even deployed, then we can keep on top of them as well. Shout out to our fantastic Threat Intel team. They kind of help us find all that extra info if that is the need. Now, when we have all that tooling in place, when pivot detection is working and designed, and when we manage to stop the actor, sometimes even before they've begun, then they only have two choices. They can either go somewhere else, or they can entirely retool. Retooling requires them to change everything, because we've got footprints for nearly everything that they're doing. I don't want to say absolutely everything. We don't know. But pretty damn close. Now, this makes them indistinguishable from a new actor. But honestly, we don't really care at that point. If we end up being a show-up actor, so be it. We'll track them as a new actor. Sometimes they've actually retooled to the point where they decide to do something completely different than what they've been doing before. Now, we don't usually... Because we're pretty thorough in our collection, sometimes we still find evidence that a new actor is actually an old actor retooled, and that's kind of fascinating for different reasons. And when we find that evidence, we can still put it together and make great work of that. And sometimes that little tenuous link, as you probably know, is something that's really, really simple. Something as simple as putting a couple of numbers, the same 1, 2, 3, 4 numbers in there, constantly using four dots in their email address. Now, given that as our hunt loop, let's go back to Spencer for the show and tell. All right. Thanks, Alan. Let's look at a few campaigns that have touched our hearts. And, well, we'd like to think we've touched theirs, too. The first actor appeared on our radar by spinning up 100 apps per user account across multiple accounts, all from free email providers. So a user account is limited to running five apps until they verify their account by adding a payment method, like the credit card. After that, 100 apps is the new max. So here we have new accounts immediately adding a credit card and going full tilt to 100 apps. That's not normal. Normal users don't do this. That activity stands out and gets on our radar fast. And to top things off, fraudulent credit cards were used to verify each account. And all of the apps were identical. So we inspected one of the apps and saw that they were running a Tor hidden service accessible through SSH. Here's a screenshot of the script that would run once their app was deployed. We suspended the accounts and very soon the actor was back and we had their attention. Soon after, we saw their underlying intent, mining Monero. The apps were mining with LibXMR and sending all traffic through Tor. Now after seeing this, we believe that the initial wave of apps that were running Tor were really part of some capabilities testing, so some real live bad actor DevOps. We continued to suspend the accounts and the actor would pivot, each time trying to minimize their footprint to avoid detection. So the top image is from an app that packed the Tor and mining binaries in a zip file, which would then be unzipped with a unique passphrase at the time of deployment. The bottom image is from a later pivot, this time using GPG encrypted payloads with unique names and unique passphrases. So decrypt, unpack, and mine, sending everything through Tor. Now this user was really fast. They appeared to be retooling their apps and back online within just four hours of being suspended. And this type of activity at this scale threatened the performance of some of the shared resources. Other customers were impacted due to these noisy neighbor situations, so we had to stay on top of this actor. But they were automating their operation and getting faster, mostly during our off hours. So playing never-ending whack-a-mole was unsustainable and really a path toward team burnout. So we took a step back and we looked at all of the data provided from this actor's use of the platform. Home field advantage, right? This turned into a list of indicators which we could use to form a TTP footprint. The actual footprint is very close to what's on this slide. As you can imagine, to make the most from cryptocurrency mining, the actor needs to spread out across as many accounts as possible. So to make it worth their time, they try to automate any part of their operation, like account creation. That kind of automation generates patterns that we can use for detection. In this case, we look for groups of accounts that signed up from an IP address, that happened to be a Tor exit node, from a particular free email provider, and had an email address that matched a certain naming pattern. If a new account matched those three indicators, we already have high confidence that it's an account controlled by this actor. Next, the accounts would quickly create five apps, all with a positive size, and they would leave the names as the default Heroku haiku. Then sampling some of the apps, we could confirm if they had a GPG blob, and if they had the startup script, which decrypted and unpacked the payload. Again, normal users don't do this. So when we joined these indicators together, the false positive rate was zero. Very high confidence, right? So now matching these 10 indicators, low value by themselves, gave us a high value decision. We can now identify this actor without having to pick everything apart, every time, on every pivot. Just focus on what's different, which saved us a bunch of time, while wasting the actors. They soon gave up, and appeared to have left the platform. Let's look at another campaign. This actor came to our attention through a phishing report. We suspended their account, and very soon, we saw that the same phish was reported again, so we tracked them as a campaign. They were targeting customers of a specific insurance provider. When inspecting one of their apps, we see the following directory structure, which contains message-sending capabilities in the mailer.py file. Here, they would use third-party messaging add-ons to either distribute their messages or handle their loot. We suspended the accounts and hunted for more, and found an entirely different app used for the same campaign. This time, it was a JavaScript React app, which had some added functionality. Like, now they were going after credit card information, as well as credentials. This screenshot shows the collection of credit card number, expiration date, and CVV in French. Really quick, I want to share these screenshots from another pivot, where the actor repurposed somebody else's kit. You can probably Google for some of these keywords, and still find it out there somewhere on the internet. We developed a TTP footprint for this actor. This time, it was more app-focused, since they didn't need to spread out across multiple accounts to profit like the crypto-miner did. We also used these unique indicators to update rules in our detection and response tooling, just whenever possible, whenever it was appropriate. But this actor was still very persistent. We want to break their spirit. We don't want to help them improve their coding skills as we go back and forth. Typically, being in proximity to the sensitive information that they were gathering is like being in proximity to toxic waste. Unless you're the bad actor, then it has value. But it's only valuable if the information is valid. So considering this, we did our best to get that information into the appropriate hands, so that passwords, payment information could all get reset and nullified. Let's strip the value and really waste their time. Also, we found ways to notify the other service providers that were used in the campaign, which put even more pressure on this actor. These two things disrupted their operations enough that it appears to have pushed them from the platform. But some of the external indicators that we used to track them, like what you can find on EARLScan, suggest that they're still active, just not on our platform. The third campaign is from a couple of years ago. It started as a DMCA takedown request, claiming that a Heroku app was distributing a copyrighted e-book. When we checked out the link that was reported, the PDF was not the full e-book, but had the same title and same cover art as the real book. But it also had a link to download the book on another site. Nothing weird there, right? This screenshot is not from what was reported, but it was from one of the other apps that we found while researching this campaign. When we investigate an app, we're looking for just enough information to establish intent with high confidence, while hunting for unique indicators and general functionality. Now, with an app like this, we don't have enough time to become subject matter experts and pick everything apart. So we typically start with something like the index.php file, or look for some other unique files that really stand out, directories. So in this case, these were some of the files and directories that stood out. func.php, the document generator PHP files, and the keyw directory. Now, func is Indonesian for function, by the way. It's going to be important in a few seconds. Let's see what's in the keyw directory first. Lots of text files. Lots of text files. Each filled with lots of book titles, from New York Times bestsellers to obscure auto-wiring diagrams. Now, these screenshots are just from one of the files. Overall, this app had over 300,000 titles. To understand how these titles are being used, we went back to the root and searched for the keyw string in the PHP files. Now, in this screenshot, we see that they were creating sitemap XML files for each book index file. Huh. And they would make sitemaps for each book title. These sitemaps would be sent to search engines for... Black Hat SEO! We saw other tactics like cloaking, where search engines would return different results than a normal visitor. Some apps would perform multiple redirects. And then they would do link manipulation by taking these long book titles, slicing them up, creating a whole bunch of different links, and sending them back out to the search engines. And I'm sure there's more, but, I mean, this was more than enough to establish intent. We don't want this kind of activity on our platform. Now, we had to see how widespread it was. Turned out, there were thousands of accounts participating in this campaign. Many were found just by looking at patterns from the sign-up data, like source IP and user-agent string combinations, as well as the use of email sub-inboxing patterns to create multiple accounts. So, you know, like how you can move the dot around in a Gmail account? It's been fixed. The overall campaign included a variety of apps that were ultimately doing the same thing. Some were even sniping orphaned subdomains of reputable customers in order to boost their rankings with the search engines. It's been fixed as well. So, abusing our systems to abuse the search engine algorithms. I mean, it's just abuse all the way down. Now, here's a quick look at some of the other indicators. Now, we mentioned hunting within the sign-up data. These accounts were created within the typical working hours of the Indonesian time zone, and only on five days out of the week. They weren't non-stop sign-ups, but you see these bursts of accounts being created a few times a day within those working days. Other fun indicators were typos and Indonesian words. One that had me scratching my head at first was S-U-K-S-E-S, which translates to how it sounds. Success. So, we successfully booted them from the platform. Now, I wish we could dive deeper and share more, but we want to briefly mention some of the lessons that we've learned while fighting abuse on a platform. First, demotivating a bad actor can be very effective and satisfying. Know your environment and hunt for internal indicators, no matter how little value they appear to have, because collectively they can show intent, build confidence, and help make a high-value decision. Also, check if there are ways to include external indicators, like OSINT or threat intelligence, and enrich that data. For us, not focusing on things like suspension count, but rather focusing on patterns that the bad actors were using to take advantage of our services. Those patterns are worth reporting back to the business so they can be addressed and fixed, and ultimately create a platform that's less hospitable for abuse. Thanks again for attending our talk. If you're interested in more of this, but maybe for more of a philosophical or business approach, check out our Black Hat Talk. Thank you. Thank you. Any questions in text talks in Track 1?