0%
毅种循环

返回

Email Phishing Eng. · 2: Untraceable InfraBlur image

First published on the WeChat official account: Yofune Security Research. Follow for more.

Stealth and Adversarial Defense—Building Untraceable Infrastructure#

This is Part 2 of the Email Phishing Engineering series. Part 1 broke down the architectural debt and detection surface of traditional phishing frameworks (GoPhish). This article goes deep into the infrastructure layer—from domain acquisition and network topology through TLS fingerprints to probes—layer by layer on how to build infrastructure that withstands threat-intel attribution and sandbox analysis.


0x01 Infrastructure Survival Windows#

Under OPSEC rules in red/blue engagement, infrastructure lifetime decides outcomes. A bare public-IP VPS, a domain registered 12 hours ago, HTTPS with a self-signed cert—picture a stock Cobalt Strike with unaltered fingerprints: that stack’s survival window is often under 10 minutes. Modern enterprise defense-in-depth draws on multi-dimensional intel:

  • Secure Email Gateways (SEG): Domain-reputation modules in major Chinese mail security gateways (QiAnXin Mail Security Gateway, Sangfor Mail Security Gateway, Coremail) score on registration age, sending history, SPF/DKIM status, and more. Cloud services such as NetEase Enterprise Mail and Tencent Enterprise Mail embed anti-spam engines based on sending-behavior profiles and default higher risk weight for domains under 30 days old. International products such as Proofpoint TRAP (real-time correlation of domain reputation and URL classification) and Spamhaus DBL are also deployed to some degree in China, mainly for foreign-invested and multinational firms.

  • Network edge: Next-gen firewalls (Huawei HiSec, Sangfor AF, QiAnXin Smart Firewall) and web content / internet behavior management appliances (Sangfor AC, NetentSec) with TLS decryption can extract client traits. Many Chinese enterprises already get SSL audit with their internet behavior management purchases; despite significant performance cost, an egress with SSL audit can produce JA3/JA4 fingerprints that identify non-browser automation tools.

  • Endpoint and sandbox: Domestic EDR includes QiAnXin Tianqing, Sangfor EDR, Huorong Enterprise, and others. For mail sandboxes—QiAnXin SkyEye Sandbox, ThreatBook OneSandbox (a domestic sandbox-as-a-service representative), DBAPPSecurity threat-intel sandboxes, and similar—vendors crawl URLs in mail with headless browsers, extract DOM structure, and return JavaScript probe content. Some vendor sandboxes already support full JavaScript execution on Chromium kernels (educated guess; not fully confirmed).

  • Threat intelligence centers: Domestic SOC CT-log monitoring paths differ from overseas ones. Subscribing directly to major foreign security-intel APIs for real-time push is often unstable under domestic network conditions; the mainstream approach is domain-monitoring services from QiAnXin Threat Intelligence Center and ThreatBook, with alert rules for newly registered domains similar to the organization’s own. Alibaba Cloud and Tencent Cloud DNSPod also offer domain-registration monitoring APIs for enterprise customers.

Infrastructure is the first-order factor. That means a battle-oriented phishing exercise platform must treat anti-attribution and high stealth as first-class priorities in architecture.


0x02 Domain Reputation Engineering: From Acquisition to Care#

Step one for infrastructure is not buying a server—it is buying a domain. Domain reputation decides whether mail clears the SEG’s first gate.

2.1 Drop Fresh Domains; Embrace Aged Domains#

A common red-team mistake: register something like corp-login-update.com for a single op. The fatal issue is domain age. Some security vendors treat registration duration as a core factor. Sending linked mail immediately after registration often lands in junk or direct quarantine (550 5.7.1). This has been observed on 189, 136, and 163 mail in China.

Operational acquisition strategies:

Aged domain acquisition. Look for domains with multi-year history, categorized by registrars as “tech” or “business,” that entered cooling after non-renewal. These come with initial reputation. Per The Record (2024), a 9-year-old domain digitalscrapbookingfreebies.com was re-registered after cooling by a phishing group and successfully bypassed a state health agency’s mail gateway. Age data comes from Whois history; reputation scores inherit DNS resolution history and continuity of SSL certificate issuance.

Subdomain takeover. In February 2024, Guardio Labs researchers Nati Tal and Oleg Zaytsev exposed a large-scale subdomain takeover campaign codenamed “ResurrecAds” (see Guard.io research). Attackers scanned expired CNAME records of large enterprises (MSN, VMware, McAfee, Cornell University, UNICEF, etc.)—e.g. marthastewart.msn.com CNAME pointing to the 22-year-abandoned domain msnmarthastesweeps.com. Re-registering that domain enabled mail from @marthastewart.msn.com, inheriting MSN top-tier reputation. At peak the campaign sent ~5 million malicious messages per day from ~22,000 unique IPs (including residential ISP proxies), rotating each hijacked domain after only 1–2 days. Guardio Labs provides a free detection tool (checker.guard.io).

Homoglyphs and Punycode. Visual confusion via Unicode—Latin a (U+0061) vs Cyrillic а (U+0430), Latin o (U+006F) vs Greek ο (U+03BF). Modern browsers (Chrome 58+, Firefox 58+, Edge) force Punycode display for cross-script mixes: when a domain mixes characters from different Unicode scripts, the address bar shows the xn-- form. But 2025 research from Tencent Cloud Security notes that within a single script (e.g. full Japanese Hiragana), homoglyph confusion can still bypass browser detection—e.g. substituting (U+3093) for / to build phishing URLs like https://account.booking[.]comんdetail that visually resemble path structure. (Still active in Web3 attack incidents.)

  • Blue team countermeasures: Use confusables-inspector (open-source on GitHub, updated June 2025) to auto-detect confusable characters; on the SEG side, Punycode-decode all URLs in message bodies for inspection.

2.2 Correct Configuration of Mail Authentication Protocols#

SPF, DKIM, and DMARC are mandatory, not optional. If you want phishing mail in the victim’s inbox, this is one of the conditions.

  • SPF include: chain hijacking: The SubdoMailing campaign showed SPF’s include: mechanism as an attack surface—when an enterprise SPF record references an abandoned external domain, registering that domain lets an attacker inject malicious authorization.

  • DKIM key length: Prefer rsa-sha256 with keys of at least 2048 bits. 1024-bit keys face brute-force risk (see cryptographic analysis lessons from CVE-2023-50387 on DNSSEC).

  • DMARC policy: On a self-hosted mail gateway this is indispensable. Set DMARC to v=DMARC1; p=reject;—this seemingly harsh policy actually increases the domain’s “trustworthiness,” because it signals that the owner takes mail security seriously.


0x03 Network Topology: Don’t Let the Blue Team Touch Your Real IP#

For a long time, writing the phishing platform’s public IP into the domain A record meant: the blue team can ban the IP, scan open ports, attribute via ASN to the VPS provider, and file Abuse with the IDC to get the host killed. That still works on domestic clouds—see Huawei Cloud / Tencent Cloud / Alibaba Cloud policies: internal scanning and external abuse both shut machines down.

3.1 Cloudflare Tunnel: From Passive Inbound to Active Outbound#

When building the TaiGong project we also drew on overseas technical write-ups. Broadly: use tunneling to hide the entire infrastructure. Nginx alone is limited, so we abandoned traditional reverse proxies and adopted Cloudflare Tunnel end-to-end.

How it works: Run the cloudflared daemon on the server; it actively opens outbound HTTP/2 or QUIC long-lived connections to Cloudflare edge nodes (default to port 7844). The server needs no open inbound ports—security groups can deny all inbound. When a request hits a Cloudflare edge, it is multiplexed over the established tunnel to a local loopback address (127.0.0.1:80).

Core benefits:

DimensionTraditional reverse proxyCloudflare Tunnel
Inbound portsMust open 80/443No inbound ports required
IP stealthCDN helps, but origin IPs may still surface in FOFA/ZoomEye/Shodan historyPhysical-level hide; mappers only see CF node IPs
ICP filingUnfiled domains on domestic cloud hosts can be RST at the ISP layerOutbound traffic is not subject to Host-header sniffing the same way; can pierce
DDoS protectionDepends on fronting CDNCF edge is natively DDoS-resistant

CDN edge auth: Tunnel alone is not enough—once the blue team has the domain they can still script requests and flood the database with junk. Think of countermeasures similar to Cobalt Strike beacon camouflage. TaiGong’s solution combines Cloudflare Transform Rules: the edge injects a custom Header on all legitimate requests; the backend TaiGong engine only serves the phishing page after validating that Header. Tokenless requests (mappers, sandbox crawlers, direct scanners) get a 302 to a benign target (e.g. https://www.baidu.com), reducing spatial-engine scanning and attribution at the root.

  • Blue team countermeasures: Detect abnormal high-frequency outbound connections to [IP range]:7844 (Cloudflare Tunnel port); identify Tunnel-characteristic traffic on network appliances; watch for uncommon headers in request packets.

3.2 Edge Environment-Aware Filtering#

Implement the first filter layer in Cloudflare Workers or Edge Functions; selectively origin-fetch based on request traits:

  1. ASN denylist:

    Filter cloud-provider and security-vendor ASNs—these ranges are almost never real victims.

    • Alibaba Cloud (AS45102, AS37963): China’s largest public cloud, covering East China 1/2, North China 1/2/3, South China 1, etc. Nearly all domestic commercial SEG sandboxes and third-party mail-security crawler nodes sit on Alibaba Cloud.
    • Tencent Cloud (AS45090, AS132203): Tencent Cloud public egress; sandbox traffic for Tencent Enterprise Mail and WeChat Work mail security modules exits here.

    • Huawei Cloud (AS55967): Huawei Cloud public egress; mail security for some government/enterprise customers.

  2. Security-vendor ASNs: QiAnXin, Sangfor, Knownsec scan-node ranges—these vendors’ mail sandboxes and threat-intel crawlers usually have fixed egress ranges, but I did not find specific CIDRs.

  3. References above: https://bgp.tools/

    1. Bot Management Score: Use Cloudflare’s Bot Management engine; return decoy content for scores below 30.
    1. Geo-IP restriction: Limit source countries to the exercise audience’s geography; if you know the target’s IP ranges, restrict down to city and drop everything outside. (Similar to the geo-fencing feature implemented later; with a CDN you can do this natively.)

0x04 TLS Fingerprint Adversarial Techniques: JA3/JA4 and uTLS Evasion#

This is the lowest-level technical detail in the offense/defense game—the first layer above TCP/IP.

4.1 ClientHello Fingerprint Principles#

When a client starts HTTPS it sends a ClientHello containing TLS version, cipher suites, extensions, elliptic curves, compression methods, and more. Different software stacks produce fixed structural differences:

  • JA3 (Salesforce, 2017): Concatenate selected fields and MD5-hash them into a 32-character fingerprint. For example, Go’s default JA3 is 771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-21,29-23-24,0.

  • JA4 (FoxIO, 2023): A more structured, hierarchical scheme in the form t13i<cs>_<ext>_<groups>, without MD5; supports fingerprinting both sides of the handshake (JA4 Server / JA4 Client / JA4S / JA4XSS, etc.).

If you use Go’s standard net/http or gomail to make requests, traffic carries Go-unique JA3/JA4 fingerprints. (Open-source: Zeek’s ja4 plugin, Suricata JA3 support; domestic commercial: QiAnXin SkyEye, NSFOCUS NTA, Colasoft network analysis TLS fingerprint modules, and some full-packet appliances.) At the edge, seeing an unfamiliar external IP repeatedly handshaking with a specific fingerprint and behavior resembling credential-collection POSTs is enough to block immediately.

4.2 uTLS Browser Impersonation#

TaiGong draws on refraction-networking/utls (GitHub, Go 1.21+). uTLS is a fork of Go’s crypto/tls that allows programmatic, precise control of ClientHello:

  • Preset browser templates: HelloChrome_Auto, HelloFirefox_Auto, HelloSafari_16_0, HelloIOS_14, etc.—exact imitation of cipher suite order, extension lists, and elliptic-curve combinations for the corresponding browser.

  • Randomized fingerprints: HelloRandomized randomly selects combinations from all cipher suites and extensions uTLS supports—useful against denylist-style detection.

  • Custom fingerprints: HelloCustom lets you fully hand-build ClientHello—capture a real browser ClientHello (tcpdump or Wireshark), reverse it with Fingerprinter.FingerprintClientHello() into a uTLS config, then ApplyPreset() for an exact copy.

Important limits: uTLS currently only impersonates browsers at the ClientHello stage. tls-client implements similar imitation through server Hello verification, but is less mature than uTLS. Also, Go’s standard library lacks some TLS 1.3 extensions (e.g. Compressed Certificate), so certain Chrome templates fail handshakes against specific servers. See GitHub Issue #321.

4.3 GREASE Against GREASE#

RFC 8701 defines TLS GREASE (Generate Random Extensions And Sustain Extensibility) to ensure backward compatibility for protocol extensions. Chrome pioneered random insertion of GREASE cipher suites (e.g. 0x0A0A) and extension types in ClientHello so servers would not tear down on unknown values.

Interestingly, GREASE makes JA3 detection harder: Chrome may send different GREASE values per connection, so the JA3 fingerprint changes.

  • Advanced red-team technique: Actively add GREASE values in a custom uTLS ClientHello so the fingerprint is closer to real Chrome. But consistency matters—AI models (e.g. PerimeterX, DataDome ML classifiers) do not look only at a single handshake fingerprint; they analyze TLS behavioral consistency across the session (e.g. whether the HTTP/2 SETTINGS frame sequence after handshake matches a browser).

0x05 Payload-Layer Adversarial Techniques: Multi-Stage Probe Pages#

The last line of infrastructure stealth is the landing page itself. At this layer TaiGong uses a dual architecture of client-side JS probes + server-side multi-factor joint judgment. Part of this section is lifted from research notes in TaiGong’s Chapter 6: The Advanced Identification Contest—not particularly mysterious or uniquely brilliant, but a useful concrete example to publish.

5.1 Client Dual Probes: magic.js + finger.js#

TaiGong injects two independent client scripts into every landing-page template—magic.js and fing.js (finger). Their roles are roughly:

  1. Detect navigator.webdriver
  • Detect HeadlessChrome/PhantomJS-style keywords in the UA
  • Detect whether Chrome DevTools Protocol is connected
  • Detect empty navigator.plugins
  • Detect missing navigator.languages
  • Detect automation-framework properties such as window._phantom, window._selenium
  • Detect zero window.outerWidth / outerHeight
  • Detect contradictions between Notification.permission and Permissions API results
  • Detect WebGL renderers such as SwiftShader/llvmpipe (software renderers)
  • Detect performance.timing DOM parse times under 5ms

Decision logic: When signals >= 2 (default threshold), document.write replaces the entire page with standard Nginx 404 HTML. After 100ms, setTimeout runs again to cover async-loaded checks (e.g. Permissions API). On sandbox detection it also fires a pixel report to /report?id=xxx&reason=sandboxer for stats.

Red team view: The engineering tradeoff is explicit—prefer false negatives over false positives, because for phishing exercises delivery rate matters more. Threshold 2 means a single anomalous signal (e.g. only UA matching HeadlessChrome) does not block; only two or more independent dimensions hit at once. In Taigong usage the backend controls this; adjust sensitivity via the threshold variable—recommended range 1–3.

Blue team view: magic.js detection logic is static and fully attributable. It cannot catch:

  • Sandboxes using real Chrome instances (non-headless)—WebDriver flag scrubbed, WebGL normal, plugins present
  • Crawlers egressing from real corporate network IPs—no static checks hit
  • puppeteer-extra-plugin-stealth + real browser instances—items 1, 3, 4, and 5 all bypassed

That is exactly why server-side joint judgment is indispensable.

fing.js (client environment collection) — the second script injected alongside magic.js, running after magic.js judges non-sandbox. Collection includes:

  • Canvas fingerprint: hash of canvas.toDataURL() for fixed text + fixed colors + fixed rectangles—different browser/OS/GPU combos produce different renders
  • Browser attributes: navigator.userAgent, navigator.language, navigator.platform
  • Screen attributes: screen.width×screen.height
  • Environment attributes: timezone offset (new Date().getTimezoneOffset()), touch support ('ontouchstart' in window), cookies enabled (navigator.cookieEnabled), DNT (navigator.doNotTrack)

Collected data is POSTed to a backend endpoint; the server associates it with the click event in the database for later victim behavior profiling and risk scoring.

5.2 Server Multi-Factor Joint Judgment: CheckEvasion#

In server-side functions Taigong runs the following checks, priority high to low:

  1. JA4 denylist: Exact client TLS fingerprint match against known scanner/sandbox libraries (e.g. Evilginx’s t13d191000_9dc949149365_e7c285222651)
  2. IP denylist: Exact IP, CIDR, and wildcard-prefix formats
  3. Cloud-provider IP blocking: Built-in 200+ CIDR rules covering AWS/Azure/GCP/Alibaba Cloud/Tencent Cloud
  4. Crawler UA blocking: 35 known bot UA keywords—from Googlebot/Bingbot through python-requests/Go-http-client to VirusTotal/Censys; common ones are all covered
  5. Three-tier geo-fence: Country (CN), province (CN-Guangdong), city (CN-Guangdong-Shenzhen); multi-region comma-separated mixes supported

On suspicion, per config: return 302 to a legitimate site, return a fake Nginx 404, or serve as normal.

A concrete scenario: exercise against a company’s finance department; mail spoofed as “annual audit notice”; landing page is a forged Office 365 login form.

Layer 1 — Server (request blocked before the landing page)

Some mail gateways visit the link in the background before the user ever receives the message. When the request hits the taigong server:

  • Cloud-provider IP block: egress IP falls in a Tencent CDN CIDR → if cloud-provider IP interception is on, return 302 to Baidu home. The gateway sees “this link redirects to Baidu” and judges it safe.
  • Even if cloud detection is off, UA check: TencentCloud UA contains “TencentCloud/Tencent-Cloud,” hits crawler denylist → same block.

Layer 2 — magic.js (server did not block; landing HTML returned, but sandbox never sees real content)

Suppose a more advanced sandbox—real corporate network egress, normal browser UA, no JA4 denylist hit—successfully fetches the landing HTML. magic.js then runs:

  • navigator.webdriver === true → +1 (sandbox driven by Selenium/Playwright)
  • navigator.plugins.length === 0 → +1 (headless, no plugins)
  • load time < 5ms → +1 (machine opens DOM in milliseconds)

signals = 3 >= 2, block triggers. document.write replaces the entire browser DOM with:

404 Not Found#

Plus a pixel report: /report?id=Ab7Xk2Q&reason=sandboxer.

Sandbox perspective: It thinks it hit a page that is already offline (404)—no phishing traits captured. Sandbox verdict: safe.

Real user perspective: Receives mail, clicks link, browser opens the landing page normally. magic.js runs—navigator.webdriver is false, plugins load, render takes hundreds of ms—signals = 0, no block. Page shows the Office 365 login form. Password, submit, redirect. Fully seamless.

So the actual design intent is:

Not “prevent sandboxes from accessing,” but make sandboxes and real people see different things. Sandbox sees Nginx 404; human sees the phishing form. With both layers stacked, a sandbox must bypass IP/UA/JA4 filters server-side and hit fewer than 2 client detection signals. Does the anti-attribution design look reasonable? Limitations remain.

5.3 Real-World Effectiveness and Limits of This Approach#

Limitations:

  • No behavioral analysis: magic.js does not track mouse trajectories, scroll detection, or Fitts’s law analysis. Some commercial anti-detection white papers tout these, but in engineering behavioral analysis is high-latency, high false-positive, and resource-heavy—cost/benefit is worse than static checks for phishing scenarios.

  • No delayed rendering: Landing Page HTML is returned complete; magic.js replaces content after render. If a SEG can dump a DOM snapshot before magic.js runs, it still sees the phishing form. Sandbox evolution is moving exactly toward capturing initial-state DOM.

  • Not a true “superposition state”: Superposition was an earlier idea of mine; I have not found a good way to implement it. Current logic is “destroy the page after detecting a sandbox,” not “do not show content until identity is uncertain.” That engineering distinction is critical—true superposition with no malicious elements in the first response requires the server to deliver phishing content only after receiving a client probe callback, adding latency and complexity.

That is the full set of my views on infrastructure for phishing operational security. But in today’s offense/defense contests, even perfectly stealthy infrastructure, once it enters the content adversarial phase, is still crushed by AI classifiers (e.g. Microsoft Defender ML models, Exchange Safety AI) if you only ship static HTML and hard-coded copy. The next article goes deep into body-level adversarial techniques: polymorphic HTML and a semantic dilution engine—making every phishing message a unique fingerprint and probing the defenses of Bayesian and NLP classifiers.


References#


Series Navigation