5 min read By Excello Mail Team

50 Requests, 50 Different Pages: A Polymorphic Phishing Kit That Occasionally Breaks Itself

SANS Internet Storm Center handler Xavier Mertens pulled a phishing link from a spam trap and found a kit that rebuilds its credential-harvesting page from scratch on every single request, using randomized code and zero-width characters to defeat hash-based detection, undone in one out of fifty tries by an unscoped variable name.

Most phishing kits get caught the same way: a security vendor fingerprints the page, hashes it, and pushes that hash into a blocklist that every other vendor eventually inherits. It is slow, but it works, because most kits serve the same HTML to everyone who clicks the link. SANS Internet Storm Center handler Xavier Mertens found a kit that refuses to play by that rule at all. Every request to the same URL comes back structurally different, which means every hash-based defense checking it is chasing a target that never holds still. The interesting part is not that the evasion works. It is that the mechanism built to make it work is buggy enough to occasionally sabotage itself.

Fifty Requests, Fifty Fingerprints

Mertens pulled the phishing link from a message caught in a spam trap and, instead of just recording it and moving on, wrote a script to fetch the same URL fifty times in a row and compare what came back. Every one of the fifty samples produced a distinct SHA-256 hash. The page title alone rotated across at least 21 different values, cycling through deliberately bland words like Solution, Viewer, Credentials, Private, and Authenticate, none of which would mean anything to an analyst glancing at a URL scanner’s output. Form and input field names, CSS class names, and element identifiers were all reshuffled between requests. Numeric values inside the code were rewritten as arithmetic expressions instead of plain digits. Zero-width characters were inserted inside otherwise visible strings, an old trick for defeating simple text-matching rules that a human reader would never notice. None of this changes what the page does to a visitor. It exists purely to make sure no two copies of it look alike to a machine.

The Bug Hiding Inside the Obfuscator

Forty-nine of the fifty samples deobfuscated cleanly and displayed the credential form as designed. One did not. It got stuck in an infinite loop instead of rendering anything at all. Mertens traced the failure to the obfuscator’s own randomization: two separate functions in the decoding chain had been given different, randomly generated names, which is exactly what a polymorphic engine is supposed to do, but both of those functions’ loops referenced the same undeclared variable, a lowercase k. Because the variable was never declared with its own scope, JavaScript treated it as a single shared global rather than two independent counters, and when both functions tried to use it at once, the loop never terminated. The obfuscator was systematic enough to rewrite nearly everything else about the page on every pass. It was not disciplined enough to check that its own renaming logic respected variable scope, so roughly one in fifty visitors got a broken page instead of a working credential trap.

Polymorphism Is a Detection Problem, Not a DMARC Problem

None of this touches the question DMARC, SPF, and DKIM exist to answer, which is whether the domain in a message’s From header had the authority to send it. The polymorphism happens entirely after a click, on infrastructure the attacker controls outright, rewriting the page a browser renders rather than anything about how the email that carried the link got authenticated or delivered. A message pointing at this kit could, in principle, pass every authentication check a receiving mailbox runs and still land a user on a page built specifically to defeat the hash-matching and static-signature tools sitting downstream of that inbox. Authentication protocols were never designed to evaluate what a link ultimately renders, and a kit like this is a reminder of exactly how much ground sits past that boundary, still worth defending, just not with the same tools.

What This Means for Your Program

Do not rely on hash or exact-signature matching as your only defense against credential-harvesting pages. A kit that regenerates its HTML on every request will produce a new hash for every analyst, every sandbox, and every automated crawler that touches it, making static fingerprinting a losing race by design.

Push link and content inspection further down the chain, not just at the inbox. Since DMARC only validates the sending domain, a security stack needs a separate layer, sandboxed link detonation, behavioral page analysis, or browser isolation, that actually evaluates what a URL delivers once someone clicks it.

Treat inconsistent or broken phishing pages as a detection opportunity, not a dead end. A kit’s own bugs, like the shared variable that froze one in fifty samples here, can sometimes provide a more reliable fingerprint than the page’s intentionally randomized content ever will.

Keep collecting and comparing multiple samples of the same suspicious URL before drawing conclusions. A single fetch of a polymorphic page tells you almost nothing about the kit behind it. Repeated sampling, the way Mertens approached this one, is what actually reveals the pattern.

The Takeaway

A phishing kit that rewrites its own HTML on every single visit represents a real step up in how hard these pages are to catch with the signature-based tools most defenses still lean on. It also represents, in the one broken sample out of fifty, a reminder that attackers build under the same pressure and same sloppiness as everyone else, and that sophistication in one dimension does not guarantee correctness in another. Neither the evasion nor the bug has anything to do with DMARC, because both live entirely on the far side of the click. That is not a flaw in DMARC. It is a scope, and every organization’s defense needs a layer built specifically for what sits past it.


DMARC tells you whether a domain had the authority to send a message. It cannot tell you what a link inside that message renders once someone clicks it, polymorphic or otherwise. Excello Mail turns your DMARC aggregate reports into a clear, continuous record of every service sending as your domain, so the layer authentication actually covers stays watched while your team builds the defenses for everything past the click. Sign up for free to Excello Mail and get that foundation in place.