ACBM - Le Virus Informatique qui vous défend !Retour à l'accueilLes brèvesLe magasinContacts Ecrire dans le virusListe de diffusionPetites annoncesLes concours



2013-11-04 00:00

Cartes bancaires sans contact : sauve qui peut ?


En dépit de sa réputation désastreuse en matière de sécurité, nous n'échapperons pas à la carte bancaire sans contact ! On nous assure que des progrès seraient en cours, mais peut-on avoir davantage confiance ? Vérifions donc par nos propres moyens !

En août 2013, sur les 60 millions de cartes bancaires françaises alors en circulation, plus de 13 millions disposaient déjà de la technologie « sans contact », souvent à l'insu de leurs porteurs, tandis que l'on en comptait plus de 59 millions en Europe. Et le mouvement s'accélère à toute vitesse, au fur et à mesure que les commerçants s'équipent de terminaux compatibles. Début 2012, les expériences de Renaud Lifchitz, fortement médiatisées, démontraient qu'il était possible d'accéder à distance, sans que leur porteur ne s'en rende compte, au contenu de la plupart de ces cartes : nom, prénom, numéro et date d'expiration, historique des dernières utilisations... et plus si affinités. Tombant soi-disant des nues, la CNIL organisait alors une série d'expertises pour en avoir le coeur net. Pourtant, dans ses rapports de 2007 et 2009, l'Observatoire de la sécurité des cartes de paiement avait déjà tiré la sonnette d'alarme et émis un certain nombre de recommandations, pas vraiment suivies d'effets...

Pour notre part, il nous a fallu attendre juin 2013 pour obtenir gratuitement notre propre carte contactless, réputée bénéficier des améliorations les plus récentes (le nom du porteur ne devant par exemple plus être lisible en mode sans contact depuis la fin septembre 2012). Honnêtement, le produit est bien pratique à l'usage, et ne fait pas courir un trop grand risque financier en cas de vol ou de perte, car dès que l'on dépasse un cumul de 60 euros de paiements sans contact, le code PIN est exigé. De même, la sollicitation à distance de la carte (avec un simple terminal de paiement mobile ?) pour réaliser des paiements à l'insu de son porteur ne pourrait porter que sur des montants de 20 euros au maximum, évidemment ridicules par rapport au risque pénal encouru.


Ce qui est bien plus préoccupant, c'est la perspective de voir les données de sa carte récupérées ou même modifiées (mais oui !) de façon furtive, juste en se faisant frôler dans une foule ou une file d'attente (d'où l'intérêt des étuis blindés, encore beaucoup trop peu répandus).

Bizarrement, les applications habituellement utilisées pour explorer les cartes EMV en mode « contact » nous ont très vite laissé sur notre faim : associés à un lecteur NFC, ni le regretté Scriptis EMV Explorer de Soliatis (version 1.1.03 datant déjà de 2006), ni le stupéfiant logiciel libre CardPeek (dans sa toute récente version 0.8 pour Windows), n'ont réussi à lire le numéro de notre carte (PAN ou Primary Account Number) qui s'imprime pourtant (en partie) sur les tickets de caisse ! Il nous a donc fallu créer de toutes pièces nos propres outils d'investigation, après avoir longuement joué au chat et à la souris avec notre carte personnelle.

Nul besoin de faire du reverse engineering toutefois, puisque les spécifications EMV sont librement téléchargeables par toute personne intéressée.

Il faut cependant s'attendre à des différences notables entre les modes avec et sans contact. En effet, lors d'une transaction sans contact, la carte ne reste guère plus de 500 ms devant le lecteur, ce qui est bien inférieur au temps qu'elle passerait dans un terminal à contact, que ce soit avant ou après la saisie du code confidentiel.

Il faut donc faire très vite, et même carrément « mettre la charrue avant les boeufs », ce qui n'est pas sans inconvénients ! Un peu comme lorsque l'on prend du carburant à un distributeur automatique, en retirant sa carte avant que l'automate ne sache combien de litres il va délivrer. Prévoyons donc quelques surprises...

Commençons par le commencement !
Dès qu'une carte bancaire EMV est présentée à un terminal de paiement, celui-ci doit faire connaissance avec elle en dressant la liste des « applications » qu'elle supporte : Carte Bleue, Visa, Mastercard, etc. Cela fait, il choisira celle avec laquelle il poursuivra la transaction, ou bien il la rejettera en cas d'incompatibilité (carte purement nationale utilisée à l'étranger, par exemple). Dans un « vrai » terminal, cette besogne est confiée à un module logiciel baptisé Entry Point (point d'entrée).

En mode sans contact, tout commence obligatoirement par une commande de sélection d'une application baptisée PPSE, dont l'identifiant est 2PAY.SYS.DDF01 : 00 A4 04 00 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 00.

La carte renverra un bloc de données (dit FCI ou File Control Information) dont le contenu est déjà instructif. On y trouvera notamment les identifiants des applications supportées par la carte (avec leur ordre préférentiel de priorité), et le numéro du kernel capable de les gérer. Un autre module logiciel du terminal, tout simplement, faisant l'objet d'une spécification EMV détaillée : plus de 200 pages, par exemple, pour le Kernel 3 avec lequel notre carte Visa est compatible. Assez indigeste certes, mais rassemblant la quasi totalité des informations nécessaires pour aller, moyennant beaucoup de patience, jusqu'au fond des choses !

Dans notre carte personnelle, les deux applications reconnues sont CB (A0 00 00 00 42 10 10) et VISA DEBIT (A0 00 00 00 03 10 10). Dans une carte Mastercard, on trouverait plutôt à la place A0 00 00 00 04 10 10. Nous commençons nos investigations par l'application Carte Bleue franco-française, mais nous ferons quelques trouvailles en allant ensuite inspecter les autres...

Sélectionnons donc l'application CB (qui bénéficie d'ailleurs de la priorité la plus élevée) par une commande 00 A4 04 00 07 A0 00 00 00 42 10 10 00. Là encore, la carte retourne un FCI, et c'est ici que les différences commencent à être de taille entre les modes contact (longueur 33 octets) et sans contact (longueur 64 octets).

Parlez vous TLV ?
A ce stade de notre exploration, il convient de se familiariser avec la façon dont les données sont rangées dans la carte. L'organisation TLV (Tag Length Value) consiste à définir des « objets », dont chacun est étiqueté par un tag (un identifiant long d'un ou deux octets) et un octet précisant sa longueur. Pour corser le tout, un objet peut lui-même contenir d'autres structures TLV imbriquées.

Prenons un exemple : dans le FCI que retourne la commande de sélection de l'application CB se trouve (vers la fin) le groupe d'octets suivant : 9F 4D 02 11 FE.

9F4D est un tag dont la signification se trouve dans le « dictionnaire » intégré aux spécifications EMV, et disponible un peu partout sur Internet. Ici, c'est Log Entry, indiquant où et comment est enregistré l'historique des transactions. Pas inintéressant !

L'octet 02 précise que les données « utiles » tiennent sur les deux octets qui le suivent, soit 11 et FE. Selon la spécification du kernel 3 (page 120), 11h signifie que l'historique réside dans un fichier adressable par le SFI (Short File Identifier) n° 11h (17 en décimal), sa longueur étant au maximum de FEh enregistrements (254 en décimal). Bizarrement, nous n'y avons trouvé que 25 enregistrements, les plus récents ayant écrasé les plus anciens... Peut-être dans un louable souci de protection de la vie privée, qui sait ?

Mais le point crucial est que si l'on accède à la carte en mode sans contact, on trouve dans le FCI un objet dont le tag est 9F38, et dont la longueur est (ici) de 24 octets (18h). Facultatif (et donc très souvent absent) en mode contact, cet objet joue un rôle essentiel en mode sans contact. Baptisé PDOL (Processing Options Data Object List), c'est une liste d'objets que la carte réclame au terminal. Et dans l'ordre, s'il vous plaît !

Dans notre cas personnel (et certainement dans bien d'autres), cette liste se présente comme suit : 9F 66 04 9F 02 06 9F 03 06 9F 1A 02 95 05 5F 2A 02 9A 03 9C 01 9F 37 04.

Selon le dictionnaire des tags présent dans les spécifications des kernels, les objets réclamés sont donc les suivants :

9F66 Terminal transaction Qualifiers 4 octets
9F02 Amount, Authorized (Numeric) 6 octets
9F03 Amount, Other (Numeric) 6 octets
9F1A Terminal Country Code 2 octets
9505 Terminal Verification Results 5 octets
5F2A Transaction Currency Code 2 octets
9A Transaction Date 3 octets
9C Transaction Type 1 octet
9F37 Unpredictable Number 4 octets

Il saute aux yeux qu'il s'agit là de la description détaillée de la transaction, que le terminal transmet à la carte pour validation. Les quatre octets aléatoires du tag 9F37 sont manifestement là pour permettre à la carte de calculer rapidement un cryptogramme non rejouable, qui servira (plus tard) à prouver que celle-ci est authentique. Subsidiairement, c'est à partir de ces informations que la carte enregistrera une nouvelle entrée dans son historique, sans savoir encore si la transaction est acceptée ou refusée !

Le terminal enverra ces données à la carte à l'intérieur d'une commande GPO (Get Processing Options), qui constitue ainsi le début des « choses sérieuses » (Initiate Application Processing en jargon EMV).

En l'absence de PDOL (cas très fréquent en mode contact), un terminal bien élevé enverra tout de même une commande GPO, mais « vide » : 80 A8 00 00 02 83 00. En effet, la carte a le droit de refuser l'accès à certaines des données à lecture libre qu'elle contient, tant qu'elle n'a pas reçu cette commande. Elle répondrait alors SW1SW2 = 6985 (Conditions of use not satisfied) au lieu de 9000. Nous y voila !

Partons en exploration !
Pour prendre connaissance des données que contient une carte bancaire EMV (avec ou sans contact), deux modes d'accès doivent être utilisés tour à tour : la lecture directe d'objets « primitifs » par des commandes GET DATA, et la lecture d'enregistrements plus complexes au sein de fichiers par enchaînement de commandes SELECT et READ RECORD.

Bien entendu, la première méthode est plus rapide, et pourrait s'appliquer à des informations dont il est souhaitable de disposer au plus vite après la présentation de la carte. Aux temps héroïques des cartes EMV, les seuls objets lisibles de cette façon étaient :

9F36 Application Transaction Counter (ATC)
9F17 PIN Try Counter
9F13 Last Online ATC Register
9F4F Log Format

Obligatoirement présent, le compteur ATC totalise le nombre de transactions traitées par la carte, avec ou sans succès. C'est dire qu'il se trouvera incrémenté après chaque commande GPO valide. Pas de panique toutefois, car ses deux octets lui permettent de compter jusqu'à 65535, ce qui fait considérer aux experts que le risque de saturation est négligeable, même en cas de manoeuvre malveillante (attaque DoS) visant à bloquer la carte par débordement de ce compteur. Et ils n'ont pas tort...

Le registre 9F13, pour sa part, mémorise la dernière valeur d'ATC correspondant à une transaction traitée en ligne. En pratique, et selon les règles de sécurité fixées par l'émetteur pour une carte donnée, le terminal déclenchera inopinément une vérification en ligne dès que la différence entre ATC et ce Last Online ATC Register dépassera une certaine valeur (en général moins d'une vingtaine).

Un exemple pratique : pour connaître le nombre de présentations encore possibles du code PIN, on pourrait envoyer (après sélection de l'application) une commande 80 CA 9F 17 04. Pour peu que la carte réponde 9F 17 01 03, nous saurions alors que le contenu de l'objet dont le tag est 9F17 et la longueur 1 octet est 03h (3 tentatives autorisées). Une valeur inférieure indiquerait naturellement que le dernier code PIN présenté était faux !

L'autre façon de récupérer des données (et notamment l'éventuel historique des transactions) consiste à sélectionner un fichier par son numéro de SFI (Short File Identifier), puis à lire tout ou partie des enregistrements qu'il contient, au moyen de commandes READ RECORD.

En principe, une liste des principaux fichiers que contient la carte est indiquée, avec le nombre d'enregistrements dont ils se composent, dans le bloc de données que retourne la carte après avoir reçu une commande GPO. Ces informations résident dans un objet baptisé AFL (Application File Locator), identifié par un tag 94.

On l'aura compris, naviguer « proprement » dans l'arborescence des fichiers d'une carte EMV n'est pas si facile, aussi les petits malins que nous sommes auront tout intérêt à opérer par force brute, c'est-à-dire en essayant toutes les valeurs de SFI arithmétiquement possibles. Nous en avons évidemment le temps, et cela peut d'ailleurs faire apparaître des fichiers propriétaires ou non documentés, voire des comptes-rendus d'erreur inhabituels, de nature à nous mettre la puce à l'oreille !

Nous avons par conséquent développé un petit logiciel ZCBasic, qui fonctionnera indifféremment sur un lecteur PC/SC avec ou sans contact. On ne manquera évidemment pas d'essayer les deux, et de comparer les résultats obtenus.

Attention, si on l'utilise avec un lecteur Omnikey 5321 (bi-mode) branché seul, il faut programmer ComPort=102 pour le faire fonctionner en mode sans contact.

#Include CARDUTIL.DEF
#Include COMMERR.DEF
#Include MISC.DEF
Declare Command &H00 &HA4 SEL(S$)
Declare Command &H80 &HA8 GPO(S$,Le=0)
Declare Command &H80 &HCA GETD(Lc=0,P$)
Declare Command &H00 &HB2 RREC(Lc=0,P$)
ComPort=101
Open "SCANCB.log" For Output As #1
Open "SFICB.log" For Output As #2
CLS:Print "SCANCB (c)2013 Patrick GUEULLE":Print
Call WaitForCard:Print
ResetCard:Call CheckSW1SW2
S$=Chr$(&HA0)+Chr$(0)+Chr$(0)+Chr$(0)+Chr$(&H42)+Chr$(&H10)+Chr$(&H10)
Call SEL(P1P2=&H0400,S$)
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$
Print C$;
Next F:Print:Print
Call RandomString(R$,4)
G$=Chr$(&H83)+Chr$(&H21)+Chr$(&H32)+Chr$(&H00)+Chr$(&H00)+Chr$(&H00) _
+Chr$(&H00)+Chr$(&H00)+Chr$(&H00)+Chr$(&H00)+Chr$(&H00)+Chr$(&H00) _
+Chr$(&H00)+Chr$(&H00)+Chr$(&H00)+Chr$(&H00)+Chr$(&H00)+Chr$(&H00) _
+Chr$(&H02)+Chr$(&H50)+Chr$(&H00)+Chr$(&H00)+Chr$(&H00)+Chr$(&H00) _
+Chr$(&H00)+Chr$(&H09)+Chr$(&H78)+Chr$(&H12)+Chr$(&H12)+Chr$(&H31) _
+Chr$(&H00)+R$
Print"Initier transaction a zero ? Entrer OUI ou NON"
Line Input Z$:Print
If Z$="OUI" Or Z$="oui" Then Call GPO(G$)
For N=0 To &HFF
Call GETD(P1=&H9F,P2=N,P$,Le=0)
If SW1<>&H61 Then Goto P
L=SW2:Print "9F";Hex$(N);" : ";
L=SW2:Print #1,"9F";Hex$(N);" : ";
Call GETD(P1=&H9F,P2=N,P$,Le=L)
For F=1 TO L
C$=MID$(P$,F,1):C=ASC(C$):C$=HEX$(C)
IF LEN(C$)=1 then C$="0"+C$
Print C$;:Print #1,C$;
Next F:Print:Print #1
P:Next N:Print:Print #1
S=4
For G=1 To 31
S=S+8
R=1
Record:
Call RREC(P1=R, P2=S,P$,Le=0)
Print #2,"SFI";(S-4)/8,"Record";R,Hex$(SW1SW2)
If SW1<>&H61 Then Goto SFI
Call RREC(P1=R, P2=S,P$,Le=SW2)
Print "SFI";(S-4)/8;"Record";R;": ";
Print #1,"SFI";(S-4)/8;"Record";R;": ";
For F=1 TO Len(P$)
C$=MID$(P$,F,1):C=ASC(C$):C$=HEX$(C)
IF LEN(C$)=1 then C$="0"+C$
Print C$;:Print #1,C$;
Next F:Print:Print #1
Z$=Inkey$
If Z$=Chr$(32) Then Call Sleep(5000)
If Z$=Chr$(27) Then Goto vide
R=R+1:Print:Print #1:Goto Record
SFI:Next G
vide:PRINT:PRINT #1
Close #1:Close #2
Call WaitForNoCard

Le code source ci-dessus (SCANCB.BAS) ne doit pas être considéré comme un outil clef en main destiné à s'attaquer subrepticement aux cartes sans contact de tout un chacun, car là n'est évidemment pas notre propos ! Avant de le recompiler en un exécutable pour Windows SCANCB.EXE (à l'aide du SDK BasicCard, téléchargeable gratuitement), on pourra au contraire opérer quelques ajustements pour parfaire sa compatibilité avec la carte dont on est le légitime porteur et qui servira de cobaye.

En l'état, ce programme inspecte minutieusement l'application CB disponible sur toutes les cartes bancaires françaises (avec et sans contact), après avoir affiché le FCI retourné par la commande SELECT (ce qui permet de vérifier d'un coup d'oeil la présence ou non d'un tag 9F38 suivi de PDOL). En plus d'afficher toutes les données qu'il parvient à en extraire (pauses possibles en pressant brièvement la barre d'espace), il construit deux fichiers texte SCANCB.LOG et SFICB.LOG.

Le premier engrange tout d'abord le contenu de tous les objets primitifs directement accessibles par la commande GET DATA. Et en présence d'une carte sans contact (même lue en mode contact), il y a du neuf !

9F13 : 9F1302003F Last online ATC register
9F17 : 9F170103 PIN try counter
9F36 : 9F3602004C ATC
9F4F : 9F4F109F02069F27019F1A025F2A029A039C01 Log format
9F51 : 9F51020978 Application Currency Code
9F52 : 9F5204E3B82000 Application default action
9F54 : 9F5406000000100000 Cumulative Total Transaction Amount Limit
9F56 : 9F560180 Issuer Authetication indicator
9F57 : 9F57020250 Issuer country code
9F58 : 9F58010A Lower Consecutive Offline Limit
9F59 : 9F590114 Upper Consecutive Offline Limit
9F5C : 9F5C06000000200000 Cumulative Total Transaction Amount Upper Limit
9F68 : 9F680482400000 Card additional processes
9F6B : 9F6B06999999999999 Card CVM limit
9F77 : 9F7706000000006000 VLP Funds Limit
9F78 : 9F7806000000002000 VLP Single Transaction Limit

Parmi plusieurs « plafonds » techniques (à ne pas confondre avec ceux qui ont été alloués par la banque à son client), on remarquera ceux baptisés VLP. Héritage d'une fonctionnalité aujourd'hui obsolète de paiements de faibles montants (Very Low Payments), ils coïncident désormais avec la limite de 60 euros de paiements sans contact cumulés, et avec le montant maximum (20 euros) de ceux-ci.

Si nous sélectionnions l'application VISA DEBIT (A0 00 00 00 03 10 10) au lieu de CB (A0 00 00 00 42 10 10), nous trouverions sans doute en supplément un objet dont le tag est 9F79 (VLP Available Funds), et dont le contenu initial de 60,00 euros diminue au fur et à mesure des paiements réalisés en mode sans contact. Il semble toutefois revenir à 60 euros dès qu'un paiement est effectué en mode contact, avec présentation du code PIN. A surveiller, donc !

A la suite, nous allons découvrir le contenu de tous les enregistrements des différents fichiers ayant pu être lus. En mode contact, on repèrera notamment l'identité du porteur (précédée d'un tag 5F20), le numéro de la carte (tag 5A), sa date d'expiration (tag 5F24), et même l'équivalent du contenu de sa piste magnétique ISO2 (tag 57). Ce serait amplement suffisant pour procéder à des paiements en ligne sur des sites (étrangers, bien sûr...) ne réclamant pas le cryptogramme visuel !

Dans le fichier SFICB.LOG, nous retrouverons les comptes-rendus SW1SW2 reçus lors de chaque tentative de lecture d'un enregistrement, existant ou non. De quoi se faire une idée de la raison pour laquelle l'accès a éventuellement été refusé (le très fréquent 6A82 signifiant par exemple tout simplement File not found).

En mode sans contact, on doit normalement récupérer beaucoup moins de données, sauf si on répond « OUI » pour initier une transaction « à zéro ».

Cette astuce consiste à créer de toutes pièces une commande GPO vraisemblable, mais dans laquelle le montant de la transaction est nul. C'est une pratique courante dans le métier pour procéder à des tests, notamment de paiement sécurisé en ligne. Même quand elle ne laisse aucune trace dans l'historique, une telle transaction à blanc incrémente tout de même le compteur ATC. A employer par conséquent avec une certaine modération !

C'est à ce stade que nous allons pouvoir faire l'inventaire des données sensibles que cette manoeuvre triviale a rendues (ou non) accessibles en lecture. Cela dépend fort probablement de l'âge de la carte, mais même dans les plus récentes l'équivalent de la piste magnétique est toujours lisible...

Bien que les organismes officiels comme la CNIL et l'OSCP relativisent la menace en remarquant (à juste titre) que le contenu de cet objet Track 2 Equivalent Data diffère subtilement du contenu de la piste physique, force est de constater que cela ne touche guère que quelques octets de données dites « discrétionnaires ». Or ceux-ci sont assez couramment ignorés sur le terrain, par exemple à certains péages autoroutiers où il a pu être vérifié jadis qu'un groupe de zéros faisait tout aussi bien l'affaire !

De toute façon, le texte de la spécification EMV est formel : dans une annexe E2 intitulée Creating Track 2, il est indiqué ouvertement « Track 2 Equivalent Data contains all data elements required to create an emulation of the physical Track 2 ». Tout est dit, non ?

Et si les experts se trompaient ?
Maintenant que nous sommes équipés pour faire parler à peu près n'importe quelle carte bancaire sans contact, il est tentant de chercher à comprendre pourquoi les outils couramment utilisés par certains experts en disent beaucoup moins long, au risque de les amener à tirer des conclusions faussement optimistes.

Nous avons donc développé un second programme (EMVCL.BAS, destiné celui-là à être chargé dans une BasicCard sans contact (ZC 7.5). Emulant fidèlement (mais anonymement) notre propre carte bancaire sans contact jusques et y compris au stade de la réception de la commande GPO, il répond toutefois à celle-ci par un compte-rendu d'erreur 6985 (Conditions of use not satisfied).

Les choses en resteront donc là, même si un petit plaisantin s'amusait à présenter discrètement cette carte à un terminal de point de vente pour une tentative de paiement. Ne recevant évidemment pas le cryptogramme attendu, l'appareil rejetterait tout bonnement la transaction ou réclamerait la lecture de la puce afin de la rattraper.
Par contre, utilisée à domicile avec des lecteurs PC/SC pilotés par des logiciels comme CardPeek ou EMV Explorer, cette carte enregistrera fidèlement toutes les commandes qui lui seront envoyées, faisant découvrir très vite le pot aux roses.

#Include Misc.Def
Public A$,C$ As String
#Pragma UID(Single)
#Pragma ATS(TA1=0,FWI=7,TC1=0,HB=Chr$(&H20)+Chr$(&H63)+Chr$(&HCB)+Chr$(&HA5)+Chr$(&HA0))
#Pragma ATR(Direct,T=1,HB="emvCL")
Open "Card.Log" For Append As #1
Write #1,""
Command &HC8 &H04 COP(Lc=0,S$)
Close #1
S$="(c)2009 Patrick GUEULLE"
End Command
Command &HC8 &HA2 FLUSH()
Close #1
Kill "Card.log"
End Command
Command Else SAVE(S$)
Call SuspendSW1SW2Processing()
C$=CHR$(CLA)+CHR$(INS)+CHR$(P1)+CHR$(P2)+Chr$(Lc)+S$
If LePresent() Then C$=C$+Chr$(Le)
S$=String$(Le,&HFF)
Write #1,C$
SW1SW2=&H9000
End Command
Command &H00 &HA4 SEL(S$)
C$=CHR$(CLA)+CHR$(INS)+CHR$(P1)+CHR$(P2)+Chr$(Lc)+S$
If LePresent() Then C$=C$+Chr$(Le)
Write #1,C$
A$=S$:S$="":SW1SW2=&H6A82
If A$="2PAY.SYS.DDF01" Then _
S$=Chr$(&H6F)+Chr$(&H57)+Chr$(&H84)+Chr$(&H0E)+"2PAY.SYS.DDF01" _
+Chr$(&HA5)+Chr$(&H45)+Chr$(&HBF)+Chr$(&H0C)+Chr$(&H42)+Chr$(&H61) _
+Chr$(&H1B)+Chr$(&H4F)+Chr$(&H07)+Chr$(&HA0)+Chr$(&H00)+Chr$(&H00) _
+Chr$(&H00)+Chr$(&H42)+Chr$(&H10)+Chr$(&H10)+Chr$(&H87)+Chr$(&H01) _
+Chr$(&H01)+Chr$(&H50)+Chr$(&H02)+"CB"+Chr$(&H9F) _
+Chr$(&H2A)+Chr$(&H08)+Chr$(&H03)+Chr$(&H00)+Chr$(&H00)+Chr$(&H00) _
+Chr$(&H00)+Chr$(&H00)+Chr$(&H00)+Chr$(&H00)+Chr$(&H61)+Chr$(&H23) _
+Chr$(&H4F)+Chr$(&H07)+Chr$(&HA0)+Chr$(&H00)+Chr$(&H00)+Chr$(&H00) _
+Chr$(&H03)+Chr$(&H10)+Chr$(&H10)+Chr$(&H87)+Chr$(&H01)+Chr$(&H02) _
+Chr$(&H50)+Chr$(&H0A)+"VISA DEBIT" _
+Chr$(&H9F)+Chr$(&H2A)+Chr$(&H08)+Chr$(&H03) _
+Chr$(&H00)+Chr$(&H00)+Chr$(&H00)+Chr$(&H00)+Chr$(&H00)+Chr$(&H00) _
+Chr$(&H00):ResponseLength=Len(S$):SW1SW2=&H9000
If Right$(A$,3)=Chr$(&H42)+Chr$(&H10)+Chr$(&H10)Then _
S$=Chr$(&H6F)+Chr$(&H40)+Chr$(&H84)+Chr$(&H07)+Chr$(&HA0) _
+Chr$(&H00)+Chr$(&H00)+Chr$(&H00)+Chr$(&H42)+Chr$(&H10)+Chr$(&H10) _
+Chr$(&HA5)+Chr$(&H35)+Chr$(&H50)+Chr$(&H02)+"CB" _
+Chr$(&H87)+Chr$(&H01)+Chr$(&H01)+Chr$(&H9F)+Chr$(&H38)+Chr$(&H18) _
+Chr$(&H9F)+Chr$(&H66)+Chr$(&H04)+Chr$(&H9F)+Chr$(&H02)+Chr$(&H06) _
+Chr$(&H9F)+Chr$(&H03)+Chr$(&H06)+Chr$(&H9F)+Chr$(&H1A)+Chr$(&H02) _
+Chr$(&H95)+Chr$(&H05)+Chr$(&H5F)+Chr$(&H2A)+Chr$(&H02)+Chr$(&H9A) _
+Chr$(&H03)+Chr$(&H9C)+Chr$(&H01)+Chr$(&H9F)+Chr$(&H37)+Chr$(&H04) _
+Chr$(&H5F)+Chr$(&H2D)+Chr$(&H04)+Chr$(&H66)+Chr$(&H72)+Chr$(&H65) _
+Chr$(&H6E)+Chr$(&HBF)+Chr$(&H0C)+Chr$(&H09)+Chr$(&HDF)+Chr$(&H61) _
+Chr$(&H01)+Chr$(&H03)+Chr$(&H9F)+Chr$(&H4D)+Chr$(&H02)+Chr$(&H11) _
+Chr$(&HFE):ResponseLength=Len(S$):SW1SW2=&H9000
If Right$(A$,3)=Chr$(&H03)+Chr$(&H10)+Chr$(&H10)Then _
S$=Chr$(&H6F)+Chr$(&H44)+Chr$(&H84)+Chr$(&H07)+Chr$(&HA0) _
+Chr$(&H00)+Chr$(&H00)+Chr$(&H00)+Chr$(&H03)+Chr$(&H10)+Chr$(&H10) _
+Chr$(&HA5)+Chr$(&H39)+Chr$(&H50)+Chr$(&H0A)+"VISA DEBIT" _
+Chr$(&H87)+Chr$(&H01)+Chr$(&H02)+Chr$(&H9F)+Chr$(&H38)+Chr$(&H18) _
+Chr$(&H9F)+Chr$(&H66)+Chr$(&H04)+Chr$(&H9F)+Chr$(&H02)+Chr$(&H06) _
+Chr$(&H9F)+Chr$(&H03)+Chr$(&H06)+Chr$(&H9F)+Chr$(&H1A)+Chr$(&H02) _
+Chr$(&H95)+Chr$(&H05)+Chr$(&H5F)+Chr$(&H2A)+Chr$(&H02)+Chr$(&H9A) _
+Chr$(&H03)+Chr$(&H9C)+Chr$(&H01)+Chr$(&H9F)+Chr$(&H37)+Chr$(&H04) _
+Chr$(&H5F)+Chr$(&H2D)+Chr$(&H04)+Chr$(&H66)+Chr$(&H72)+Chr$(&H65) _
+Chr$(&H6E)+Chr$(&HBF)+Chr$(&H0C)+Chr$(&H05)+Chr$(&H9F)+Chr$(&H4D) _
+Chr$(&H02)+Chr$(&H11)+Chr$(&HFE):ResponseLength=Len(S$):SW1SW2=&H9000
End Command
Command &H80 &HA8 GPO(G$)
C$=CHR$(CLA)+CHR$(INS)+CHR$(P1)+CHR$(P2)+Chr$(Lc)+G$
If LePresent() Then C$=C$+Chr$(Le)
Write #1,C$
SW1SW2=&H6985
End Command
Command &H00 &HB2 RREC(G$)
C$=CHR$(CLA)+CHR$(INS)+CHR$(P1)+CHR$(P2)+Chr$(Lc)+G$
If LePresent() Then C$=C$+Chr$(Le)
Write #1,C$
SW1SW2=&H6A83
End Command
Command &H80 &HCA GETD(G$)
C$=CHR$(CLA)+CHR$(INS)+CHR$(P1)+CHR$(P2)+Chr$(Lc)+G$
If LePresent() Then C$=C$+Chr$(Le)
Write #1,C$
SW1SW2=&H6A88
End Command

Une fois terminé le dialogue entre la carte et le lecteur sans contact, un petit utilitaire pour Windows CLUTIL.BAS (à compiler en CLUTIL.EXE) va permettre de récupérer (dans un fichier CARD.LOG) tout ce qui a été enregistré, et si nécessaire de libérer la mémoire en vue de prochaines aventures.

#Include CARDUTIL.DEF
#Include COMMERR.DEF
ComPort=101
Declare Command &HC8 &HA2 FLUSH()
Declare Command &HC8 &H04 COP(S$,Le=&H17)
Declare Sub FlushRF()
Declare Sub ReadSpy()
CLS:PRINT"BasicSpy utilities Copyright (c)2001, 20013 Patrick GUEULLE":PRINT
Call WaitForCard
ResetCard:Call CheckSW1SW2:PRINT
Call COP(S$)
IF Len(S$)<>&H17 Then Print"Wrong card !":EXIT
menu:PRINT
PRINT:PRINT"1 --> Download LOG file"
PRINT:PRINT"2 --> Clear LOG file"
PRINT:PRINT"0 --> Quit"
PRINT:PRINT"Your choice, then ENTER"
LINE INPUT X$:PRINT:PRINT
IF X$="1" THEN Call ReadSpy()
IF X$="2" THEN Call FlushRF()
IF X$="0" OR X$="" THEN EXIT
GOTO menu
Sub FlushRF()
Call FLUSH():Call CheckSW1SW2
IF SW1SW2=&H9000 THEN CLS:PRINT "LOG file cleared !"
End Sub
Sub ReadSpy()
Open"@:card.log" For Input As #1
Open"card.log" For Output As #2
CLS: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"---- End Of File ----"
Close
End Sub

Voici comment se présente le début du dialogue intercepté entre notre carte de test et CardPeek (version 0.8 ou antérieure), un excellent logiciel qui nous a toujours donné satisfaction en mode contact :

00 A4 04 00 0E 31 50 41 59 2E 53 59 53 2E 44 44 46 30 31 00
00 A4 04 00 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 00
00 A4 04 00 07 A0 00 00 00 42 10 10 00
80 A8 00 00 1A 83 18 9F 66 04 9F 02 06 9F 03 06 9F 1A 02 95 05 5F 2A 02 9A 03 9C 01 9F 37 04 00
80 A8 00 00 02 83 00 00

L'anomalie saute aux yeux : dans le bloc de données de la commande GPO, on découvre le contenu de PDOL en lieu et place de la concaténation du contenu des tags réclamés ! Non seulement les données ainsi envoyées à la carte ne sont pas les bonnes, mais leur longueur est incorrecte (18h au lieu des 21h attendus). Ce « bug », dont la cause pourrait être une simple faute de frappe dans le code-source, passait largement inaperçu en mode contact, les commandes GPO « vides » étant pour leur part convenablement gérées. Bien entendu, nous avons averti l'auteur du logiciel de ce défaut, qui devrait être corrigé dès la prochaine version. Mais, en attendant, combien d'investigateurs auront cru en toute bonne foi (mais à tort) que l'on ne pouvait plus du tout lire de données indiscrètes dans les cartes sans contact ? C'était pourtant trop beau pour être vrai...

Le cas du logiciel EMV Explorer est sensiblement différent dans la mesure où, bien qu'un peu « bizarre », le contenu de la commande GPO est plus proche de ce qu'il devrait être. Mais sa longueur est là encore incorrecte (1Fh octets au lieu de 21h). Même punition, donc : les cartes sans contact un peu sourcilleuses ne donneront pas accès aux données les plus sensibles qu'elles contiennent ! Mais n'en tirons surtout pas de conclusions faussement rassurantes...

00 A4 04 00 0E 31 50 41 59 2E 53 59 53 2E 44 44 46 30 31 00
00 A4 04 00 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 00
00 A4 04 00 07 A0 00 00 00 42 10 10 00
80 A8 00 00 21 83 1F 80 00 00 00 00 00 00 10 00 00 00 00 00 00 08 26 00 00 00 00 00 09 78 03 04 16 54 00 00 00 00 00
00 A4 04 00 07 A0 00 00 00 03 10 10 00
80 A8 00 00 21 83 1F 80 00 00 00 00 00 00 10 00 00 00 00 00 00 08 26 00 00 00 00 00 09 78 03 04 16 54 00 00 00 00 00

A titre de « corrigé », voici la commande GPO enregistrée par la même carte lors de l'utilisation de notre logiciel SCANCB.EXE :

80 A8 00 00 23 83 21 32 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 50 00 00 00 00 00 09 78 12 12 31 00 E4 EC 9E 52 00

On pourra vérifier que la longueur du bloc de données introduit par le tag 83 (21h soit 33 octets) est bien égale à la somme des longueurs des objets réclamés dans PDOL (4 + 6 + 6 + 2 + 5 + 2 + 3 + 1 + 4). Un octet de plus ou de moins, et cela ne fonctionnerait sûrement pas. D'où la nécessité d'adapter légèrement notre code source SCANCB.BAS, pour une carte donnée, selon le contenu exact de PDOL. Un logiciel malveillant pourrait évidemment automatiser cette procédure et s'attaquer ainsi à n'importe quelle carte rencontrée « dans la nature », mais notre éthique nous interdit bien sûr d'aller jusque-là.

Pour les farceurs (et ceux qui veulent se protéger)
Même si cela ne permettrait en aucune façon de frauder, nos investigations ont démontré qu'il serait parfaitement possible de modifier indirectement certains champs de données à l'intérieur d'une carte bancaire sans contact dont on approcherait un lecteur approprié. Le compteur ATC, tout d'abord, en envoyant simplement plusieurs commandes GPO valides mais de montant nul. De quoi obliger la carte à se faire vérifier en ligne lors du prochain paiement, ce qui va plutôt dans le sens de la sécurité.

Moins anodin serait l'envoi de commandes GPO contenant un montant et une date fantaisistes, car pour peu que leur syntaxe soit correcte, les transactions en question s'inscriraient méticuleusement dans l'historique de la carte ! Si sa capacité n'est que de 25 entrées, on devine à quel point il serait facile et rapide de tout remplacer par des enregistrements « bidon », éventuellement antérieurs à la date du jour (ici le 31/12/2012) ou libellés dans une devise du bout du monde. Adieu, la lecture de ce « mouchard » à des fins indiscrètes ! Simultanément, le cumul des paiements sans contact se trouverait certainement diminué, voire ramené à zéro. De quoi interdire toute utilisation du mode sans contact tant que le code PIN n'aurait pas été présenté lors d'un paiement en mode contact ! Cela pourrait être utile à l'occasion...
Il est assez croustillant de remarquer que si des recommandations officielles, aujourd'hui en cours d'application, proscrivent la lecture de l'historique en mode sans contact, elles n'empêchent absolument pas de modifier son contenu à distance...

De telles plaisanteries ne bloquant pas durablement la carte comme le ferait la présentation de trois codes PIN erronés, il ne s'agirait cependant pas vraiment d'actes de malveillance, et le bénéfice serait à peu près nul pour l'attaquant. Il n'empêche que cela fait plutôt désordre.
Patrick Gueulle

Tous les ouvrages de l'auteur





Vous aimez cette page ? Partagez-en le lien sur les réseaux sociaux !

Facebook
Twitter
Google+
LinkedIn


Retour aux archives
Retour à l'accueil
[RSS]
Legal & cookies