Reading view

There are new articles available, click to refresh the page.

Like Shooting Phish in a Barrel

PHISHING SCHOOL

Bypassing Link Crawlers

You’ve just convinced a target user to click your link. In doing so, you have achieved the critical step in social engineering:

Convincing someone to let you in the door!

Now, we just have a few more technical controls that might get in the way of us reeling in our catch. The first of which is link crawlers.

What’s a Link Crawler?

Link crawlers, or “protected links” are one of the most annoying email controls out there. I don’t hate them because of their effectiveness (or ineffectiveness) at blocking phishing. I hate them because they are a real pain for end users and so many secure email gateways (SEGs) use them as a security feature these days. Here’s what they do, and why they suck:

What link crawlers do

They replace all links in an email with a link to their own web server with some unique ID to look up the original link. Then, when a user clicks a link in the email, they first get sent to purgatory… oops, I mean the “protected link” website. The SEG’s web server looks up the original link, and then sends out a web crawler to check out the content of the link’s webpage. If it looks too phishy, the user will be blocked from accessing the link’s URL. If the crawler thinks the page is benign, it will forward the user on to the original link’s URL.

Why link crawlers suck

First, have you ever had to reset your password for some web service you rarely use, and they sent you a one-time-use link to start the reset process? If your secure email gateway (SEG) replaces that link with a “safe link”, and has to check out the real link before allowing you to visit it, then guess what? You will never be able to reset your password because your SEG keeps killing your one-time-use links! I know that some link crawlers work in the opposite order (i.e. crawling the link right after the user visits) to get around this problem, but most of them click first, and send the user to a dead one-time-use URL later.

Second, these link replacements also make it so that the end user actually has no clue where a link is really going to send them. Hovering the link in an email will always show them a URL for the SEG’s link crawling service so there is no way the user can detect a masked link.

Third, I see these “security features” as really just an overt data grab by the SEGs that implement them. They want to collect valuable user behavior telemetry more than they really care about protecting them from phishing campaigns. I wonder how many SEGs sell this data to the devil… oops, I mean “marketing firms”. It all seems very “big brother” to me.

Lastly, this control is not even that hard to bypass. I think if link crawlers were extremely effective at blocking phishing attacks, then I would be more forgiving and able to accept their downsides as a necessary evil. However, that is not the case. Let’s go ahead and talk about ways to bypass them!

Parser Bypasses

Similar to bypassing link filter protections, if the SEG’s link parser doesn’t see our link, then it can’t replace it with a safe link. By focusing on this tactic we can sometimes get two bypasses for the price of one. We’ve already covered this in Feeding the Phishes, so I’ll skip the details here.

Completely Automated Public Turing test to tell Computers and Humans Apart (CAPTCHA)

Link crawlers are just robots. Therefore, to defeat link crawlers, we need to wage war with the robots! We smarty pants humans have employed CAPTCHAs as robot bouncers for decades now to kick them out of our websites. We can use the same approach to protect our phishing pages from crawlers as well. Because SEGs just want a peak at our website content to make a determination of whether it’s benign, there is no real motivation for them to employ any sort of CAPTCHA solver logic. For us, that means our CAPTCHAs don’t even have to be all that complicated or secure like they would need to be to protect a real website. I personally think this approach has been overused and abused by spammers to the point that many users are sketched out by them, but it’s still a valid link crawler bypass for many SEGs and a pretty quick and obvious choice.

Fun Fact (think about it)

Because the test is administered by a computer, in contrast to the standard Turing test that is administered by a human, CAPTCHAs are sometimes described as reverse Turing tests. — Wikipedia

Join the Redirect Arms Race

Warning: I don’t actually recommend this, but it works, and therefore we have to talk about it. I’ll try to keep it brief.

Q: If you are tasked with implementing a link checker, how should you treat redirects like HTTP 302 responses?

A: They are common enough that you should probably follow the redirect.

Q: What about if it redirects again? This time via JavaScript instead of an HTTP response code. Should you follow it?

A: Yes, this is common enough too, so maybe we should follow it.

Q: But how many times?

A: ???

That’s up to you as the software engineer to decide. If you specify a depth of 3 and your script gets redirected 3 times, it’s going to stop following redirects and just assess the content on the current page. Phishers are going to redirect 4 times and defeat your bot. You’re going to up the depth, then they are going to up the redirects, and so on and so forth ad nauseam.

Welcome to the redirect arms race.

I see this “in the wild” all the time so it must work as a bypass, but it is annoying, and cliche, and kinda dumb in my opinion. So…

Please don’t join the redirect arms race!!!

Alert!

Link crawling bots tend to come in two different flavors:

  1. Content scraping scripts
  2. Automated browser scripts

The easiest to implement, and therefore the most common type of link crawler is just a simple content scraping script. You can think of these as being a scripted version of using a tool like cURL to pull a URL’s content and checking it for phishy language. These scripts might also look for links on the page and crawl each of them to a certain depth as well.

Because scrapers just read the content, they don’t actually execute any JavaScript like a web browser would. We can use this to our advantage by using JavaScript to detect actions that require user interaction, and then forward them on to the real phishing content. One very simple way of doing this is to include an “alert()” statement just before a “window.location” change. If we obfuscate the “window.location” change, then scraper will not see any additional content it needs to vet. When a human user clicks our link, and views our page in their browser, they will get a simple alert message that they have to accept, and then will be forwarded to the real phishing page. The content of the alert doesn’t matter, so we can use it to play into the wording of our pretext (e.g. “Downloading your document. Click Okay to continue.”).

Because it is simply too easy to defeat content scrapers with JavaScript, some SEGs have gone through the trouble of scripting automated browsers to crawl links. While the automated browser can execute JavaScript, emulating human interaction is still difficult. Once again, if we use an “alert()” function on our page, JavaScript execution will be blocked until the user accepts the message. In some cases, if the software engineer who wrote the script did not consider alert boxes, then their automated browser instance will be stuck on the page while the alert is asking for user input. If the software engineer does consider alerts, then they will likely stumble upon a common solution like the following:

browser.target_page.on('dialog', async dialog => {
await dialog.accept()
})

I myself have used this very technique to accept alerts when writing web scrapers for OSINT.

The problem with this solution is that it will accept the dialog (alert) immediately when it appears. A real human is going to need at least a second or two to see the alert, read it, move their mouse to the accept button, and click. If we set a timer on the alert box acceptance, we can pretty easily detect when a bot is accepting the alert and send them somewhere else. Few software engineers who are tasked with implementing these link crawler scripts will think this many moves in advance, and therefore even simple bypasses like this tend to work surprisingly well.

Count the Clicks

If we keep in mind that most link crawlers visit link URLs just before sending the user to the same URL, we can often defeat them by simply displaying a different set of content for the first click. The link crawler sees something benign and allows the user to visit, and that’s when we swap out the content. It is possible to achieve this directly in Apache using the ‘mod_security’ feature or in Nginx using the ‘map’ feature. Though it may be easiest in most cases to use a tool like Satellite to do this for you using the ‘times_served’ feature:

https://github.com/t94j0/satellite/wiki/Route-Configuration

I tend to prefer writing my own basic web servers for hosting phishing sites so I have more granular control over the data I want to track and log. It’s then pretty simple to either keep a dictionary in memory to track clicks or add a SQLite database if you are concerned about persisting data if you need to restart the server.

Browser Fingerprinting

One way to detect bots that is far less intrusive and annoying than CAPTCHAs is to use browser fingerprinting. The idea here is to use features of JavaScript to determine what type of browser is visiting your webpage. Browser fingerprinting is extremely common today for both tracking users without cookies, and defending against bots. Many automated browser frameworks like Selenium and Puppeteer have default behaviors that are easy to detect. For example, most headless browsers have ‘outerHeight’ and ‘outerWidth’ attributes set to zero. There are many other well known indicators that your site is being viewed by a bot. Here’s a nice tool if you would like to start tinkering:

https://github.com/infosimples/detect-headless

Another more extensive open source project that was designed for user tracking but can also be useful for this type of bot protection is FingerprintJS:

https://github.com/fingerprintjs/fingerprintjs

Most SEGs that implement link crawlers are not really incentivized to stay on the bleeding edge when it comes to hiding their bots. Therefore, in the vast majority of cases, we will be able to block SEG link crawlers with just open source tooling. However, there are also some really amazing paid options out there that specialize in bot protection and are constantly on the bleeding edge. For example, Dylan Evans wrote a great blog and some tooling that demonstrates how to thwart bots using Cloudflare Turnstile:

https://fin3ss3g0d.net/index.php/2024/04/08/evilgophishs-approach-to-advanced-bot-detection-with-cloudflare-turnstile/

I would imagine just about any decent paid solution will thwart any SEG link crawlers you might encounter. It’s sort of like bringing a gun to a knife fight.

ASN Blocking

Autonomous system numbers (ASNs) are groups of IP ranges that belong to an entity or domain. In practice, every public IP address belongs to an ASN, and you can look up the organization that owns each ASN. Because most SEGs operate using a SAAS model, when their link crawler visits your site the traffic will originate from an ASN either owned by the SEG, by their internet service provider, or by a cloud computing service they use to run their software. In any case, the ASN will likely be consistent for a particular SEG, and will not be the same as the ASN associated with the IPs of your target users. If you collect IP and ASN data on your phishing sites, you can build a list of known-bad ASNs that you should block from viewing your real content. This can help you display benign content to SEG link crawlers, and will also help protect you from web crawlers in general that might put your domain on a blocklist.

Call Them

Once again, because link crawlers are an email control, we can bypass them by simply not using email as our message transport for social engineering. Calling from a spoofed number is easy and often highly effective.

Story of the Aggressive Link Crawler

Some SEGs actually crawl all links in an email, whether they are clicked by a user or not. The first time I encountered one, I thought I was having the most successful phishing campaign ever until I realized that my click rate was just under 100% (some messages must have bounced or something).

Luckily, I had already added a quick IP address lookup feature to Phishmonger at this point and I was able to see that the SEG was generating clicks from IPs all around the world. What they were doing was using an IP rotation service to make themselves harder to block and/or stop.

Also luckily, my client was only based and operating out of a single U.S. state. I was able to put a GeoIP filter on HumbleChameleon which I was using as my web server, and redirect the fake clicks elsewhere.

This worked well enough as a workaround in this scenario, but it would not work for bigger companies with a wider global footprint. I got lucky. Therefore, I think a better generalized bypass for this type of link crawler is to track the time between sending an email, and when the user clicks. These aggressive link crawlers are trying to vet the links in the email before the user has a chance to see and click them, so they will visit your links almost immediately (within seconds to a couple minutes) of receiving each email. They don’t have the luxury of being able to “jitter” their click times without seriously jamming the flow of incoming emails. Therefore, we can treat any clicks that happen within 2–3 minutes of sending the email as highly suspicious and either reject them (i.e. 404 and ask the user to come back later), or apply some additional vetting logic to make sure we aren’t dealing with a bot.

In Summary

Link crawlers, or “safe links” are going to allow SEGs to use bots to vet your phishing links before users are allowed to visit them. This control is annoying, but not very difficult to bypass. We just need to use some tried and true methods of detecting bots. There are some great open source and paid solutions that can help us detect bots and show them benign content.

SEGs aren’t properly incentivized to stay on the bleeding edge of writing stealthy web crawlers, so we can get some pretty good mileage out of known techniques and free tools. Just bring a leg to the arms race:

Finally, it’s always a good idea to collect data on your campaigns beyond just clicks, and to review that data for evidence of controls like link crawlers. If you aren’t tracking any browser fingerprints, or IP locations, or delivery-to-click times, then how can you say with any confidence what was a legitimate click versus a security product looking at your phishing page? Feedback loops are an essential part of developing and improving our tradecraft. Go collect some data!


Like Shooting Phish in a Barrel was originally published in Posts By SpecterOps Team Members on Medium, where people are continuing the conversation by highlighting and responding to this story.

The post Like Shooting Phish in a Barrel appeared first on Security Boulevard.

Feeding the Phishes

PHISHING SCHOOL

Bypassing Phishing Link Filters

You could have a solid pretext that slips right by your target secure email gateway (SEG); however, if your link looks too sketchy (or, you know, “smells phishy”), your phish could go belly-up before it even gets a bite. That’s why I tend to think of link filters as their own separate control. Let’s talk briefly about how these link filters work and then explore some ways we might be able to bypass them.

What the Filter? (WTF)

Over the past few years, I’ve noticed a growing interest in detecting phishing based on the links themselves–or, at least, there are several very popular SEGs that place a very high weight on the presence of a link in an email. I’ve seen so much of this that I have made this type of detection one of my first troubleshooting steps when a SEG blocks me. I’ll simply remove all links from an email and check if the message content gets through.

In at least one case, I encountered a SEG that blocked ANY email that contained a link to ANY unrecognized domain, no matter what the wording or subject line said. In this case, I believe my client was curating a list of allowed domains and instructed the SEG to block everything else. It’s an extreme measure, but I think it is a very valid concern. Emails with links are inherently riskier than emails that do not contain links; therefore, most modern SEGs will increase the SPAM score of any message that contains a link and often will apply additional scrutiny to the links themselves.

How Link Filters Work — Finding the Links

If a SEG filters links in an email, it will first need to detect/parse each link in the content. To do this, almost any experienced software engineer will directly go to using Regular Expressions (“regex” for short):

Stand back! I know regular expressions

To which, any other experienced software engineer will be quick to remind us that while regex is extremely powerful, it is also easy to screw up:

99 problems (and regex is one)

As an example, here are just a few of the top regex filters I found for parsing links on stackoverflow:

(http|ftp|https):\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])

(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)(?:\([-A-Z0–9+&@#\/%=~_|$?!:,.]*\)|[-A-Z0–9+&@#\/%=~_|$?!:,.])*(?:\([-A-Z0–9+&@#\/%=~_|$?!:,.]*\)|[A-Z0–9+&@#\/%=~_|$])

(?:(?:https?|ftp):\/\/)?[\w/\-?=%.]+\.[\w/\-&?=%.]+

([\w+]+\:\/\/)?([\w\d-]+\.)*[\w-]+[\.\:]\w+([\/\?\=\&\#\.]?[\w-]+)*\/?

(?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0–9%])|www\d{0,3}[.]|[a-z0–9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:’”.,<>?«»“”‘’]))

Don’t worry if you don’t know what any of these mean. I consider myself to be well versed in regex and even I have no opinion on which of these options would be better than the others. However, there are a couple things I would like to note from these examples:

  1. There is no “right” answer; URLs can be very complex
  2. Most (but not all) are looking for strings that start with “http” or something similar

These are also some of the most popular (think “smart people”) answers to this problem of parsing links. I could also imagine that some software engineers would take a more naive approach of searching for all anchor (“<a>”) HTML tags or looking for “href=” to indicate the start of a link. No matter which solution the software engineer chooses, there are likely going to be at least some valid URLs that their parser doesn’t catch and might leave room for a categorical bypass. We might also be able to evade parsers if we can avoid the common indicators like “http” or break up our link into multiple sections.

Side Note: Did you see that some of these popular URL parsers account for FTP and some don’t? Did you know that most browsers can connect to FTP shares? Have you ever tried to deliver a phishing payload over an anonymous FTP link?

How Link Filters Work — Filtering the Links

Once a SEG has parsed out all the links in an email, how should it determine which ones look legitimate and which ones don’t? Most SEGs these days look at two major factors for each link:

  1. The reputation of the domain
  2. How the link “looks”

Checking the domain reputation is pretty straightforward; you just split the link to see what’s between the first two forward slashes (“//”) and the next forward slash (“/”) and look up the resulting domain or subdomain on Virustotal or similar. Many SEGs will share intelligence on known bad domains with other security products and vice versa. If your domain has been flagged as malicious, the SEG will either block the email or remove the link.

As far as checking how the link “looks”, most SEGs these days use artificial intelligence or machine learning (i.e., AI/ML) to categorize links as malicious or benign. These AI models have been trained on a large volume of known-bad links and can detect themes and patterns commonly used by SPAM authors. As phishers, I think it’s important for us to focus on the “known-bad” part of that statement.

I’ve seen one researcher’s talk who claimed their AI model was able to detect over 98% of malicious links from their training data. At first glance, this seems like a very impressive number; however, we need to keep in mind that in order to have a training set of malicious links in the first place, humans had to detect 100% of the training set as malicious. Therefore, the AI model was only 98% as good as a human at detecting phishing links solely on the “look” of the link. I would imagine that it would do much worse on a set of unknown-bad links, if there was a way to hypothetically attain such a set. To slip through the cracks, we should aim to put our links in that unknown-bad category.

Even though we are up against AI models, I like to remind myself that these models can only be trained on human-curated data and therefore can only theoretically approach the competence of a human, but not surpass humans at this task. If we can make our links look convincing enough for a human, the AI should not give us any trouble.

Bypassing Link Filters

Given what we now know about how link filters work, we should have two main tactics available to us for bypassing the filter:

  1. Format our link so that it slips through the link parsing phase
  2. Make our link “look” more legitimate

If the parser doesn’t register our link as a link, then it can’t apply any additional scrutiny to the location. If we can make our link location look like some legitimate link, then even if we can’t bypass the parser, we might get the green light anyway. Please note that these approaches are not mutually exclusive and you might have greater success mixing techniques.

Bypassing the Parser

Don’t use an anchor tag

One of the most basic parser bypasses I have found for some SEGs is to simply leave the link URL in plaintext by removing the hyperlink in Outlook. Normally, link URLs are placed in the “hypertext reference” (href) attribute of an HTML anchor tag (<a>). As I mentioned earlier, one naive but surprisingly common solution for parsing links is to use an HTML parsing library like BeautifulSoup in Python. For example:

soup = BeautifulSoup(email.content, 'html.parser')
links = soup.find_all("a") # Find all elements with the tag <a>
for link in links:
print("Link:", link.get("href"), "Text:", link.string)

Any SEG that uses this approach to parse links won’t see a URL outside of an anchor tag. While a URL that is not a clickable link might look a little odd to the end user, it’s generally worth the tradeoff when this bypass works. In many cases, mail clients will parse and display URLs as hyperlinks even if they are not in an anchor tag; therefore, there is usually little to no downside of using this technique.

Use a Base Tag (a.k.a BaseStriker Attack)

One interesting method of bypassing some link filters is to use a little-known HTML tag called “base”. This tag allows you to set the base domain for any links that use relative references (i.e., links with hrefs that start with “/something” instead of direct references like “https://example.com/something”). In this case, the “https://example.com” would be considered the “base” of the URL. By defining the base using the HTML base tag in the header of the HTML content, you can then use just relative references in the body of the message. While HTML headers frequently contain URLs for things like CSS or XML schemas, the header is usually not expected to contain anything malicious and may be overlooked by a link parser. This technique is known as the “BaseStriker” attack and has been known to work against some very popular SEGs:

https://www.cyberdefensemagazine.com/basestriker-attack-technique-allow-to-bypass-microsoft-office-365-anti-phishing-filter/

The reason why this technique works is because you essentially break your link into two pieces: the domain is in the HTML headers, and the rest of the URL is in your anchor tags in the body. Because the hrefs for the anchor tags don’t start with “https://” they aren’t detected as links.

Scheming Little Bypasses

The first part of a URL, before the colon and forward slashes, is what’s known as the “scheme”:

URI = scheme ":" ["//" authority] path ["?" query] ["#" fragment]

As mentioned earlier, some of the more robust ways to detect URLs is by looking for anything that looks like a scheme (e.g. “http://”, or “https://”), followed by a sequence of characters that would be allowed in a URL. If we simply leave off the scheme, many link parsers will not be able to detect our URL, but it will still look like a URL to a human:

accounts.goooogle.com/login?id=34567

A human might easily be convinced to simply copy and paste this link into their browser for us. In addition, there are quite a few legitimate schemes that could open a program on our target user’s system and potentially slip through a URL parser that is only looking for web links:

https://en.wikipedia.org/wiki/List_of_URI_schemes

There are at least a few that could be very useful as phishing links ;)

QR Phishing

What if there isn’t a link in the email at all? What if it’s an image instead? You can use a tool like SquarePhish to automate phishing with QR codes instead of traditional links:

GitHub - secureworks/squarephish

I haven’t played with this yet, but have heard good things from friends that have used similar techniques. If you want to play with automating this attack yourself, NodeJS has a simple library for generating QRs:

qrcode

Bypassing the Filter

Don’t Mask

(Hold on. I need to get on my soapbox…) I can’t count how many times I’ve been blocked because of a masked link only to find that unmasking the link would get the same pretext through. I think this is because spammers have thoroughly abused this feature of anchor tags in the past and average email users seldom use masked links. Link filters tend to see masked links as far more dangerous than regular links; therefore, just use a regular link. It seems like everyone these days knows how to hover a link and check its real location anyway, so masked links are even bad at tricking humans now. Don’t be cliche. Don’t use masked links.

Use Categorized Domains

Many link filters block or remove links to domains that are either uncategorized, categorized as malicious, or were recently registered. Therefore, it’s generally a good idea to use domains that have been parked long enough to be categorized. We’ve already touched on this in “One Phish Two Phish, Red Teams Spew Phish”, so I’ll skip the process of getting a good domain; however, just know that the same rules apply here.

Use “Legitimate” Domains

If you don’t want to go through all the trouble of maintaining categorized domains for phishing links, there are some generally trustworthy domains you can leverage instead. One example I recently saw “in-the-wild” was a spammer using a sites.google.com link. They just hosted their phishing page on Google! I thought this was brilliant because I would expect most link filters to allow Google, and even most end users would think anything on google.com must be legit. Some other similar examples would be hosting your phishing sites as static pages on GitHub, in an S3 bucket, other common content delivery networks (CDNs), or on SharePoint, etc. There are tons of seemingly “legitimate” sites that allow users to host pages of arbitrary HTML content.

Arbitrary Redirects

Along the same lines as hosting your phishing site on a trusted domain is using trusted domains to redirect to your phishing site. One classic example of this would be link shorteners like TinyURL. While TinyURL has been abused for SPAM to the point that I would expect most SEGs to block TinyURL links, it does demonstrate the usefulness of arbitrary redirects.

A more useful form of arbitrary redirect for bypassing link filters are URLs with either cross-site scripting (XSS) vulnerabilities that allow us to specify a ‘window.location’ change or URLs that take an HTTP GET parameter specifying where the page should redirect to. As part of my reconnaissance phase, I like to spend at least a few minutes on the main website of my target to look for these types of vulnerabilities. These vulnerabilities are surprisingly common and while an arbitrary redirect might be considered a low-risk finding on a web application penetration test report, they can be extremely useful when combined with phishing. Your links will point to a URL on your target organization’s main website. It is extremely unlikely that a link filter or even a human will see the danger. In some cases, you may find that your target organization has configured an explicit allow list in the SEG for links that point to their domains.

Link to an Attachment

Did you know that links in an email can also point to an email attachment? Instead of providing a URL in the href of your anchor tag, you can specify the content identifier (CID) of the attachment (e.g. href=“cid:mycontentidentifier@content.net”). One way I have used this trick to bypass link filters is to link to an HTML attachment and use obfuscated JavaScript to redirect the user to the phishing site. Because our href does not look like a URL, most SEGs will think our link is benign. You could also link to a PDF, DOCX, or several other usually allowed file types that then contain the real phishing link. This might require a little more setup in your pretext to instruct the user, or just hope that they will click the link after opening the document. In this case, I think it makes the most sense to add any additional instructions inside the document where the contents are less likely to be scrutinized by the SEG’s content filter.

Pick Up The Phone

This blog rounds out our “message inbound” controls that we have to bypass for social engineering pretexts. It would not be complete without mentioning one of the simplest bypasses of them all:

Not using email!

If you pick up the phone and talk directly to your target, your pretext travels from your mouth, through the phone, then directly into their ear, and hits their brain without ever passing through a content or reputation filter.

Along the same lines, Zoom calls, Teams chats, LinkedIn messaging, and just about any other common business communication channel will likely be subject to far fewer controls than email. I’ve trained quite a few red teamers who prefer phone calls over emails because it greatly simplifies their workflow. Just a few awkward calls is usually all it takes to cede access to a target environment.

More interactive forms of communication, like phone calls, also allow you to gauge how the target is feeling about your pretext in real time. It’s usually obvious within seconds whether someone believes you and wants to help or if they think you’re full of it and it’s time to cut your losses, hang up the phone, and try someone else. You can also use phone calls as a way to prime a target for a follow-up email to add perceived legitimacy. Getting our message to the user is half the battle, and social engineering phone calls can be a powerful shortcut.

In Summary

If you need to bypass a link filter, either:

  1. Make your link look like it’s not a link
  2. Make your link look like a “legitimate” link

People still use links in emails all the time. You just need to blend in with the “real” ones and you can trick the filter. If you are really in a pinch, just call your targets instead. It feels more personal, but it gets the job done quickly.


Feeding the Phishes was originally published in Posts By SpecterOps Team Members on Medium, where people are continuing the conversation by highlighting and responding to this story.

The post Feeding the Phishes appeared first on Security Boulevard.

One Phish Two Phish, Red Teams Spew Phish

PHISHING SCHOOL

How to Give your Phishing Domains a Reputation Boost

“Armed with the foreknowledge of my own death, I knew the giant couldn’t kill me. All the same, I preferred to keep my bones unbroken” — Big Phish

When we send out our phishing emails, we are reckoning with giants. Spamhaus, SpamAssassin, SpamTitan, Barracuda, and many more giants wish to grind your bones to bake their bread. They are big. They are scary. But they don’t catch everything. Just like Edward Bloom learned; the best way to deal with giants is to make a good first impression.

What’s your name, giant? — Karl

That’s how we will deal with these giants as well. Let’s talk about proper etiquette when speaking with giants.

“He Ate My Dog”

The first opportunity a mail server has to reject your email is right at the beginning of an SMTP exchange. The server can run checks on the reputation of both your sending IP, and the domain you are claiming to be in your FROM address. In general, the main controls that will get you blocked by a good secure email gateway (SEG) are some version of the following:

  • Does your sending IP show up on a known SPAM list like Spamhaus?
  • Is the geographical location of the sending IP in another country?
  • What’s the reputation/category of the sending domain?
  • What’s the age of the sending domain?
  • Does SPF fail?
He ate my dog

Of course, all of these checks are generally configurable, and not every SEG will perform all of these checks. These are just some of the most common controls I tend to expect are the root cause of a failure at this stage in the phish’s lifecycle. None of these is really all that difficult to address/bypass so by taking them into account, we can usually ensure our phishing campaigns are not blocked at this layer.

Bypassing Sender Reputation Checks

When we attempt to deliver our message, we will be connecting to a mail server for the target email’s domain, telling it who we are and who we want to send a message to, and then giving it the contents of the message. Here is an example of what that conversation looks like under the hood with data we control in blue and server responses in green:

SMTP Greetings

In general, IP address blocks are easy for us to troubleshoot because if our sending IP is blocked, the server will typically just terminate the TCP connection and we won’t even be able to start this SMTP call and response. It’s pretty rare to be blocked by IP right off the bat, and typically means you’re sending from an IP that is associated with sending a lot of SPAM, or the GeoIP result for your sending IP is in a blocked country or region. If that’s the case, just try sending from another IP.

The next opportunity for the server to block us is by the reputation of the domain we supply as the sending domain. Notice in our example that the sending domain is ‘contoso.com’ and is used in both the EHLO and MAIL FROM commands. These domains typically match, but they don’t have to. Feel free to tinker with mismatching these values to see how different mail servers respond.

You can think of the EHLO and MAIL FROM commands as saying “I’m a mail server for contoso.com, and I’m going to send an email from chris@contoso.com to one of your users”. At this point, the receiving server has an opportunity to accept or reject our claim by checking a few things:

  • Is contoso.com on a known SPAM list? (never going to let it through)
  • Is contoso.com explicitly whitelisted? (always going to let it through)
  • How old is the contoso.com domain?
  • Is contoso.com categorized? And if so, what category is it?
  • Has the server ever received emails from contoso.com before?
  • Does contoso.com’s MX record match your sending IP address?
  • Does a reverse DNS lookup of your sending IP resolve to <something>.contoso.com?
  • Does contoso.com publish an SPF record that includes your sending IP address?

Most mail servers will perform one or more of these checks to obtain hints about whether you can be trusted or not. Some of these hints, like reverse DNS records, will increase our reputation if they pass the check, but won’t really hurt our reputation too much if they fail. Others, like trying to spoof a domain from an IP that is not in that domain’s SPF record, will likely get us burned right away. Therefore, we should try to pass as many of these checks as we can, while avoiding techniques that could be clearly identified as a spoof.

So, Which Domain Should I Use?

When choosing our sending domain, we have a few options, each with its own pros and cons. We can either spoof a domain that we do not own, or buy a domain. If we buy a domain, we can either get a brand new domain of our choosing, or buy an expired domain that was previously bought by someone else. No one method is inherently better than the others, but we should have a clear understanding of how to get the most out of each technique when making our choice.

Spoofed Domains

Pros

  • Free! ‘Nough said
  • Makes attribution difficult. You are basically framing someone else. (Note: this could be a con if you have to go through attribution and deconfliction with the blue team)
  • Probably already categorized and old enough to pass checks for newly registered domains
  • Successful spoofs can look very legitimate, and therefore boost success rates

Cons

  • Limited to existing domains that you can find
  • You may be able to use non-existent domains, but they are easy to identify and often blocked. It’s generally better to purchase in this case.
  • Most high-value domains have implemented email security settings like SPF that could make it difficult, if not impossible to spoof without detection
  • We can’t set up our own email security settings on the domain that might boost our reputation (no control and no proof-of-ownership)
  • We have no influence over domain category or reputation

Considerations When Spoofing Domains

Does our target mail server actually check SPF?

If not, we should be able to successfully spoof just about any domain. I’ve seen several cases where, for whatever reason, SPF checks were either turned off or misconfigured so that failing SPF did not result in rejected emails. It’s often worth a shot to try to deliver a few benign emails while intentionally failing SPF to see if the server sends back an error message or says it delivered them. While you won’t receive any bounce messages or responses from recipients (those would go to the mail server for your spoofed domain), you could try putting image links or tags for remote CSS resources in the emails that point to a web server you own and track requests for these resources as potential indicators that the emails were delivered.

Is there a similar registered domain that lacks an SPF record?

You may be able to find domains that have been registered that look very similar to your target organization’s domain, but have not been configured with any email security settings that would allow a mail server to confirm or deny a spoof attempt. In some cases, I’ve seen clients that buy up domains similar to their own to prevent typosquatting, but then forget to apply email settings to prevent spoofing. In other cases, I’ve seen opportunistic domain squatters who buy look-alike domains in case they may become valuable, and don’t bother to set up any DNS records for their domains. In either case, we can potentially spoof these domains and the mail server will have no way of knowing we don’t own them. While this might mean we are starting off with a generally low trust score, most mail servers will not outright reject messages just because the sending domain lacks a properly configured SPF record. That is because there are so many legitimate organizations that have never bothered to set one up.

Does your target organization have an expired domain listed in an ‘include’ statement in their SPF record?

Let’s say our target organization’s email domain is fabrikam.com, and we would like to spoof an internal email address (bigboss@fabrikam.com) while sending to our target users. Consider that fabrikam.com has the following SPF record as an example:

v=spf1 mx a ip4:12.34.45.56/28 include:sendgrid.net include:imexpired.net -all

This SPF record lists the hosts/IPs that are allowed to send emails from frabrikam.com. Here is a breakdown of what each piece means:

v=spf1

This is an SPF version 1 TXT record. Used to distinguish SPF from other TXT records.

mx

The IP of the domain’s MX (mail server) record is trusted to send emails from fabrikam.com

a

the IP from doing a forward DNS lookup on the domain itself is also trusted

ip4:12.34.45.56/28

Any IP in this small range is trusted to send emails from fabrikam.com

include:sendgrid.net

any IPs or IP ranges listed in sendgrid.net’s SPF record are also trusted

include:imexpired.net

any IPs or IP ranges listed in imexpired.net’s SPF record are also trusted

-all

every other sending IP that was not listed in the previous directives is explicitly denied from sending emails claiming to be from fabrikam.com

As this demonstration shows, the ‘include’ directive in SPF allows you to trust other domains to send on your domain’s behalf. For example, emailing services like sendgrid can be configured to pass SPF checks so that sendgrid can deliver marketing emails from fabrikam.com to their customers. In the case of our example, if our client previously trusted imexpired.net to send emails, but the domain is now expired, it means we buy imexpired.net and add our own server to imexpired.net’s SPF record. We will then be able to pass SPF checks for fabrikam.com and spoof internal users.

Can we bypass SPF protections with other technical tricks?

Depending on the receiving mail server’s configuration, there may be other ways we can spoof domains that we do not own. For example, some email servers do not require SPF alignment. This means that we can have a mismatch between the domain we specify in the ‘MAIL FROM’ SMTP command, and the ‘From’ field in the message content itself. In these cases, we can use either a domain we own and can pass SPF for, or any domain without an SPF record in the ‘SMTP FROM’ command and then choose any other domain for the email address that our target user sees in their mail client. Another trick we can sometimes use is to supply what’s known as the “null sender”. To do this, we simply specify “<>” as the sender. The null sender is used for bounce messages and is sometimes allowed by spam filters for troubleshooting.

SMTP is a purely text-based protocol. This means that there is often ambiguity in determining the beginning and end of each section of data and SMTP implementations often have parsing flaws that can be abused to bypass security features like SPF and DKIM. In 2020, Chen Jianjun et. al published a whitepaper demonstrating 18 separate such flaws they discovered and that affected even some big email providers like Google:

https://i.blackhat.com/USA-20/Thursday/us-20-Chen-You-Have-No-Idea-Who-Sent-That-Email-18-Attacks-On-Email-Sender-Authentication.pdf

https://www.usenix.org/system/files/sec20fall_chen-jianjun_prepub_0.pdf

They also published the tool they used to discover these vulnerabilities, as well as their research methodology. While they disclosed these vulnerabilities to the vendors they tested, they did not test every major SEG for all of these vulnerabilities, and you might find that some popular SEGs are still vulnerable ;)

In 2023, Marcello Salvati demonstrated a flaw in a popular email sending service that allowed anyone to pass SPF for millions of legitimate domains.

https://www.youtube.com/watch?v=NwnT15q_PS8

His DefCon talk on the subject demonstrates his research and discovery process as well. I know that there are similar flaws in some other major email sending services, but I will not be throwing them under the bus in this post. Happy hunting!

Purchasing Brand New Domains

Pros

  • We can set up SPF, DMARC, DKIM to ensure we pass these checks
  • We control the MX record so we can receive mail at this domain
  • More granular creative control over the name

Cons

  • May take some time to build a reputation before sending a campaign

Purchasing Expired Domains

Pros

  • We can set up SPF, DMARC, DKIM and ensure we pass these checks
  • We control the MX record so we can receive mail at this domain
  • More likely to already be categorized
  • You may have wayback machine results to help keep the current category
  • You might salvage some freebee social media accounts

Cons

  • Little control over the domain name. You can get key words but otherwise just have to get lucky on which ones become available

Considerations for any Purchased Domain

The two major advantages to using domains we own for phishing is that we can specify the mail server and mail security settings for the domain. This means that we can actually have back-and-forth conversations with phishing targets if we need to. This opens up the possibility for more individualized pretexts. By setting up our own SPF, DMARC, and DKIM records, we can ensure that we pass these checks to give our emails a high probability of passing reputation based checks.

The third benefit of owning a domain is that we can control more factors that might help us categorize the domain. Email gateways, web proxies, and DNS security appliances will often crawl new domains to determine what kind of content is posted on the domain’s main website if one exists. They then make a determination of whether to block or allow requests for that domain based on the type of site it is. Security products that include category checks like this are often configurable. For example, some organizations block social media sites while others allow employees to use social media at work. In general, most network administrators will allow certain common benign categories. A couple classic desirable categories for red teamers are ‘healthcare’ and ‘finance’. These categories have additional benefits when used for command and control (C2) traffic, though for the purposes of delivering emails, we really just need to be categorized as anything that’s not sketchy. If your domain is not categorized at all, or in a ‘bad’ category, then your campaign will be dead in the water, so here’s some tips on getting off the naughty list.

Categorizing New Domains

.US.ORG Domains

One of my favorite shortcuts for domain categorization is to register domains off the ‘us.org’ or similar top levels. Because ‘us.org’ is a domain registrar, its Bluecoat category is ‘Web Hosting’, and has been around for many years. The minute you buy one of these domains, you are automatically going to be lumped in a generally benign and frequently allowed category.

Categorize with HumbleChameleon

While Humble Chameleon (HC) was designed to bypass multi-factor authentication on phishing assessments, it also has some great features for ‘hiding behind’ benign domains. You can set HC’s ‘primary_target’ option to point at a site you would like to mimic and let the transparent proxy do the rest.

Warning: any time your domain is crawled, your server will be forwarding traffic to the impersonated site. I have seen logs on my server before where someone was scanning my site for WordPress vulnerabilities, and therefore causing my server to send the same malicious traffic to the site I was impersonating. While the chances of being sued for this are pretty low, please be aware that this technique may put you in a bit of a gray area. Choose targets wisely and keep good logs.

Categorizing with Clones and Nginx/Apache

If you’ve never used httrack to clone a site, you should really do yourself a favor and explore this absolute classic! How classic you ask? Xavier Roche first released this website cloner back in 1998 and it’s still a great utility for quickly cloning a site. Httrack saves website resources in a directory structure that is ideal for hosting with a static Nginx or Apache web server. The whole setup process can be easily scripted with Ansible to stand up clones for domain categorization.

Categorizing with Chatgpt and S3

The more modern version of static site hosting is to ask an AI bot to write your website for you, and then serve the static content using cheap cloud services like S3 buckets and content delivery networks. If you get stuck, or don’t know how to automate this process, you can just ask the robot ;)

Categorizing Expired Domains

Whenever you purchase an expired domain, you should go ahead and check its category before you buy. It’s much easier to maintain a good category than to try to re-categorize a domain, so only buy it if it’s already in a benign category. Once you buy one, you have two options to maintain the category. You can either generate some new content or re-host the site’s old content. If you want to generate new content, the AI route is probably the most efficient. However, my preferred approach is to just put the content of the old site back up on the Internet. If that content was what got the original categorization, then it should also keep it in the same category.

Categorizing with Wayback

If the expired domain you just purchased was indexed by the Wayback Machine, then you can download the old pages with a simple Ruby script:

https://github.com/hartator/wayback-machine-downloader

This script is insanely easy to install and use, and will generally get you a nice static site clone within minutes when paired with Nginx, Apache, etc. Keep in mind that you may want to manually modify site content that might still be under copyright or trademark from the prior owner.

Social Media Account Bonus

For expired sites you’ve bought, have you ever set up a mail server and monitored for incoming emails? I have! And the results can be fascinating. What you might find is that the domain you just bought used to belong to a functioning company, and some of that company’s employees used their work email to sign up for services like social media sites. Now, the company went under, those employees don’t have access to their former work email, but you do. Once again, I need to stress that this is a legal gray area, so do what you can to give these people back their accounts, and change PII on any others you decide to keep as catphish accounts.

General Tips for any Domain

Send Some ‘Safe’ Emails First

Some SEGs will block emails from domains they have never seen before regardless of reputation. Therefore, it’s generally a good idea to send some completely benign emails with your new domain before you send out any phishing pretexts. You can address these to the ‘info@’ or similar generic mailboxes and keep the messages vague to hopefully go unnoticed/ignored by any humans on the other end. We’re just trying to prime the SEG to make a determination that emails from our domain are safe and should be allowed in the future. I’ve also heard that adding hidden links to emails with HREFs that point to your domain will also work against some SEGs, though I have not personally experimented with this technique.

Use Sendgrid, MailChimp, etc.

These services specialize in mass email delivery for their clients. They work tirelessly to keep their email servers off of block lists and help marketers deliver phishing campaigns… ahem I mean ‘advertisements’ to their targets… oops I mean ‘leads’. Once again, marketing tools are your friend when cold emailing. Keep in mind that these services don’t appreciate scammers and spammers like you, so don’t be surprised if you get too aggressive with your phishing and your account gets blocked. Yet another argument for keeping campaigns small and targeted.

Use your Registrar’s Email Service

Most domain registrars also offer hosting and email services. Some even provide a few mailboxes for free! Similar to email sending services, your registrar’s mail servers will often be delivering tons of legitimate messages for other customers and therefore have a good reputation from an IP perspective. If you take this route, be sure to let the registrar know that you are a penetration tester and which domains you will be using for what campaigns. Most I’ve worked with have an abuse email address and will honor your use case.

Use Gmail for the Long Con

Personal emails are often a blind spot for corporate email filters. Completely blocking inbound emails from Gmail, Yahoo, Outlook, etc. is a tough pill to swallow and most network administrators decide to allow them instead of answering constant requests from employees to put in an exception for this or that sender. In addition, it’s extremely difficult to apply reputation scores to individual senders. Therefore, if you can think of a pretext that would make sense to come from a Gmail account, you have a high probability of at least bypassing domain reputation checks. This can work really well for individualized campaigns where you actually have a back-and-forth conversation with the targets before link/payload delivery.

Set Up SPF, DKIM, and DMARC

For sending domains you own, it will always work in your favor to set up email security settings. Check the API documentation for your registrar and write a script to set these DNS settings.

Read the Logs!

When you do start sending emails with a domain, make sure to watch your SMTP logs carefully. They are often extremely helpful for identifying if your messages are being blocked for reasons you control. For example, I know Mimecast will frequently block emails from new senders that it hasn’t seen before, but will respond with a very helpful message explaining how to get off their ‘gray list’. The solution is simply to resend the email within the next 24 hours. If you aren’t watching the logs, you would be blocked when you could easily deliver your email.

Parting Wisdom

“What I recalled of Sunday School was that the more difficult something became, the more rewarding it was in the end.” — Big Phish


One Phish Two Phish, Red Teams Spew Phish was originally published in Posts By SpecterOps Team Members on Medium, where people are continuing the conversation by highlighting and responding to this story.

The post One Phish Two Phish, Red Teams Spew Phish appeared first on Security Boulevard.

❌