Table of Contents
A municipal city government mailbox received an email one line long. It said a payment had been received, pointed at the attached invoice, and gave a support phone number. The attachment was a PDF invoice for a consumer antivirus renewal, $545.75, marked paid in full with a remaining balance of zero. Nobody at the city had bought it.
The document's own metadata records when it was produced. Converted to a common reference, that creation time matches the message's Date header exactly. Not the same minute. The same second.
Printed at the Moment of Send
The document information dictionary, stored in UTF-16BE, reads /Title (Invoice), /Creator (wkhtmltopdf 0.12.6), /Producer (Qt 4.8.7), then a creation date. That toolchain is a general-purpose command-line renderer that turns HTML into PDF, whose most common legitimate use is exactly this job: generating invoice documents from a template, programmatically.
What is unusual is not the tool. It is the timing. A creation stamp landing in the same second as the send time means the file was produced by the sending process itself, as the mail went out, rather than pulled from a folder of prepared attachments. Two metadata fields can be edited; a same-second match between a document and the message carrying it is a property of how the campaign runs.
An Empty Annotation Array and an Empty Image Dictionary
The rest of the file is remarkable for what is missing. The page object declares an annotation array, and the object it points to is literally an empty pair of brackets: zero link annotations, no clickable region anywhere in the document. The resource dictionary declares an image container that is also empty, so the file holds no images. The document catalogue is three tokens long. No form dictionary. No open action. No name tree.
The visible content is pure text, drawn with two embedded font subsets, one bold and one regular. Independent attachment analysis reported the same profile: no JavaScript, no form fields, no launch action, no embedded files, zero URI objects. The file weighed 22,286 bytes and scanned clean.
A clean verdict normally means nothing was found, with the implication that something may have been hidden well. Here nothing was found because nothing was there. The attacker did not conceal the attack surface. They deleted it.
Reading the Invoice Without Decompressing It
Embedded font subsets carry a character map, and in a subset from this renderer the glyphs are listed in order of first use, which makes the map an index of what the page says and in what order. The regular subset spelled out the order identifier QKRI-3018-ZSS, a month name, the greeting word, then the recipient's own mailbox local part. The bold subset began with the forged McAfee brand name.
So the greeting was personalised from the mailbox address, a template variable filled with the local part, which is list-driven sending rather than research. And the product line on the invoice, TrustShield, reads as invented and should not be assumed to exist in the real vendor's catalogue. Brand-name matching passes on the brand, and nobody checks the product against a price list.
Eight Hours Ahead of Its Own Mail Path
PDF timestamps carry a time zone offset, and this one declared UTC+8. The mail path did not. The message was submitted through a Google Workspace account belonging to a South American university, travelled out through Gmail infrastructure, and arrived at a United States inbound security gateway. The submission address in the Gmail receipt line matches the UTC+8 offset, not the relay path.
The same offset explains an inconsistency on the face of the document: the printed invoice date sits one calendar day ahead of the send date, because in the operator's own zone the clock had already passed midnight. It is a location leak, written by the rendering tool in a field nobody edits.
Passed Upstream, Failed at the Door, Delivered as Trusted
At the inbound gateway: DKIM pass for a Workspace signing domain derived from the sender's own apex domain, SPF pass designating the Gmail egress address as a permitted sender, no usable DMARC policy found. One hop later at the Microsoft handoff: SPF softfail, DKIM fail with the explicit reason that the body hash did not verify, no DMARC action, and composite authentication returning nothing at all.
That body-hash failure has a benign cause worth stating plainly. The gateway appended its own external-sender caution banner after the message had been signed, and any modification after signing breaks the hash, exactly as RFC 7489 assumes it will. It is documented behaviour, not tampering. The gateway also re-sealed the message with an ARC record, which Microsoft validated even while the underlying signatures failed.
Then the decision that mattered got made, and none of those signals fed it. Microsoft assigned a spam confidence level of minus one, the value reserved for trusted mail, because the message came from an allow-listed gateway. One mailbox was affected and the recorded mitigation was no action taken. The irony sits one hop upstream: that same gateway had scored the message spam 8 and matched two of its own threat dictionaries, and its verdict did not survive the handoff. Reconciling an upstream verdict against a downstream trust decision is the argument for augmenting a gateway rather than chaining verdicts and trusting the last one.
See Your Risk: Calculate how many threats your SEG is missing
What Was Left to Evaluate
With no link to resolve and no active object to inspect, the only evaluable material was identity and behaviour. Themis, the IRONSCALES Adaptive AI analyst, returned 90 percent confidence and labelled the message a vishing attack, the correct class rather than a near miss.
Its signals were all behavioural. A first-time sender with no correspondence history. A display name unrelated to the mailbox it sent from. A greeting addressed to a mailbox local part instead of a person. A consumer security brand asserted with no matching sender domain. An unfamiliar charge presented as already paid. And one phone number as the only available action.
Presenting the charge as settled is the clever part of the pretext. There is nothing to pay, so there is no payment page to scan and no deadline to fake. The victim supplies the urgency by calling to dispute money they did not spend. MITRE ATT&CK tracks that as spearphishing voice, and whether this number was answered is unknown. The 2024 Verizon Data Breach Investigations Report puts a human element in 68 percent of breaches. This message reduced itself to that element alone.
Hunting a Toolchain and a Time Zone
Flag inbound branded invoices whose creator and producer strings belong to a generic command-line rendering toolchain, because a real vendor's billing system names itself. Treat a creation timestamp matching the message Date header to the second, alongside a declared time zone that disagrees with the mail path, as a composite signal; neither half is suspicious alone. And classify a zero-URI, zero-annotation, zero-image attachment carrying a support phone number as a callback lure class in its own right.
For users, one rule covers the family, consistent with CISA phishing guidance and the behaviour NIST describes: never dial a number that arrives in a document. Verify the vendor independently, then report it. A callback lure only pays if somebody calls.
Indicators of Compromise
| Type | Indicator | Context |
|---|---|---|
| Phone | +1(656) 556-2142 | Attacker-controlled callback number, the entire payload; printed in the one line body and again inside the invoice as a support line |
| File | Open_ invoice document invoice Receipt and and save your printed receipt.pdf | Text-only invoice attachment, 22,286 bytes, shown with MIME header folding normalised out |
| Hash | 3616ffe782f4a04a2c2d1f8fc2d32684 | MD5 of the invoice PDF |
| Hash | dea7b0a198826b15e7493d9918258d120ec831c286cd69038107d1e2214832cc | SHA256 of the invoice PDF |
| Artifact | /Producer (Qt 4.8.7) with /Creator (wkhtmltopdf 0.12.6) | Generic command-line HTML rendering toolchain declared in the document information dictionary; a real vendor billing system names itself instead |
| Artifact | Document creation timestamp equal to the message Date header to the second | The attachment was rendered by the sending process at the moment of send, not attached from a prepared library |
| Artifact | Declared PDF time zone offset of +08'00' | Rendering host sat eight hours ahead of a mail path that ran through Gmail and a United States gateway |
| Artifact | Empty annotation array, empty image container, three-token document catalogue | Zero link annotations, zero images, no form dictionary, no open action, no name tree |
| Artifact | Zero count for URI objects, JavaScript, form fields, launch actions and embedded files | No active content and no extractable web address anywhere in the file; scanned clean |
| Artifact | Order identifier QKRI-3018-ZSS | Fabricated order reference giving the receipt the texture of a real one |
| Artifact | TrustShield | Product name presented on the invoice; should not be assumed to exist in the impersonated vendor's catalogue |
| Artifact | $545.75 total, $545.75 paid, 0.00 USD remaining | Charge presented as already settled, so the lure is a dispute rather than a payment |
| IP | 162[.]62[.]63[.]230 | Submission address recorded in the Gmail receipt line, consistent with the document's UTC+8 offset rather than the relay path |
| Subject | "Open: invoice document invoice Receipt and and save your printed receipt" | Duplicated words inside the subject, a template assembled badly |
| Behavior | Greeting resolved to the recipient's mailbox local part rather than a name | Template variable filled from the address, recovered from the embedded font character map; the value itself is withheld |
| Behavior | First-time sender, no correspondence history, display name unrelated to the sending mailbox | Sending identity was a mailbox at a bystander university on Google Workspace, address and apex domain withheld |
| Behavior | SPF pass and DKIM pass at the inbound gateway, SPF softfail and DKIM body-hash fail at the final hop | Per-hop authentication divergence on one delivery; the body-hash failure was caused by the gateway appending its own caution banner after signing |
| Behavior | Spam confidence level of minus one at the final hop | Delivered as trusted because the last hop was allow-listed, despite the softfail, the body-hash failure and no usable DMARC policy |
| Behavior | Upstream gateway spam score of 8 with two threat-dictionary matches | Correct upstream verdict that did not survive the handoff to the destination |
MITRE ATT&CK Mapping
| Technique | ID | Application |
|---|---|---|
| Phishing: Spearphishing Attachment | T1566.001 | Fabricated antivirus renewal invoice delivered as a text-only PDF attachment with no active content |
| Phishing: Spearphishing Voice | T1566.004 | One support phone number as the only call to action, moving the fraud onto a voice channel |
| Impersonation | T1656 | Consumer antivirus brand forged in the invoice header and footer, under a product name that reads as invented |
| Financial Theft | T1657 | Charge presented as already paid to provoke a dispute call, the point at which payment or remote access is extracted |
| Masquerading | T1036 | Attachment shaped as an ordinary vendor receipt, structurally indistinguishable from a legitimate template-rendered invoice |
See You Next Time
The strongest evidence here was a timestamp and an empty pair of brackets. The only control that got it right was the one that never looks at the file. Check back tomorrow.
Related attacks
| Attack | What happened |
|---|---|
| A Real Zoom Alert, Resent by the Attacker Who Asked for It | Zoom really sent this sign-in alert. |
| The PayPal Phish With No Link and No Brand Name | The brand was typed only in leetspeak, the substituted glyphs were shrunk a few pixels so they read as letters, and the sole payload was a phone number. |
| McAfee Renewal Scam Sent Under the Victim's Own Name | A fake McAfee renewal receipt carried no link and no attachment. |
| A Real Squarespace Invite Carried a Fake Norton Bill | A genuine Squarespace contributor invitation, sent through SendGrid with every authentication check passing. |
| The Fake McAfee Renewal Typed Into a Calendar Field | The scam copy was typed into a calendar event's description field, so Google's own notifier wrote and delivered it from a real. |
Explore More Articles
Say goodbye to Phishing, BEC, and QR code attacks. Our Adaptive AI automatically learns and evolves to keep your employees safe from email attacks.