# NGate Android NFC Relay Malware Variant - Trojanized HandyPay Banking App Campaign Targeting Brazil (2025-2026)

> ESET Research disclosed a new NGate Android malware variant that trojanizes the legitimate HandyPay NFC relay app to steal payment card data and PINs from Brazilian users. Distributed via a fake Rio de Premios lottery website and a fake Google Play page for a bogus Protecao Cartao (Card Protection) app, the malware forwards victims' NFC card data to an attacker-controlled device for contactless ATM cash-outs while exfiltrating captured PINs over HTTP. ESET assesses portions of the malicious code as AI-generated.

- **Published:** 2026-04-22T12:00:00Z
- **Last reviewed:** 2026-04-22T12:00:00Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-0407
- **Card image:** https://intel.threadlinqs.com/og/threat/threat-intel-ngate-handypay-nfc-relay-tl-2026-0407.webp?v=c653e836 (Threadlinqs threat intel: NGate Brazil ATM Cash-Out Relay: Detection & IOCs (TL-2026-0407) — High severity, 26 IOCs, 9 detection rules.)
- **ID:** TL-2026-0407
- **Severity:** HIGH
- **Category:** MALWARE
- **Status:** ACTIVE
- **Actor:** NGate Operator
- **Detections:** 9 (1 shown free below) · **IOCs:** 26 (3 shown free below)

## Description

OVERVIEW

ESET Research disclosed on 2026-04-21 a fresh variant of the NGate Android malware family that abandons the previously-used open-source NFCGate tooling in favour of trojanizing a legitimate Android app called HandyPay. HandyPay has been on Google Play since 2021 and provides a legitimate NFC relay capability intended for sharing payment cards between paired family members or devices. The threat actor weaponised HandyPay's native functionality by injecting malicious code into the APK, distributing the trojanized package outside Google Play under two lures, and routing all captured NFC traffic to an attacker-controlled receiver device. The campaign has been active since 2025-11 and targets Android users in Brazil; ESET identified logs from four compromised Brazilian devices on the attacker C&C server containing captured PIN codes, IP addresses and timestamps.

DISTRIBUTION AND INITIAL ACCESS

Two trojanized samples were observed in the wild, both hosted on the same infrastructure (protecaocartao.online, fronted by Cloudflare at 104.21.91.170, with C&C at 108.165.230.223 hosted by BattleHost). The first lure is a phishing website that impersonates Rio de Premios, a scratch-card lottery run by Loterj (Rio de Janeiro state lottery operator). The rigged scratch card always reveals three matching symbols awarding the victim R$20,000. Claiming the prize opens WhatsApp with a prefilled message to a number whose profile impersonates Caixa Economica Federal, the Brazilian government-owned bank that manages most state lotteries. The victim is then directed to install a patched HandyPay APK renamed Rio_de_Premios_Pagamento.apk (SHA-1 94AF94CA818697E1D99123F69965B11EAD9F010C). The second lure is a fake Google Play web page for an app called Protecao Cartao (Portuguese: Card Protection), which delivers PROTECAO_CARTAO.apk (SHA-1 48A0DE6A43FC6E49318AD6873EA63FE325200DBC or A4F793539480677241EF312150E9C02E324C0AA2). Android's install prompt blocks the sideload until the victim enables installation from unknown sources.

EXECUTION AND FUNCTIONALITY

Once installed, the app requests to be set as the device's default payment application - a legitimate HandyPay prompt that is retained unchanged. Crucially, no additional Android permissions are requested, which keeps the malware's detection surface extremely small. The operator's paired device (linked to an attacker email hardcoded in the APK; two distinct operator email addresses were observed across samples) performs the receiving side of the relay, which requires default-payment-app status to emulate tap-to-pay. The victim is induced to enter their payment-card PIN into a patched text field inside the app and then to hold their physical card against the back of the NFC-enabled phone. Captured NFC traffic is forwarded via HandyPay's existing relay channel to the operator device, which the attackers use to conduct contactless ATM withdrawals and unauthorised point-of-sale payments. Separately, the captured PIN is exfiltrated out-of-band over plain HTTP to the 108.165.230.223 C&C server, which doubles as the distribution host.

AI-ASSISTED CODE

ESET attributes the malicious code injection to likely GenAI tooling based on telltale emoji embedded in log strings and stylistic patterns typical of LLM-generated text. This is consistent with a broader 2025-2026 trend documented in ESET's H2 2025 Threat Report in which low-skill threat actors increasingly outsource malware authoring to LLMs, lowering the barrier to entry for NFC-relay fraud.

RELATIONSHIP TO PRIOR NGATE AND PHANTOMCARD CAMPAIGNS

NGate first became public in 2024 when ESET documented attacks against Czech banking customers relaying NFC traffic via the open-source NFCGate tool. The malware family diversified in 2025 with the PhantomCard variant that targeted Brazil using the NFU Pay MaaS to handle the relay, and similarly-named apps (including Card Protection-style branding) were observed as early as October 2025. The subject campaign diverges from both: the operator chose to patch the cheap (EUR 9.99/month donation-ware) HandyPay app instead of paying hundreds of USD per month for NFU Pay (~US$400/mo) or TX-NFC (~US$500/mo) MaaS subscriptions.

VICTIMOLOGY AND IMPACT

Confirmed victims are Android users in Brazil. Four compromised devices with captured PIN data were observed on the C&C server at time of analysis. Primary impact is direct financial loss via unauthorised ATM withdrawals and contactless payments. Secondary impact includes reputational damage to HandyPay, Caixa Economica Federal, Loterj, and Google Play. HandyPay has been notified by ESET and confirmed an internal investigation. Google has been notified through the App Defense Alliance and Google Play Protect detects known samples.

ATTRIBUTION

ESET has not attributed the campaign to a named actor. The shared hosting infrastructure and shared APK base imply a single operator or tightly-coordinated crew. Motivation is clearly financial (ATM cash-out) rather than espionage. Confidence in a single-actor operation is high; national attribution is unknown.

## MITRE ATT&CK

- T1660 Phishing
- T1476 Deliver Malicious App via Other Means
- T1658 Exploitation for Client Execution
- T1624 Event Triggered Execution
- T1655 Masquerading
- T1628 Hide Artifacts
- T1406 Obfuscated Files or Information
- T1417 Input Capture
- T1426 System Information Discovery
- T1409 Stored Application Data
- T1437 Application Layer Protocol
- T1481 Web Service
- T1646 Exfiltration Over C2 Channel
- T1643 Generate Traffic from Victim

## Free detection (Splunk SPL, Microsoft KQL, Sigma)

**NGate HandyPay — Trojanized APK Distribution Download (Exploitation)** (`TL-2026-0407-SPL-001`)

Detects retrieval of the trojanized HandyPay APK filenames (PROTECAO_CARTAO.apk, Rio_de_Premios_Pagamento.apk) or requests to the NGate distribution infrastructure (protecaocartao.online / 104.21.91.170 / 108.165.230.223) via web-proxy or DNS telemetry. Fires on initial-access stage of TL-2026-0407.

- **Languages:** Splunk SPL, Microsoft KQL, Sigma
- **ATT&CK:** T1660, T1476, T1655.001
- **Data sources:** proxy, dns, edr, firewall
- **Severity:** critical
- **Confidence:** high

### Splunk SPL

```spl
index=proxy sourcetype IN ("bluecoat:proxysg:access:syslog", "zscalernss-web", "pan:threat", "stream:http")
  earliest=-24h
  (dest="protecaocartao.online" OR dest_ip IN ("104.21.91.170", "108.165.230.223") OR uri_path="*PROTECAO_CARTAO.apk" OR uri_path="*Rio_de_Premios_Pagamento.apk")
| eval reason=case(
    dest="protecaocartao.online", "ngate_c2_domain",
    dest_ip=="104.21.91.170", "ngate_distribution_ip",
    dest_ip=="108.165.230.223", "ngate_cc_ip",
    match(uri_path, "(PROTECAO_CARTAO|Rio_de_Premios_Pagamento)\.apk"), "trojanized_apk_filename",
    1==1, "other")
| stats count min(_time) as first_seen max(_time) as last_seen values(uri_path) as uri_paths values(http_user_agent) as user_agents values(reason) as reasons by src_ip user dest dest_ip
| eval first_seen=strftime(first_seen, "%Y-%m-%dT%H:%M:%S"), last_seen=strftime(last_seen, "%Y-%m-%dT%H:%M:%S")
| table first_seen last_seen src_ip user dest dest_ip uri_paths user_agents reasons count
```

### Microsoft KQL

```kql
let apkNames = dynamic(["PROTECAO_CARTAO.apk", "Rio_de_Premios_Pagamento.apk"]);
let c2Hosts  = dynamic(["protecaocartao.online"]);
let c2Ips    = dynamic(["104.21.91.170", "108.165.230.223"]);
(
    CommonSecurityLog
    | where TimeGenerated > ago(24h)
    | where DeviceVendor in ("Palo Alto Networks", "Zscaler", "Check Point", "Fortinet", "Cisco")
    | where DestinationHostName in (c2Hosts) or DestinationIP in (c2Ips) or RequestURL has_any (apkNames)
    | project TimeGenerated, SourceIP, DestinationIP, DestinationHostName, RequestURL, RequestClientApplication, DeviceAction, Reason="proxy_match"
)
| union (
    DeviceNetworkEvents
    | where Timestamp > ago(24h)
    | where RemoteIP in (c2Ips) or RemoteUrl has_any (c2Hosts) or RemoteUrl has_any (apkNames)
    | project TimeGenerated=Timestamp, SourceIP=LocalIP, DestinationIP=RemoteIP, DestinationHostName=RemoteUrl, RequestURL=RemoteUrl, RequestClientApplication=InitiatingProcessFileName, DeviceAction=ActionType, Reason="edr_match"
)
| summarize FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), Hits=count(), URLs=make_set(RequestURL, 20), UAs=make_set(RequestClientApplication, 10)
  by SourceIP, DestinationIP, DestinationHostName, Reason
```

### Sigma

```yaml
title: NGate HandyPay Trojanized APK Distribution Download
id: 7b3d5f10-0a11-4f2c-9b77-a8c1ng400101
status: experimental
description: |
  Detects web-proxy, EDR or DNS retrieval of the trojanized HandyPay APK filenames or
  traffic to the NGate distribution / C&C infrastructure observed in TL-2026-0407
  (ESET NGate variant, trojanized HandyPay, targeting Brazil, 2025-2026).
references:
  - https://www.welivesecurity.com/en/eset-research/new-ngate-variant-hides-in-a-trojanized-nfc-payment-app/
  - https://github.com/eset/malware-ioc/tree/master/ngate
author: Threadlinqs Team
date: 2026-04-22
tags:
  - attack.initial_access
  - attack.t1660
  - attack.t1476
  - attack.defense_evasion
  - attack.t1655.001
logsource:
  category: proxy
  product: zeek
detection:
  sel_host:
    dst_host|endswith: 'protecaocartao.online'
  sel_ip:
    dst_ip:
      - '104.21.91.170'
      - '108.165.230.223'
  sel_uri:
    cs-uri-stem|contains:
      - 'PROTECAO_CARTAO.apk'
      - 'Rio_de_Premios_Pagamento.apk'
  condition: sel_host or sel_ip or sel_uri
falsepositives:
  - Security researchers or malware analysts deliberately fetching samples
  - Threat-intel automation replaying IOCs against a sandbox
level: critical
```

**Known false positives:**

- Security researchers intentionally retrieving NGate samples for analysis
- Threat-intelligence automation replaying IOCs against a sandbox

**Tuning notes:** Whitelist approved malware-analysis source IPs and sandbox egress. Extend the APK-filename list if new NGate HandyPay samples surface. Reduce severity to high for 104.21.91.170 alone since it is a shared Cloudflare edge IP that may have unrelated tenants.

### 8 more detection rules (Splunk SPL, Microsoft KQL, Sigma), unlock with TL Creds

- NGate HandyPay — DNS / Network Resolution to [indicator] (Exploitation) (locked: unlock with TL Creds)
- NGate HandyPay — Known Trojanized APK Hash Observed on Endpoint (Post-Exploitation) (locked: unlock with TL Creds)
- NGate HandyPay — Android UA Cleartext HTTP POST to External Collector (C2/Lateral Movement) (locked: unlock with TL Creds)
- NGate HandyPay — WhatsApp Click-Through to [indicator] Lure (Exploitation) (locked: unlock with TL Creds)
- NGate HandyPay — Default Payment Application Set to Non-Wallet Package (Post-Exploitation) (locked: unlock with TL Creds)
- NGate HandyPay — Outbound Connection to BattleHost C&C [indicator] (C2/Lateral Movement) (locked: unlock with TL Creds)
- NGate HandyPay — Non-Play Sideload Install of HandyPay / Protecao Cartao (Post-Exploitation) (locked: unlock with TL Creds)
- NGate HandyPay — HTTP POST PIN Exfiltration to C&C (C2/Lateral Movement) (locked: unlock with TL Creds)

Sign up free to unlock the detection rules: https://threadlinqs.com/?modal=signup

## Sample indicators (3 of 26)

Defanged, TLP:CLEAR.

- IP address: `104.21.91[.]170`
- Domain: `protecaocartao[.]online`
- File hash: `48A0DE6A43FC6E49318AD6873EA63FE325200DBC`

Full set of 26 indicators unlocks with TL Creds: https://threadlinqs.com/tl-creds

## Sources

- [New NGate variant hides in a trojanized NFC payment app](https://www.welivesecurity.com/en/eset-research/new-ngate-variant-hides-in-a-trojanized-nfc-payment-app/)
- [ESET malware-ioc repository - NGate](https://github.com/eset/malware-ioc/tree/master/ngate)
- [NGate Android malware relays NFC traffic to steal cash (original 2024 disclosure)](https://www.welivesecurity.com/en/eset-research/ngate-android-malware-relays-nfc-traffic-to-steal-cash/)
- [ESET Threat Report H2 2025](https://www.welivesecurity.com/en/eset-research/eset-threat-report-h2-2025/)
- [MITRE ATT&CK Mobile - T1660 Phishing](https://attack.mitre.org/techniques/T1660/)
- [MITRE ATT&CK Mobile - T1417.002 Input Capture: GUI Input Capture](https://attack.mitre.org/techniques/T1417/002/)
- [MITRE ATT&CK Mobile - T1646 Exfiltration Over C2 Channel](https://attack.mitre.org/techniques/T1646/)
- [Google Play Protect - Android App Defense Alliance](https://developers.google.com/android/play-protect)

## Full data

The other 8 detection rules (Splunk SPL / Microsoft KQL / Sigma) unlock with TL Creds; a free account includes daily creds: https://threadlinqs.com/?modal=signup
Indicator values unlock with TL Creds, at a lower price on Red and Purple; AI agents can query rules and IOCs through the Threadlinqs MCP server (Purple): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-0407
