Inside the GitHub Phishing Kits Impersonating Banks

A phishing page served from a github.io subdomain inherits three things its operator never had to buy or configure: a valid TLS certificate on a GitHub-controlled domain, a parent domain with enough legitimate traffic that reputation engines score it neutral or better, and free static hosting that survives the first round of abuse reports because what gets removed is a repository rather than a registered domain. A freshly registered lookalike domain carries the opposite profile, since low domain age, thin WHOIS history and an unremarkable certificate are precisely the signals that registrar-level and proxy-level detection is tuned to flag.

That asymmetry explains a pattern our analysts have tracked across dozens of incidents reported to banking clients over the past year: bank-impersonation kits are increasingly shipped as source code, published as a public repository, and served directly to victims through GitHub Pages. In that model the repository is simultaneously the delivery mechanism, the build artifact and the operator’s working directory, which means the entire kit is readable before a single victim ever submits a credential.

One of our analysts who covers the banking sector described the triage process this way: “You develop a kind of pattern recognition after a while. I can usually tell within the first 30 seconds of opening a repository whether it’s a real phishing kit or just a developer’s test project that happens to mention a bank’s name. It’s rarely one obvious thing; it’s a combination: a throwaway account with no history, a repo created and finished in the same day, and a file structure that has nothing to do with an actual banking product.”

The question worth asking is therefore narrower than “is this brand being mentioned”, because plenty of legitimate repositories mention bank names in dependency lists, integration tests and documentation. The useful question is this: which structural and behavioural artifacts inside a repository separate a live credential-harvesting kit from a developer’s sandbox, and which of those artifacts can you pivot on to find the rest of the same operator’s infrastructure?

Anatomy of a bank-impersonation repository

1. A cloned front end

Before any of the harvesting logic matters, the kit needs somewhere to live that does not look suspicious on first contact. GitHub Pages solves that requirement for free, turning any repository into a live HTTPS site on a github.io subdomain within minutes, and that subdomain is almost never present on a corporate proxy blocklist, an email-gateway denylist or a consumer antivirus reputation blacklist, because the same parent domain hosts millions of entirely legitimate projects.

The baseline kit bundles brand assets copied directly from the target’s real online banking portal or mobile application, including logo SVGs, icon sets, colour palettes and layout structure, with the goal of achieving pixel-level familiarity with the legitimate login flow. Some operators go one step further and rebrand the clone under a fictitious name rather than the real one, which lets them slip past brand-monitoring keyword searches while keeping the visual identity fully intact.

In one case, a kit targeting a French consumer-credit brand was found with the real brand name systematically find-and-replaced with “Jkl.oin” across every visible string, while the CSS, layout and content structure stayed untouched. A later and more advanced iteration from the same operator scaled this to 29 HTML pages covering the full credit-application journey, a four-stage personal-data collection form, a simulated customer portal with document upload, and a set of legal and GDPR boilerplate pages included purely to raise perceived legitimacy. The client-side validation script carried a hardcoded blocklist of more than 60 disposable-email domains, which is direct evidence that the operator was actively filtering junk submissions in order to keep only usable victim data.

Cloned consumer-credit homepage: layout, CSS and imagery lifted intact, brand name replaced with a fictitious label.

2. A multi-step credential-harvesting flow

Rather than presenting a single form that requests everything at once, the pages mirror the real authentication journey step by step, starting with a customer or account identifier, moving to a second screen for the secret access code or PIN, and occasionally adding a “final verification” step that requests a one-time SMS code. That last step is functionally a real-time OTP relay and MFA-bypass attempt rather than static credential theft, since the code is only useful to the operator inside a short validity window and therefore has to be consumed while the victim is still on the page.

Some kits extend well beyond static credential theft into an operator-driven confidence scam. One repository impersonating a Belgian digital banking app shipped with a functional operator-side admin panel, so that after harvesting a victim’s access PIN the attacker could edit the balance and transaction history rendered inside the fake app in real time. The workflow was to inject a fake incoming transfer, then persuade the victim they had received money by mistake and coax them into wiring it back to a mule account, and the kit bundled a client-side PDF-generation library specifically to fabricate a convincing fake transfer receipt as supporting proof.

Seeded transaction data inside the kit: IBANs, merchant names, amounts and dates pre-populated so the fake account history reads as plausible.

A separate and repeatedly reported kit ran an advance-fee variant instead, presenting a fake dashboard that showed a large six-figure balance flagged as blocked, unlockable only after the victim paid an upfront EUR 30,000 unlock fee into an account the operator controlled.

Advance-fee variant: a fabricated account balance flagged as blocked, with an explicit unlock fee.

3. Exfiltration: C2-lite over legitimate services

Where older phishing kits emailed stolen data to the attacker or wrote it to a flat file on a rented server, the current generation abuses legitimate third-party APIs as a lightweight command-and-control channel, which removes the need for attacker-owned hosting entirely and produces outbound traffic that terminates at a well-known and generally allowed destination.

The dominant pattern we observed is that the harvesting form issues a client-side POST request to a small serverless function, a Cloudflare Worker in most reviewed samples, whose only job is to relay the payload server-side to the Telegram Bot API. The operator then receives each victim’s credentials on their phone within seconds of submission, and this reliance on Telegram bots as an exfiltration channel is now common enough across commodity kits that the bot token itself is one of the more reliable pivot points available to an analyst.

One kit went a step further than simple relaying. The same worker function that pushed stolen data out to the attacker also, separately, called the real bank’s own public API in real time to pull in genuine data: a /lookup-postal endpoint took a postal code from the fake form and forwarded it live to the bank’s genuine postcode-lookup service in order to resolve which regional branch serves that address, so the dropdown the victim sees is always accurate.

The relay worker: one path pushes the payload to the Telegram Bot API, another queries the genuine bank postcode-lookup service so the victim-facing form returns real data.

Variants adapt the channel to their target audience rather than defaulting to Telegram everywhere. A kit impersonating a Vietnamese consumer-lending brand routed stolen data through a webhook into Zalo, Vietnam’s dominant messaging app, and funnelled the victim through a ten-step flow that collected national ID numbers, banking details and address data. The eKYC step in that flow was not simply a camera prompt for show, since it ran a real open-source face-detection library client-side against the victim’s webcam feed to produce convincing liveness cues, and the wider project pulled in the genuine web SDK from VNPT, the vendor that real Vietnamese banks use for identity verification, alongside production-grade tooling.

4. Anti-analysis and evasion

Several kits included a rudimentary anti-bot gate designed to fingerprint automated scanners and crawlers and serve them an inert decoy page instead of the phishing form, which is a direct attempt to defeat automated takedown pipelines and security-researcher tooling. Post-submission, some variants silently redirect the victim to the real institution’s website so that the session ends the way a normal login would, delaying both victim suspicion and any resulting fraud report, and that delay is what turns a single harvested credential set into a usable window for account takeover.

A bigger target than a password

Across the incidents reviewed, the kits are built to assemble a complete identity-and-access package rather than to steal a single login. The full set observed spans account credentials such as customer number, password and PIN, one-time SMS and 2FA codes, full payment card data including PAN, expiry, CVV and ATM PIN, and, particularly in the lending-brand kits, a much wider personal-data haul covering national ID number, date of birth, address, employer and income details, plus scanned copies of ID documents and payslips.

That breadth matters for how you scope the incident, because a card-data theft can be resolved with reissuance while a completed identity package supports account opening, loan fraud and downstream social engineering for years. Financial institutions and online payment providers remain among the most consistently targeted sectors in quarterly phishing telemetry published by the Anti-Phishing Working Group, and the kits described here sit at the more capable end of that activity rather than the commodity end.

And it is not only web pages. Most of what is covered above is a browser-rendered clone, deliberately built mobile-friendly to mimic a bank’s app rather than its desktop site, but a smaller number go further and impersonate the mobile app itself.

How convincing is convincing enough?

What makes a kit convincing is fidelity to the real banking environment, not just visually but in how it is structured and what it asks for, and those two dimensions fail independently of each other.

On structure, product type predicts the shape of the kit more than anything else does. Consumer-credit and lending brands converge on the same pattern, meaning a multi-step loan-application flow that collects employment status, income, and uploaded ID or proof-of-address documents, whereas straight retail-banking login brands converge on a simpler two-factor login clone instead.

Lending-brand pattern: a staged application form collecting identity and address data ahead of an eKYC step. Automatic translation from Vietnamese into English by Google Translate.

On the data itself, the tell is whether the kit bothered to localise the fields to the real banking and identity system being cloned, meaning correct local IBAN formats and SWIFT codes, or the correct national-ID digit format. A generic template gets the branding right and the data model wrong, while a properly localised one gets both, and that distinction is usually the fastest way to judge how much operator effort sits behind a given repository.

The most ambitious operators skip single-bank cloning altogether and impersonate a shared instant-payment rail instead, which lets them harvest from many banks’ customers at once through a single “select your bank” dropdown. This approach showed up independently across unrelated kits, including one impersonating Wero, the pan-European instant-payment scheme, where the harvesting form asks for name, IBAN, bank and full card data in one past.

Payment-rail impersonation: one form, one dropdown, and a harvesting surface that spans every participating bank at once.

What organizations should do

  • Monitor code-sharing platforms as a brand-protection surface, not just as an internal source-code-leak risk. The same crawl that looks for leaked internal repositories will not surface an external repository built to impersonate you, because the matching logic and the ownership assumptions are different.
  • Watch for naming and structural patterns, not just exact brand matches. Repository names that combine a brand with words such as “secure” or “connection”, or with the name of a regional subsidiary, are common tells, and the fictitious-rebrand cases show that exact-match keyword monitoring will miss a functioning clone entirely.
  • Treat hardcoded secrets found in a phishing kit as IOCs, not just as cleanup items. Bot tokens, Cloudflare Worker URLs and webhook endpoints can be correlated against other repositories and campaigns in order to surface the same operator’s infrastructure elsewhere, which is usually more valuable than the single repository you started from.
  • Report through official abuse channels promptly, and treat one takedown as a first move rather than a resolution. Phishing content and impersonation both fall under the GitHub Acceptable Use Policies, so reporting is straightforward, but you should then check whether the same file structure resurfaces under a new account, because it usually does.
  • Remember that deleting files is not enough. GitHub retains full commit history, so a repository cleaned up by its owner may still expose the original phishing code in earlier commits unless the entire repository is removed, and that history is also where you will often find the operator’s earliest and least-sanitised version of the kit.

These kits succeed by borrowing trust that was never meant for them, and taking that trust back starts with treating code-sharing platforms as seriously as any other place your brand can be impersonated. For the wider control set that sits around this problem, see our guide to financial services cybersecurity threats and controls.

Frequently asked questions

Cost and reputation. GitHub Pages provides free static hosting with a valid certificate on a high-reputation parent domain, so the operator avoids registration costs, avoids the domain-age and WHOIS signals that lookalike-domain detection relies on, and gets a URL that most corporate proxies and consumer security products will not block by default. The trade-off for the attacker is that the entire kit is publicly readable, which is exactly what makes these campaigns unusually analysable.


No. Git retains full commit history, so removing files in a later commit leaves the original code recoverable from earlier ones, and the GitHub Pages build may also remain cached. The repository has to be removed in full, and you should verify afterwards that the site no longer resolves rather than assuming the abuse report closed the loop.

Anything the operator had to hardcode in order for the kit to function: Telegram bot tokens and chat IDs, Cloudflare Worker or webhook URLs, mule account IBANs, disposable-email blocklists, and the directory and filename structure of the kit itself. Structure is often the strongest signal, because operators rebrand and re-host far more readily than they refactor.



They do not break the OTP, they relay it. The kit prompts for the one-time code as a final verification step and pushes it to the operator within seconds, which allows the operator to consume the code on the genuine site inside its validity window. This is why possession-only SMS OTP offers limited protection here, and why phishing-resistant factors bound to the origin behave very differently against this class of kit.

Look at the combination rather than any single indicator: account age and contribution history, whether the repository was created and completed within the same day, whether the file structure corresponds to any real banking product, and above all whether there is a live exfiltration path. A test project renders a form; a kit ships a destination for what that form collects.

Only partially. Exact-match keyword monitoring misses the rebranded clones, where the operator has find-and-replaced the brand name across every visible string while leaving the CSS, layout and assets untouched, and it also misses payment-rail impersonation that never names an individual bank in the first place. Detection has to account for visual and structural similarity as well as text.

How CybelAngel can help

CybelAngel monitors code-sharing platforms, domains, mobile app stores and the dark web as a single external brand surface, and our analyst team validates each detection before it reaches you, so what you receive is a confirmed impersonation with the supporting artifacts attached rather than a keyword alert to triage yourself. Where a takedown is warranted, our remediation team handles it and then keeps watching for the same operator resurfacing under a new account.

Dan-Madalin Pavel is a cybersecurity analyst working in the Consulting & Investigation Team.

Über den Autor