Comment nous avons perdu 230 euros chez CJ Affiliate (Conversant)

[accueil]  [menu]  [marions-nous !]  [chercher]


2008-05-27 00:00

BasicSPY : une carte à puce caméléon


Intercepter les communications entre une carte à puce et son lecteur attitré est un procédé des plus courants pour tenter de percer les mystères d'une application inconnue (lire Pirates Mag' 11). Quand il n'est pas possible (ou pas assez discret...) d'intercaler ainsi un espion hardware à l'endroit stratégique, il existe une solution élégante : implanter carrément le logger dans la carte !

Pas question, c'est évident, de bricoler physiquement à l'intérieur d'une carte à puce existante pour y ajouter cette fonctionnalité résolument indiscrète ! L'idée consiste plutôt à compléter logiciellement un « émulateur », autrement dit une carte à système d'exploitation ouvert que l'on programmera de proche en proche pour imiter (au moins partiellement) la carte d'origine.
La BasicCard se prête idéalement à cet exercice, qui a déjà fait ses preuves puisque c'est de cette façon, souvenons nous, que la carte Vitale a révélé une bonne partie ses secrets... bien mal gardés il est vrai (lire Pirates Mag' 12). Des résultats très prometteurs ayant également été obtenus avec des émulateurs de cartes SIM, il est bien tentant de généraliser le procédé !

Une réponse au Reset plausible
Première étape indispensable : programmer la carte pour qu'elle émette une réponse au reset (ATR) susceptible d'être reconnue par le terminal objet de notre curiosité. Il n'y a pas bien longtemps, la plupart des applications se contentaient de contrôler les seuls caractères « historiques » de l'ATR, laissant les lecteurs s'adapter par eux-mêmes (comme le prévoient les normes) aux octets « système » qui précisent les paramètres de communication à appliquer. A condition (et encore !) de ne pas essayer de tromper un lecteur T=0 avec une carte T=1, il était ainsi possible de prendre de sérieuses libertés lors de l'émulation de cartes existantes. Est-ce parce que nous avons maintes fois tiré la sonnette d'alarme ? La tendance commence à évoluer vers un contrôle plus strict de l'intégralité de l'ATR, ce qui obligera les petits malins que nous sommes à jouer de plus en plus au chat et à la souris...
Intéressons nous pour l'instant à une carte émise par certains casinos, à titre de passe d'accès et de carte de fidélité. Son ATR a le bon goût d'être à « convention directe » (octet initial 3Bh) et donc compatible avec la plupart des ZC 4.x et ZC 5.x placées en mode T=0 :

3B 6E 00 00 50 6C 61 79 65 72 73 50 6C 75 73 31 2E 31

Ne tentons pas le diable, et essayons de n'émuler que les caractères historiques soulignés ici (qu'il n'est pas inintéressant de décoder en ASCII !), en conservant des octets système (3B FE 11 00 FF 40 80) que nous savons être sans danger pour la BasicCard :

Declare Binary ATR = &H3B,&HFE,&H11,&H00,&HFF,&H40,&H80,_
&H50,&H6C,&H61,&H79,&H65,&H72,&H73,
&H50,&H6C,&H75,&H73,&H31,&H2E,&H31,_
&H01


N'oublions pas, en effet, que des octets système maladroitement choisis peuvent « tuer » irrémédiablement une BasicCard s'ils définissent des paramètres (notamment temporels) que ne supporte pas son processus de téléchargement. Les kits logiciels ZCBasic les plus récents (en téléchargement gratuit) refusent, en principe, le code source des ATR incompatibles avec la carte cible, mais il vaut tout de même mieux savoir exactement où l'on va... Notons bien que le second quartet du deuxième octet de l'ATR doit être impérativement égal au nombre de caractères historiques (ici 14, soit Eh), et qu'il ne faut surtout pas omettre l'octet 01h final (troisième ligne), sous peine de rendre la carte définitivement inutilisable (il précise au compilateur qu'elle doit fonctionner en protocole T=0 et sans LRC).

Le module espion
Ce premier barrage étant franchi avec succès, il va s'agir d'enregistrer, dans la vaste mémoire EEPROM de la carte, la première commande que celle-ci va recevoir du lecteur (a priori quelconque) dans lequel on va l'insérer. En présence d'une application complètement inconnue, il faut commencer par « râtisser large », grâce à la miraculeuse instruction COMMAND ELSE du langage ZCBasic :

Command Else NOTOUT(Lc=0,S$)
C$=CHR$(CLA)+CHR$(INS)+CHR$(P1)+CHR$(P2)+Chr$(Le)
S$=String$(Le,&HFF)
Write#1,C$
End Command

Bien entendu, il faut avoir au préalable ouvert (dans la carte !) un fichier baptisé, par exemple, CARD.LOG :

Open "Card.Log" For Append As #1
Write#1,""

Dans ce fichier vont ainsi s'enregistrer les en-têtes (headers) de toutes les commandes « inconnues » (entendons par-là non définies dans le code source ou par le ZCBasic) que va recevoir la carte, tandis que tout reset de celle-ci sera matérialisé par une ligne vide. Dans le cas de commandes « sortantes » (Lc = 0), la carte renverra au lecteur un nombre d'octets FFh égal à ce qu'il attend (paramètre Le), données factices qui déclencheront très certainement tôt ou tard le rejet de la carte, mais sans les inconvénients de la détection d'une « carte muette ».
Pour récupérer et visualiser le fichier « log » une fois la carte retirée du lecteur, il suffit de le réouvrir depuis une routine « terminal » écrite elle aussi en ZCBasic :

Open"@:Card.log" For Input As #1
Open"Card.log" For Output As #2
While Not EOF(1)
Input#1, Z$
For F=1 To LEN(Z$)
Z=ASC(MID$(Z$,F,1))
Y$=Hex$(Z)+" "
If Len(Y$)=2 THEN Y$="0"+Y$
Print Y$;:Print#2,Y$;
Next F:Print:Print#2
Wend
Print:Print"---- Fin de fichier ----"
Close

En l'occurence, nous pourrions lire :

00 A4 04 00 07

Selon la norme ISO 7816-4, il s'agit d'une commande SELECT dont le champ de données comporte 7 octets : simple identifiant « long » d'un fichier, peut-être, ou alors un AID (Application IDentifier), divulgué ou non, si nous sommes en présence d'une carte multi-applications... Mais comment prendre « proprement » connaissance de ces octets qui constituent la première des « clefs » donnant accès au contenu de la carte ? Facile : en programmant séparément cette commande dans la partie « émulateur » de notre carte, sans oublier de la doter d'une fonction d'enregistrement (tout juste deux lignes de code source, vive le Basic !). Du coup, nous pouvons la déclarer, en toute connaissance de cause, comme commande « entrante » (Disable Le), ce qui change tout !

Command &H00 &HA4 FIRST(S$,Disable Le)
C$=CHR$(CLA)+CHR$(INS)+CHR$(P1)+CHR$(P2)+CHR$(Lc)+S$
Write#1,C$
S$=""
End Command


Certes, cela suppose une recompilation et un nouveau téléchargement, mais le jeu en vaut la chandelle ; cette fois, la commande 00 A4 n'étant plus considérée comme inconnue, elle ne sera pas interceptée par COMMAND ELSE, et les Lc octets de données reçus du terminal s'enregistreront dans le fichier log à la suite de l'en-tête :

00 A4 04 00 07 F0 00 00 00 07 00 01

Si l'on s'amusait à soumettre cette commande à la « vraie » carte depuis un quelconque logiciel capable de nouer un dialogue T=0, on recevrait un compte-rendu de la forme SW1SW2 = 6118, signifiant qu'une réponse de 24 octets (18h) est à notre disposition. Il suffirait alors d'envoyer une commande 00 C0 00 00 18 pour en prendre connaissance et y repérer, par exemple, un groupe d'octets 43 41 53 49 4E (tout bonnement le mot « CASINO » codé en ASCII !). La porte est donc bel et bien entrouverte, alors insistons un peu : essayons la seconde commande que la carte peut s'attendre à recevoir (00 B2 01 0C 12) et voyons si dans le bloc de 18 octets (12h) reçu en réponse, on ne retrouverait pas le numéro imprimé au verso de la carte.
Clairement, nous ne prenons ainsi connaissance que de données dont la lecture doit être considérée comme libre, car nullement protégée par une quelconque fonctionnalité sécuritaire. On peut penser que les informations plus sensibles (compte de points de fidélité et peut-être photo numérisée du titulaire) sont un peu mieux cachées... Pas trace de falsification non plus dans nos manipulations, puisque nous n'avons à aucun moment émulé la moindre donnée personnelle : créer une carte qui réagit simplement comme le prescrit une norme courante et l'insérer (par mégarde ?) dans un terminal qui va forcément la refuser, cela ne constitue pas l'ombre d'une intrusion dans un système informatique. Mais il est à conseiller de s'arrêter là !

Explorer les publiphones
Omniprésents, les publiphones offrent un terrain d'investigations passionnant, dans la mesure où ils acceptent une très grande variété de cartes à puce, tant synchrones qu'asynchrones. Parmi ces dernières, la carte France Telecom mérite une enquête approfondie, du fait qu'après des évolutions tarifaires déjà discutables, sa fonctionnalité puce semble bien être en voie d'abandon. En effet, les cartes actuellement émises ne comportent plus de puce, l'utilisateur étant invité à appeler gratuitement le 3010 comme depuis un poste privé, puis à entrer manuellement son numéro de carte (les 9 derniers chiffres de son numéro de téléphone !) et son code confidentiel (choisi par ses soins). Retour à un mode d'exploitation résolument archaïque, donc, à propos duquel certains ingénieurs du CNET ont toujours émis les plus vives réserves.

photo publiphone

Avec l'apparition, notamment en zones rurales, de publiphones dépourvus de tout lecteur de cartes (voir photo), l'opérateur historique songerait-il à abandonner progressivement les cartes à puce, le ticket téléphone (avec son code à gratter) taillant déjà des croupières à la télécarte ? Certes, les cartes France Telecom à puce, même périmées, sont toujours acceptées (mais pour combien de temps encore ?) par les publiphones, où des surprises de taille nous attendent !
L'ATR à « convention inverse » (3F 65 25 08 24 04 68 90 00) des dernières cartes FT évoque fortement les cartes bancaires B0', et du coup seules les révisions logicielles B, C, D, E, F, et G de la BasicCard ZC 4.5 sont en mesure de la reproduire exactement. A partir de la Rev.H, en effet, un changement de composant interne a servi de prétexte au retour à la convention directe par défaut. Mais comme ZeitControl avait clairement laissé entendre qu'il ne produirait jamais de cartes à convention inverse (très redoutées par la communauté bancaire), n'aurait-il pas tout bonnement subi à nouveau des pressions ? Quoi qu'il en soit, des quantités significatives de certaines de ces versions ont été mises en circulation, et ne sont pas près de s'user si on les traite avec ménagements. A défaut, rien n'interdit de remettre le premier octet de l'ATR à &H3B dans le code source, mais avec le risque que cette petite entorse soit un jour repérée.
La carte France Telecom étant basée sur la bonne vieille technologie BULL CP8, il était tentant de s'inspirer des outils développés, en leur temps, pour expertiser la carte Vitale. Voici donc le code source (SPYFT.BAS) destiné à la BasicCard :

REM SPYFT (c)2002,2008 Patrick GUEULLE

Declare Binary ATR=&H3F,&H65,&H25,&H08, _
&H24,&H04,&H68,&H90,&H00,&H01

EEPROM T$(2000) As String*4
Public K As Byte
EEPROM SPY As Byte=1
Declare Sub Note(S$)

IF SPY=1 Then Open"Card.log" For Append As #1:Write#1,""

Command &HBC &HB0 LIT(Lc=0,S$)
IF SPY=1 THEN Call Note(S$)
ADR=P1P2/8:A$=""
K=(P1P2-(8*ADR))/2
For F=0 TO 63
A$=A$+T$(ADR+F)
Next F
S$=Mid$(A$,K+1,Le)
End Command

Command &HBC &HD0 UPD(S$,Disable Le)
IF Lc<>4 Then SW1SW2=&H6704
ADR=P1P2/8
T$(ADR)=S$
End Command

Command Else OTHER(Lc=0,S$)
If Spy=1 Then Call NOTE(S$)
SW1SW2=&H9000
End Command

Sub Note(S$)
Z$=CHR$(CLA)+CHR$(INS)+CHR$(P1)+CHR$(P2)
IF Len(S$)>0 Then Z$=Z$+CHR$(Lc)
IF Len(S$)=0 Then Z$=Z$+CHR$(Le)
Write#1,Z$+S$
End Sub

Command &HC8 &HA0 SPYONOFF(S$,Disable Le)
SPY=P2
End Command

Command &HC8 &H04 COPY(Lc=0,S$)
Z$="(c)2001 Patrick GUEULLE"
S$=MID$(Z$,P1P2+1,Le)
End Command

Command &HC8 &HA2 FLUSH(S$,Disable Le)
Close
Kill "Card.log" : S$=CHR$(FileError)
End Command

Avec les applications « terminal » BSPYUTIL.BAS et COPFT.BAS ci-dessous, destinées à n'importe quel lecteur PC/SC, il constitue le kit complet de ce projet riche d'applications, baptisé « BasicSPY ».

REM BSPYUTIL (c)2002,2008 Patrick GUEULLE

#Include CARDUTIL.DEF
#Include COMMERR.DEF
ComPort=101

Declare Command &HC8 &HA0 SPY()
Declare Command &HC8 &HA2 FLUSH()

Declare Sub SpyON()
Declare Sub SpyOFF()
Declare Sub FlushBS()
Declare Sub ReadSpy()

CLS:PRINT"Utilitaires BasicSPY Copyright (c)2001,2008 Patrick GUEULLE":PRINT
Call WaitForCard
ResetCard:Call CheckSW1SW2:PRINT

menu:PRINT
PRINT:PRINT"1 --> Transfert fichier interne"
PRINT:PRINT"2 --> Activation mode espion"
PRINT:PRINT"3 --> Desactivation mode espion"
PRINT:PRINT"4 --> Vidage du fichier interne"
PRINT:PRINT"0 --> Quitter"
PRINT:PRINT"Votre choix, puis ENTER"

LINE INPUT X$:PRINT:PRINT
ResetCard:Call CheckSW1SW2()
IF X$="1" THEN Call ReadSpy()
IF X$="2" THEN Call SpyON()
IF X$="3" THEN Call SpyOFF()
IF X$="4" THEN Call FlushBS()
IF X$="0" OR X$="" THEN EXIT
GOTO menu

Sub SpyON()
Call SPY(P1P2=&H0001):Call CheckSW1SW2
IF SW1SW2=&H9000 THEN CLS:PRINT "Mode espion actif !"
End Sub

Sub SpyOFF()
Call SPY(P1P2=&H0000):Call CheckSW1SW2
IF SW1SW2=&H9000 THEN CLS:PRINT "Mode espion inactif !"
End Sub

Sub FlushBS()
Call FLUSH():Call CheckSW1SW2
IF SW1SW2=&H9000 THEN CLS:PRINT "Fichier interne vide !"
End Sub

Sub ReadSpy()
Open"@:card.log" For Input As #1
Open"card.log" For Output As #2
While Not EOF(1)
Input#1, Z$
For F=1 To LEN(Z$)
Z=ASC(MID$(Z$,F,1))
Y$=Hex$(Z)+" "
If Len(Y$)=2 THEN Y$="0"+Y$
Print Y$;:Print#2,Y$;
Next F:Print:Print#2
Wend
Print:Print"---- Fin de fichier ----"
Close
End Sub

--------------------------------------------

REM COPFT (c)2002,2008 Patrick GUEULLE

#Include CARDUTIL.DEF
#Include COMMERR.DEF
ComPort=101
Public S$ As String
Public T$ As String
Declare Sub AFF(S$)
Declare Command &HBC &HB0 LIT(Lc=0,S$)
Declare Command &HBC &HD0 UPD(S$,Disable Le)

Call WaitForCard
ResetCard:Call CheckSW1SW2:Print
MAX=&H0A00

Call LIT(P1P2=&H09C8,S$,Le=2):Call CheckSW1SW2
ADL=ASC(Right$(S$,1))+256*ASC(Left$(S$,1)):ADL=(ADL AND &H3FE0)/4

Open"Clovis.log" For Output As #1
Write#1,Left$(R$,4):Write#1,Right$(R$,4)
A=ADL
While A Call LIT(P1P2=A,S$,Le=4):Write#1,S$:Print".";
A=A+8:Wend
Print:Print:Close#1
Call WaitForNocard

Call WaitForCard
ResetCard:Call CheckSW1SW2:Print
Open"Clovis.log" For Input As #1
Input#1,R$:Call UPD(P1P2=0,R$)
Input#1,R$:Call UPD(P1P2=8,R$)

A=ADL
While A Input#1,U$:Print".";
Call UPD(P1P2=A,U$)
A=A+8:Wend

Sub AFF(S$)
T$=""
For F=1 TO Len(S$)
C$=MID$(S$,F,1):C=ASC(C$):C$=HEX$(C)
IF LEN(C$)=1 then C$="0"+C$
T$=T$+C$
NEXT F
End Sub

Grâce à BSPYUTIL.EXE (l'exécutable compilé à partir de BSPYUTIL.BAS), les opérations d'activation ou de désactivation de la fonction « logger », mais surtout de récupération et de vidage du fichier log seront, en toutes circonstances, un jeu d'enfant.

Cloner la carte France Telecom ?
Vous avez bien lu : COPFT.EXE permet, quant à lui, de recopier purement et simplement, dans l'émulateur, la zone à lecture libre (ADL) d'une carte FT existante. Et tout comme dans le cas de la carte Vitale, bien qu'aucune zone protégée ne soit recopiée (le code PIN n'étant pas demandé par notre utilitaire) et qu'aucune fonction sécuritaire ne soit émulée, il y a gros à parier que ce « clone » très approximatif sera parfaitement fonctionnel ! Qu'est-il donc arrivé à cette application très sûre, ayant jadis fait figure de « vitrine » technologique ? Il faut chercher l'explication dans le fichier CARD.LOG qui, selon les modèles de publiphones, contiendra quelque chose ressemblant à :

BC B0 09 C0 20
BC B0 08 E0 70

ou à :

BC B0 09 C0 20
BC B0 08 E0 04
BC B0 09 48 14

A vrai dire, le publiphone semble bel et bien se contenter de lire la « zone de fabrication » (à partir de l'adresse 09C0) pour y vérifier l'identifiant de l'application (3FE2 à l'adresse 09E0), puis d'aller chercher le numéro de la carte dans la « zone de lecture » (qui commence à l'adresse 08E0), ou plus précisément dans le « prestataire 03 ». Mais le plus étonnant, c'est que le code PIN composé sur le clavier ne soit même plus présenté à la carte (commandes BC 20 et BC 40), ce que confirme l'observation de son compteur de codes faux, qui ne se remet plus à zéro après présentation du bon code (surveiller de près le dernier octet de l'ATR).

Prêtons l'oreille...
Il faut en avoir le coeur net : enregistrons les sons émis (ou non, selon le type de publiphone) par l'écouteur du combiné, et passons-les à l'analyseur de spectre. Nous découvrirons avec stupeur que le numéro de la carte, suivi du code confidentiel puis des digits 000001#, est carrément transmis en DTMF après que le publiphone ait appelé le très fantômatique numéro 08 36 48 35 50 ! On retrouve là le même mode opératoire (fort critiqué) que celui appliqué par les publiphones britanniques qui, lorsqu'ils reconnaissent une carte bancaire (fût-elle à piste magnétique !) appellent le 0800 144 222 et transmettent eux aussi les données confidentielles en DTMF, bien entendu en clair...
Cette fois encore, nous arrivons probablement là aux limites des manipulations que nous pouvons nous risquer à pratiquer impunément : recopier, sur un support aucunement sécurisé, des données librement lisibles dans un original dont on est le légitime titulaire (et qui, au surplus, sont inscrites dessus) ne nous paraît pas plus critiquable que photocopier une carte sans puce. Rappelons en effet que, sans le code PIN qui va avec, un tel « clone » serait inutilisable pour téléphoner « aux frais de la princesse ».
Par contre, créer une carte à puce à partir du numéro d'une carte sans puce, ou pire modifier certains champs de données, serait un pas de plus (et peut-être de trop ?) vers la falsification. Même en devinant que ce serait techniquement possible, voire facile, sans doute vaut-il mieux s'abstenir. Cela dit, les autres terrains d'expérimentation ne manquent pas, bien souvent avec des résultats surprenants ou même inquiétants : cartes SIM et USIM, cartes de fidélité, monétique, santé, etc. Le sujet n'est donc pas clos, loin s'en faut !
Patrick Gueulle pour Pirates Mag'

Tous les ouvrages de l'auteur





Vous aimez cette page ? Partagez-en le lien !

Facebook
Twitter
Google+
LinkedIn
Reddit


[homepage] [RSS] [archives]
[contact & legal & cookies] [since 1997]