Log0x9000 – Poor Mans NFC Smartcard Logger

Vor längerer Zeit habe ich ein bisschen mit JavaCards rumgespielt: Applets kodiert, auf kontaktlose Smartcard geladen und an mein NFC Smartphone gehalten. Eine wirklich sinnvolle Idee für ein Applet kam mir irgendwie nicht bis zu dem Zeitpunkt als ich wissen wollte welche Daten (APDUs) eine bestimmte Android NFC App eigentlich so an (m)eine kontaktlose Smartcard sendet und welche Daten (Response-APDUs) auslesen werden. Da kam mir die Idee zu einer Dummy Smartcard, die jede Anfrage (Command-APDU) mitloggt, mit einer OK-Quitierung (Response-APDU: 0x9000) versieht und somit relativ preiswert das Erforschen der Kommunikation zwischen NFC App und Smartcard zulässt. Ausserdem kann man damit nebenbei schlecht kodierte NFC Apps zum Absturz bringen🙂  Wird nämlich eine Response-APDU 0x9000 mit zusätzlichen Daten erwartet und bleibt das Datenfeld leer so kann es zB zu einer ArrayIndexOutOfBoundsException kommen.

Erforderlich dafür ist allerdings eine JavaCard, die das Setzen des Default Selected Privilege zulässt, da dann alle APDUs (auch das Selektieren eines nichtvorhandenen Applets) direkt an das Logging-Applet geleitet werden. Die Blank 64k Programmable JAVA SIM Card zB kann man dafür leider nicht verwenden, da die Karte das Laden/Installieren mit Privilegien per Global Platform nicht unterstützt.

Folgende Kommandos sind in der ersten lauffähigen Version implementiert:

00100000 get version (zeigt die Applet Version an)
00400200076C6F6739303030 logging = off (t0/t1/tcl off) (schaltet das Logging aus, Karte kann nun konfiguriert werden)
004002xx logging = on (bitwise) e.g:
00400201 logging = on @ t0 contact interface
00400202 logging = on @ t1 contact interface
00400204 logging = on @ tcl contactless interface
00400207 logging = on @ all contact and contactless interfaces
00400210 get logging setting (liest Logging Bits aus)
00400300 clear log (clear all log entries)
00400400 clear cr_apdus (
0041p1p2 set defaultSW p1p2=9000, 6D00, 6a80 (Default SW setzen)
00420000 get defaultSW (Default SW auslesen)
00500100 activate C/R-APDU: lc {data set}  {data-set}={len-apdu apdu-byte1...apdu-byteN len-response-apdu rapdu0... rapduN}  
00510000 get cr_index (number of C/R-APDUs) (Anzahl der konfigurierten C/R-APDUs ausgeben)
006000nn readLog n (Logeintrag n auslesen)
00610000 get log index (Anzahl der Logeinträge auslesen)

Somit kann das Logging an- und ausgeschaltet werden, Logeinträge gelöscht / konfiguriert werden und vorhandene Logeinträge aufgelistet werden.

Testkandiat

Als Proband musste die Electronic Pickpocket RFID von Identity Stronghold herhalten. Im Screenshot sieht man das angeblich eine Karte erkannt wurde.

identify_stronghold

Die geloggte APDU zeigen die Anfrage der App:

#selektieren des American Express AIDs
00 a4 04 00 05 a0 00 00 00 25

Scheinbar fragt die App nur nach einer American Express Karte.

Hall of Shame

Schlecht kodierte (ohne Überprüfung der Response APDU und ohne try-catch-Block) NFC Apps scheinen dann so auszusehen:
ec_kreditkarten_infos  speek  s-kontaktlos

Interessant ist auch der Unterschied zwischen einem Android-Gerät mit NXP NFC Controller und einem Android-Gerät mit STMicroelectronics-Oberthur-Broadcom-Gespann. Mein Nexus S (mit NXP-NFC-Controller) sendet keine weiteren APDUs wenn das Phone auf die Karte gelegt wird, während das Nexus 10 (Broadcom-NFC-Controller) scheinbar alle 0.5 Sekunden versucht eine Leseanfrage an die Karte zu senden – denn nach 10 Sekunden wurden folgende APDUs geloggt:

> l9ls
0: 00B000009000
1: 00B000009000
2: 00B000009000
3: 00B000009000
4: 00B000009000
5: 00B000009000
6: 00B000009000
7: 00B000009000
8: 00B000009000
9: 00B000009000
10: 00B000009000
11: 00B000009000
12: 00B000009000
13: 00B000009000
14: 00B000009000
15: 00B000009000
16: 00B000009000
17: 00B000009000
18: 00B000009000
19: 00B000009000

Das 00B00000 entspricht einem READ-BINARY-Kommando, das wahrscheinlich genutzt wird um zu überprüfen, ob sich die Karte noch im Feld befindet.

Antworten

Jede Anfrage stumpf mit einem 0x9000 zu beantworten macht im 2.Schritt natürlich wenig Sinn, da es so zu keiner korrekten Kommunikation zwischem dem Smartphone und der Karte kommen wird. Deshalb sollte das Applet besser mit vorkonfigurierten Response-APDU antworten. Hat man die passende NFC-Smartcard zur App parat kann man so im Wechsel eine C-APDU loggen, die C-APDU an die richtige Karte senden, das Applet mit der R-APDU konfigurieren und so Schritt für Schritt quasi die Karte emulieren. Das Unterfangen ist zwar ziemlich mühsam aber für einen Logger unter 20 Euro akzeptabel.

Bei meinen Experimenten hat es sich allerdings herausgestellt, dass es Sinn macht eine Statemachine in das Applet zu implementieren, da je nach Status der Karte Anfragen unterschiedlich beantwortet werden müssen.

Btw: Das Applet kann natürlich auch zum Loggen einer kontaktbehafteten Karte, wie zB der Gesundheitskarte genutzt werden, da es der Karte nahezu egal ist über welches Interface die APDUs gesendet werden. Lesezugriffe auf Mifare Classic bzw ISO14443-3-Level kann mit der JavaCard leider nicht geloggt werden, da die Mifare Kommunikation eine Protokollebene niedriger stattfindet und nicht über die JavaCard API läuft.

2 thoughts on “Log0x9000 – Poor Mans NFC Smartcard Logger”

  1. Hallo Regnerischer Nachmittag, vielen Dank für die Nachricht bei Twitter bzgl. ISO 14443 vs. ISO 18092. Bei XING wurde der Gastartikel von Michael Hegenbarth ausführlich in den Kommentaren zur Link-Empfehlung diskutiert. Vielleicht besteht ja die Möglichkeit, den dortigen Verlauf zu verfolgen. Gerne schicken wir auch eine Kopie als PN.

Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s