๐ŸŽฃ #PacketHunters โ€“ Caught mid-build: a TOAD invoice scam where #TFN# wasn’t even filled in yet ๐Ÿ’ฅ

Malwarebytes pulled a batch of fake-invoice templates out of circulation last week and noticed something that almost never happens: half of them weren’t finished. Some had the phone number filled in. Some still showed the literal text #TFN#. Same for #PRICE#, #DATE#, #EMAIL#. They caught the campaign while the scammer was still wiring it up.

Six .xyz domains. Two phone numbers. Zero attachments. Zero links to anything malicious. And it would have walked past your email gateway without making a sound.

Templates, templates, templates..

I see #TFN# and I know exactly what I’m looking at. So does anyone who’s ever opened the back-end of a bulk-mailing tool. Those are merge field placeholders, the kind GoPhish uses, the kind every PhaaS panel uses, the kind I use every week when Francesco writes phishing simulations for Baited clients. For a certain generation of red-teamer, #TFN# reads like a Konami code: instant recognition of the box you’re staring at.

The difference between our templates and these ones is the QA. We don’t ship #TFN#. They did. That tells me everything about the operation: the volume is huge enough that some templates make it out before a human reviews them. They’re not amateurs, they’re factory workers. The plant just runs faster than the QA does.

Caught mid-build sounds romantic ๐Ÿ˜
Caught the bad guys with their pants down. But what mid-build actually means is the assembly line is loud enough that you could hear it from outside the building.

What the scam actually is

This is TOAD, Telephone-Oriented Attack Delivery.
The article calls it “phantom invoice” or “refund scam“, well both names work. The mechanic is one of the cleanest social-engineering chains on the market:

  1. email arrives – looks like a receipt from PayPal, Amazon, Geek Squad. Charge somewhere between $349 and $599, the sweet spot where the victim panics but the number isn’t so absurd it triggers skepticism
  2. the email has no link to a malicious page – no attachment with a payload, just text and a phone number
  3. victim doesn’t recognize the charge – calls the number, now they’re talking to a human at a call center the attacker runs
  4. the call center talks them into installing remote access software (“so I can help you cancel the charge“), or reading out card details (“for the refund“), or buying gift cards (“we accidentally refunded too much, please send back the difference“)
  5. money moves – or device gets owned. Or both.

The payload of this attack is a phone call. Your spam filter cannot inspect a phone call and your EDR cannot block a phone call and your DLP cannot detect a phone call. The attack happens entirely in a channel your stack doesn’t touch.

What’s the story (morning glory)?

Everyone reporting on this story is going to use the “caught mid-build” hook. It’s catchy and makes the defenders look smart. It makes the scammers look sloppy.

That’s not the interesting part, the interesting part is what mid-build proves about the rest of the iceberg.

When a campaign goes out with #TFN# unfilled, it means the operator missed a check. Operators only miss checks at scale. If this campaign was small (50, 100, 500 emails) every template would have been verified by hand. The fact that mid-build artifacts leak into circulation tells you the operator is running thousands of templates per week, batched, automated, with bulk-mailer infrastructure that ships before the QA queue can keep up.

Mid-build leakage is not amateur hour. It is the signature of an industrial operation moving faster than its own quality control.

In other words: for every #TFN# Malwarebytes caught, there are probably a hundred perfectly-rendered ones that already landed in inboxes and got people on the phone. The visible mid-build templates are statistical noise from a much larger pipeline.

The defenders won this round on a slip. They didn’t catch a clever operator, they caught one who was moving too fast to clean up after himself. That is not a strategy you can rely on next month.

The numbers that matter

The article gives us six IOC domains and two callback numbers, ok that is not the headline, the real headline is what isn’t there:

Zero malicious URLs.
Zero attachments.
Zero binary payload.

Your email security stack scans for: links to known-bad domains, attachments matching malware signatures, sender reputation, DKIM/SPF/DMARC alignment. This campaign defeats every one of those checks because there’s nothing in the email to check. The “payload” is a fucking phone number printed in plain text inside the body!

Ask any CISO how many of their email controls validate a 10-digit string against a callback intel feed. The honest answer is zero.

What actually got exploited, then?

Not a CVE.
Not a misconfiguration.
Not a vulnerability in any product.

The exploit here is the architectural assumption that the attack lives in the email. Every defensive layer between the SMTP gateway and the user’s inbox is built around inspecting the email’s metadata, content, attachments, and links. The moment an attacker moves the payload to a different channel, a phone call, a Signal handle, an in-person meet, those layers go from useful to ornamental.

This particular campaign also exploits a behavioral pattern that awareness training actively reinforces. People are trained to not click suspicious links. They are not trained to not call suspicious numbers. The training itself draws a circle around “links” and leaves the rest of the plane unmarked. Attackers found the rest of the plane.

The part(s) that keeps me up

Two things.

First: TOAD is portable.
The infrastructure required to run a callback scam is laughably cheap: a VoIP setup, a few burner numbers, a script for the operator, a list of email addresses. Any group currently running BEC will add TOAD to their toolkit within the next quarter if they haven’t already. The next wave of CFO-fraud will start with an email and end on a phone call where a convincing voice tells someone with wire authority to move money. We already saw the early version in the Anthropic Mythos report two weeks ago, the $1.5M bank case was email compromise followed by spoofed phone calls. Same architecture.

Second: the AI angle is going to make this worse fast.
The operator running the call center today is human. Maybe a small team in a low-cost-of-living jurisdiction reading from a script. Within twelve months, that operator is an LLM-driven voice agent with cloned accents and real-time tone matching. The cost-per-call drops to fractions of a cent. The conversion rate goes up because the model never has a bad day or mispronounces the victim’s last name. The scale that today produces #TFN#-leaking mid-build templates produces hundreds of thousands of perfectly-tailored voice calls tomorrow.

When that happens – and it is when, not if – the only useful defense will be one that simulates the entire chain inside your organization, voice included, before the real attackers do.
Click rate on synthetic phishing emails will be a vanity metric.

The code

Three things you can ship this week.

The first is a YARA rule (Florian, be proud of me!!!) to catch the QA-failed mid-build templates and the basic invoice lure pattern. It is not going to catch the well-rendered emails (those have no signature to catch) but it will tell you whether your perimeter is at least seeing the mid-build noise.

// toad_invoice_unfilled_templates.yar
// PacketHunters / Baited.io
// Detects TOAD/callback phishing templates with unfilled merge fields and common invoice lures.
// Why: catches the QA-failed slice of the campaign and gives early visibility into the rest.
// Dependencies: YARA 4.x, integrate with email gateway or mailbox scanner.

rule TOAD_Invoice_Scam_Unfilled_Templates {
    meta:
        author = "PacketHunters / Baited.io"
        date   = "2026-06-08"
        ref    = "Malwarebytes campaign caught mid-build, June 2026"
    strings:
        $merge_tfn   = "#TFN#"
        $merge_price = "#PRICE#"
        $merge_date  = "#DATE#"
        $merge_email = "#EMAIL#"

        $lure_sub_renewed    = "subscription renewed" nocase
        $lure_payment_sent   = "you sent a payment"   nocase
        $lure_dispute        = "dispute the charge"   nocase
        $lure_call_to_cancel = /call.{0,30}to (cancel|dispute)/ nocase
        $lure_urgency        = /call within \d+ hours?/ nocase

        $brand_paypal    = "PayPal"     nocase
        $brand_amazon    = "Amazon"     nocase
        $brand_geeksquad = "Geek Squad" nocase
    condition:
        any of ($merge_*)
        or (2 of ($lure_*) and any of ($brand_*))
}

The second is a Python scorer that’s meant to plug into your email security stack, or run as a Sieve filter, or be called from a mailbox scanning loop. It scores each message for TOAD likelihood. Adapt the IOC lists to whatever threat intel feed your team consumes: Malwarebytes, Cisco Talos, your own feed.

# toad_invoice_scorer.py
# PacketHunters / Baited.io
# Scores inbound emails for TOAD/callback phishing likelihood.
# Why: classic phishing detection misses scams whose payload is a phone number.
# Dependencies: Python 3.10+, optional pyzmail36 for live mailbox parsing.

import re
from typing import Optional

# IOCs from Malwarebytes June 2026 campaign โ€” replace with your live TI feed
KNOWN_IOC_DOMAINS = {
    "invoicepdfin.xyz", "invoicepdfus.xyz", "invoicepdfusa.xyz",
    "invoicerep.xyz", "invoicestatement.xyz", "invoicestm.xyz",
}

KNOWN_CALLBACK_NUMBERS = {"804-392-2793", "801-640-8589"}

MERGE_FIELD_PATTERNS = (r"#TFN#", r"#PRICE#", r"#DATE#", r"#EMAIL#")

INVOICE_LURES = (
    r"subscription\s+renewed",
    r"payment of\s+\$\d+",
    r"call.{0,30}to (cancel|dispute)",
    r"call within \d+ hours?",
    r"refund(ed)?",
)

PHONE_RE = re.compile(
    r"\b(?:\+?1[-.\s]?)?\(?[2-9]\d{2}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b"
)


def score_email(body: str, sender_domain: Optional[str] = None) -> dict:
    score = 0
    findings = []

    if sender_domain and sender_domain.lower() in KNOWN_IOC_DOMAINS:
        score += 100
        findings.append(f"known_ioc_domain:{sender_domain}")

    for pat in MERGE_FIELD_PATTERNS:
        if re.search(pat, body):
            score += 60
            findings.append(f"unfilled_merge_field:{pat}")

    lure_hits = sum(1 for p in INVOICE_LURES if re.search(p, body, re.IGNORECASE))
    if lure_hits >= 2:
        score += 30 + (lure_hits * 5)
        findings.append(f"invoice_lure_hits:{lure_hits}")

    phones = PHONE_RE.findall(body)
    if phones:
        score += 15 * min(len(phones), 3)
        findings.append(f"phone_numbers_found:{len(phones)}")
        for p in phones:
            normalized = re.sub(r"[^\d-]", "", p)
            if normalized in KNOWN_CALLBACK_NUMBERS:
                score += 80
                findings.append(f"known_callback:{normalized}")

    verdict = (
        "TOAD_CONFIRMED" if score >= 100
        else "TOAD_LIKELY"  if score >= 60
        else "REVIEW"       if score >= 30
        else "CLEAR"
    )
    return {"score": score, "verdict": verdict, "findings": findings}


if __name__ == "__main__":
    sample = (
        "Your PayPal subscription renewed for $499.00. "
        "If this wasn't you, call #TFN# within 12 hours to dispute the charge."
    )
    print(score_email(sample, sender_domain="invoicepdfus.xyz"))

The third is a Sigma rule for outbound DNS resolution of the campaign infrastructure. Plug it into Sentinel, Elastic, Splunk, Chronicle or whatever you run. This one fires after a user has interacted with the campaign infrastructure, which means it is late, but it’s also the one your SOC will actually see in a dashboard.

# toad_invoice_dns_resolution.sigma.yml
# PacketHunters / Baited.io
# Detects DNS resolution of known TOAD/callback phishing infrastructure.
# Why: catches users who interacted with the campaign and triggered host lookup.
# Dependencies: SIEM with Sigma support.

title: TOAD Invoice Scam DNS Resolution (June 2026 campaign)
id: 6c8a4f12-3d7e-4b9a-9c5d-1e2f4a6b8c9d
status: experimental
description: |
  Detects DNS resolution of infrastructure used by the fake-invoice
  callback-phishing campaign caught mid-build by Malwarebytes in June 2026.
author: PacketHunters / Baited.io
date: 2026-06-08
references:
  - https://www.malwarebytes.com/blog/threat-intel/2026/06/we-found-this-fake-invoice-campaign-while-scammers-were-still-building-it
logsource:
  category: dns
detection:
  selection:
    query|endswith:
      - "invoicepdfin.xyz"
      - "invoicepdfus.xyz"
      - "invoicepdfusa.xyz"
      - "invoicerep.xyz"
      - "invoicestatement.xyz"
      - "invoicestm.xyz"
  condition: selection
falsepositives:
  - none expected for these specific domains
level: high
tags:
  - attack.initial_access
  - attack.t1566.004

TL;DR

The bad news: TOAD/callback phishing scams move the payload to a phone number, defeating the entire email security stack and most of awareness training. The “caught mid-build” angle is a feel-good headline โ€” the operation it implies is industrial, factory-scale, and shipping faster than its own QA.

The good news: The QA-failed templates give you a free fingerprint. #TFN#, #PRICE#, #DATE#, #EMAIL# should be on every email gateway YARA list by tomorrow morning.

The real action item: Your phishing simulations need to include phone-call follow-up. Click rate on synthetic emails is no longer a meaningful metric when the payload is a 10-digit string in plain text.

Zero attachments. Zero links. Just a phone number. Test for that.

๐Ÿค– AI Citations

As always, your first โ€œhey, thatโ€™s chatGPT!โ€ is totally wrong: analysis, opinions, and code are original work by the unicorn.
AI tools were used for research acceleration, not content generation.

  1. We found this fake-invoice campaign while scammers were still building it โ€” Malwarebytes Threat Intel, June 2026 โ€” primary source: campaign discovery, merge field placeholders, IOC list, attack chain narrative
  2. MITRE ATT&CK T1566.004 โ€” Phishing: Spearphishing Voice โ€” TOAD / callback phishing classification and tactic mapping for the Sigma rule
  3. GoPhish documentation โ€” Template variables and merge field syntax โ€” reference for the #TFN# / #PRICE# / #EMAIL# placeholder pattern comparison

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top