Question Corrélation UID, numéro de série et key B.

Plus d'informations
13 Fév 2021 16:01 #2081 par Uranium85
Bonjour chers camarades,
Ça fait un moment que je consulte ce merveilleux forum bien riche grâce aux contributions de tout le monde.:)
J'ai réussi depuis un moment à trouver toutes les clés A et B grâce à la hardnested attack incluse dans une distribution linux basée sur Slackware. Mon badge n'était pas vulnérables à la simple nested de mfoc et que mfcuk a pris deux jours sans succès.
Heureusement pour moi le distributeur est un vieux frigo con et idiot qui ne change rien de plus sur mon badge à part le montant lol ça m'évite de me casser la tête à comprendre des termes que j'ai lu quelques part ici comme CRC, xtea et d'autres
Aujourd'hui, j'ai décidé de créer à partir d'une carte chinoise un badge fonctionnant sur mon distributeur. Pour cela je me pose des questions :
_Est ce que chaque UID a une clé B spécifique que le distributeur connaît déjà pour pouvoir communiquer avec le badge.
(A savoir que j'ai 2 badges originaux et qu'en comparant leurs 2 dumps, les seules différences sont : l'UID, le montant, le numéro de série gravé sur la carte en hexa, et la key B de trois secteurs).
_Comme j'imagine que la réponse et Oui et que chaque UID est attribuée à un numéro de série, comment puis-je trouver la key B qui correspondra à un UID aléatoire.
Je vous remercie d'avance

Une astuce pourra te sauver la vie. Cherche la en permanence!

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
15 Fév 2021 11:17 #2097 par lou
C'est tout à fait cela.
Les clefs B sont dérivées de l'UID pour le type de machines que tu utilises.

Actuellement, nous n'avons pas connaissance de l'algo qui permettrait de calculer ces fameuses clefs B à partir d'un UID.

Je pense qu'il faudrait s'intéresser aux travaux italiens sur le sujet, car eux ont trouvé des algo de dérivations de clefs qui s'appliquent à des systèmes utilisés chez eux.
J'imagine que ça ne doit pas être trop trop différent.

La vie est trop courte pour retirer sa clef USB en toute sécurité :p

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
24 Jui 2021 09:02 #2465 par abou
Peu être uncodage xtea?
En tout cas chez moi j'ai 3 clefs comme cela. Et on vois bien que les keys A et B se suivent !

Il y a quand cherchant qu'on apprend

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
24 Jui 2021 17:21 #2468 par abou
Bon j'ai peu etre trouver une pepite mais encodé avec vieille version de python du coup pour l'instant j'arrive pas a le faire marché mais son encodage suit une norme !!!

github.com/joren485/Mifare-Key-Diversifi...y-diversification.py

Il y a quand cherchant qu'on apprend

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
25 Jui 2021 08:04 #2476 par lou

abou écrit: Bon j'ai peu etre trouver une pepite mais encodé avec vieille version de python du coup pour l'instant j'arrive pas a le faire marché mais son encodage suit une norme !!!

github.com/joren485/Mifare-Key-Diversifi...y-diversification.py


Humm ...
Cet algo de diversification utilise 4 choses :
L'UID de la carte,
Le numéro de secteur pour lequel on veut diversifier la clef,
Une clef de base,
et une clef 3DES.

Nous n'avons pas la clef de base, ni la clef 3DES.

Maintenant, on a déjà vu des boites où ils ont appliqué les consignes du constructeur (ici en l'occurrence NXP), en utilisant ... les valeurs exemples données dans le document d'implémentation !!
Donc pourquoi pas essayer avec comme clef de base A0-A5 ou B0-B5 et comme clef 3DES 00112233445566778899AABBCCDDEEFF
B)

Ceci étant, moi j'aime pas les serpents. Alors le python ...

La vie est trop courte pour retirer sa clef USB en toute sécurité :p

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
25 Jui 2021 08:15 #2479 par abou
Why not . Bas a savoir que sur mes 3 badges qui utilise un algo on toujours la même clef 0 A
Soit A0A1A2A3A4A5
Sachant que les bloc utiliser respect également la norme. Crc hex swap ect
A partir du moment qu'on a uid et toute les clef. La question est peu on faire un reverse engineering pour retrouver les manquants...? 3des ect

Il y a quand cherchant qu'on apprend

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
25 Jui 2021 08:26 - 25 Jui 2021 08:27 #2480 par abou
j'essayerai de le faire fonctionner avec python 3.9 je garanti rien, si une personne compétente en python passe par la on aurait besoin d'un coup de main. si ça fonctionne j’exporte en .exe.
#Lou s'est là, à ce moment précis que tu répond... "j'aime pas Windows faudrait l'exporter pour être lisible sous mac "

L'UID de la carte = ON A
Le numéro de secteur pour lequel on veut diversifier la clef : TOUT LES SECTEURS
Une clef de base : LA 0 A, la seul qui est par defaut sur toutes les cartes.
et une clef 3DES : qui se calcule si on arrive à faire fonctionner le script

Il y a quand cherchant qu'on apprend
Dernière édition: 25 Jui 2021 08:27 par abou.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
25 Jui 2021 08:39 #2484 par lou

abou écrit: Why not . Bas a savoir que sur mes 3 badges qui utilise un algo on toujours la même clef 0 A
Soit A0A1A2A3A4A5
Sachant que les bloc utiliser respect également la norme. Crc hex swap ect
A partir du moment qu'on a uid et toute les clef. La question est peu on faire un reverse engineering pour retrouver les manquants...? 3des ect


Le Mifare Classic prévoit que les clefs par défaut sont :
A0-A5 pour la clef A
B0-B5 pour la clef B
Et que la clef B du secteur 0 ne soit pas modifiée, pour pouvoir lire le MAD (Mifare Application Directory, qui liste ce qu'il y a comme "application" sur le badge) et donc permettre au lecteur d'accéder au secteur qui l'intéresse.

Quant à faire du reverse engineering, humm ... Le propre des algos de diversification, c'est justement de ne pas pouvoir recalculer la "master key" à partir des autres données.
Seule la brute force pourra nous aider (on peut l'aider abvec un peu d'intelligence, type définir un dictionnaire de clefs à tester). Ou la chance.

La vie est trop courte pour retirer sa clef USB en toute sécurité :p

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
25 Jui 2021 12:12 - 25 Jui 2021 12:16 #2488 par abou
Bon bas déjà je galere avec le script, j'ai que des souci de conversion de type de donnée. je poste le script si quelqu un est en mesure de le faire fonctionner.
je poste egalement la structure d'une de mes clef donc bloc 0 avec toutes les clefs. j'ai l'impression d'être incompris.


Quelque chose est masqué pour les invités. Veuillez vous connecter ou vous enregistrer pour le visualiser.

def gen_subkeys(K, cipher):
    """Generate subkeys of cipher"""
    from struct import pack, unpack
    L = "b'00000000000000000000000000000000"
    L = cipher.encrypt(bytes(L))

    LHigh = unpack(">Q", L[:8])[0]
    LLow = unpack(">Q", L[8:])[0]

    K1High = ((LHigh << 1) | (LLow >> 63)) & 0xFFFFFFFFFFFFFFFF
    K1Low = (LLow << 1) & 0xFFFFFFFFFFFFFFFF

    if (LHigh >> 63):
        K1Low ^= 0x87

    K2High = ((K1High << 1) | (K1Low >> 63)) & 0xFFFFFFFFFFFFFFFF
    K2Low = ((K1Low << 1)) & 0xFFFFFFFFFFFFFFFF

    if (K1High >> 63):
        K2Low ^= 0x87

    K1 = pack(">QQ", K1High, K1Low)
    K2 = pack(">QQ", K2High, K2Low)

    return K1, K2


def xor(data, key):
    """XOR function"""
    from itertools import cycle
    xored = "".join(chr(ord(x) ^ ord(y)) for (x, y) in zip(data, cycle(key)))
    return xored.encode("hex")


def cmac_div(key, UID, Sector_number):

    from Crypto.Cipher import AES
    cipher = AES.new(key, AES.MODE_CBC)  ##AES in Cipher block Chaining mode, Init Vector=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    K1, K2 = gen_subkeys(key, cipher)
    xorkey = K1

    M = "01" + UID + Sector_number
    padding = "8000000000000000000000000000000000000000000000000000"
    padding = bytes(padding)
    if len(M) < 64:  ## if padding needed
        M += padding
        xorkey = K2

    if len(M) != 64:
        print("M != 32 byte!")
        exit()

    xordata = M[-32:]  ##last 16 bytes of M
    xoreddata = xor(xordata, xorkey)  ##xor xordata with K1 of K2

    M = M[:-32] + str(xoreddata)  ##replace last 16 bytes with xordata

    cipher = AES.new(key, AES.MODE_CBC)  ##reset cipher
    divkey = cipher.encrypt(M)
    divkey = divkey[-32:-20]  ##AES M and slice out the right piece

    print("AES version")
    print("Masterkey:\t " + key.upper())
    print("UID:\t\t " + UID.upper())
    print("Sector:\t\t " + Sector_number.upper())
    print("Subkey 1:\t " + str(K1))
    print("Subkey 2:\t " + str(K2))
    print("Message:\t " + M)
    print("Diversified key: " + str(divkey.upper()))
    print ()

    return divkey


def des3_div(key, UID, Sector_number, MIFkey):
    """"""
    from Crypto.Cipher import DES3

    trailerblock = 4 * int(Sector_number) + 3  ##van sector naar trailerblock van sector
    trailerblock = "{:02x}".format(trailerblock)
    print(trailerblock)
    trailerblock=bytes(trailerblock)
    M = MIFkey[:8]
    M += xor(MIFkey[8:10].decode("hex"), UID[:2].decode("hex"))
    M += xor(MIFkey[10:].decode("hex"), UID[2:4].decode("hex"))
    M += xor(trailerblock.decode("hex"), UID[4:6].decode("hex"))
    M += UID[6:]

    cipher = DES3.new(key,0)
    divkey = cipher.encrypt(M).hex()[2:14]

    print("3DES version")
    print("Masterkey:\t " + key.upper())
    print("UID:\t\t " + UID.upper())
    print("Sector:\t\t " + Sector_number.upper())
    print("Trailer Block:\t " + trailerblock)
    print("Mifare key:\t " + MIFkey.upper())
    print("Message:\t " + M.upper())
    print("Diversified key: " + str(divkey.upper()))
    print ()

    return divkey


if __name__ == "__main__":
    masterkey = "b'00112233445566778899aabbccddeeff"
    UID = "F4EA548E"
    Sector_number = "05"
    MIFkey = "A0A1A2A3A4A5"  ## Only needed for 3DES version(MF RC171)

    cmac_div(masterkey, UID, Sector_number)
    des3_div(masterkey, UID, "01", MIFkey)

Il y a quand cherchant qu'on apprend
Dernière édition: 25 Jui 2021 12:16 par abou.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
25 Jui 2021 15:08 #2489 par abou
autre piste ici en C :

github.com/nfc-tools/libfreefare

Il y a quand cherchant qu'on apprend

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
05 Sep 2021 09:30 #2835 par abou
du nouveau sur la crrelation entre uid et key.
On peut constater une suite logique de la programmation des key. certainement generer par l'uid.
ce que je constate pour ma part , c'est quel sont toutes de type comestero cashless
ici une doc du logiciel des machines.

www.sisol.ch/download/BA_Unico_engl.pdf

je pense que pour trouver comme elles sont encodé il faudrait décompilé le soft et trouver l'algo dedans. (comme ca était fait pour le calcul XTEA des badges aztek luxeo)

quelqu'un peu relevé le défi???

Il y a quand cherchant qu'on apprend

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
08 Sep 2021 11:42 - 08 Sep 2021 11:44 #2872 par lou

abou écrit: du nouveau sur la crrelation entre uid et key.
On peut constater une suite logique de la programmation des key. certainement generer par l'uid.
ce que je constate pour ma part , c'est quel sont toutes de type comestero cashless
ici une doc du logiciel des machines.

www.sisol.ch/download/BA_Unico_engl.pdf

je pense que pour trouver comme elles sont encodé il faudrait décompilé le soft et trouver l'algo dedans. (comme ca était fait pour le calcul XTEA des badges aztek luxeo)

quelqu'un peu relevé le défi???


Tu as le firmware d'un lecteur compatible sélecta ?
Pour Aztek/Luxéo, c'était le point de départ ...

Qu'est ce qui te fait dire que les clefs sont du type comestero ?
Quelle suite logique vois-tu dans les clefs ?

La vie est trop courte pour retirer sa clef USB en toute sécurité :p
Dernière édition: 08 Sep 2021 11:44 par lou.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
09 Sep 2021 13:53 - 09 Sep 2021 14:04 #2883 par abou
Slt Lou
Commestro car c'est écrit sur la machine et sur le badge...
Je peu retrouver le logiciel. Si je l'ai encore sur le pc...
la il y'a des soft de programmation de clé :
www.rfideas.com/support/tools/downloads
je sais pas si il utilise le meme type d'aglo
sinon j'ai regarder le script mizip et repris pour faire la meme chose sur mifare.
sur mizip chaque clé est xoré par une valeur fixe.
peut être la même chose. reste à trouvé quelle valeur !

Je joint une liste de Key lier a une clé:
tu vas vite comprendre Lou pourquoi je dit qu'il y'a une suite logique... j'ai 4 badges (dump) encodé pareil avec des clés qui on l'air de suivre la meme logique en tout cas flagrant pour les 2 premiers bytes!
2 clé sur une meme station qui ont pas les mêmes key A et B...
sauf toujours la 0 A.


Quelque chose est masqué pour les invités. Veuillez vous connecter ou vous enregistrer pour le visualiser.

Il y a quand cherchant qu'on apprend
Dernière édition: 09 Sep 2021 14:04 par abou.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
10 Sep 2021 12:57 #2886 par larkaaFR
Bonjour ! J'ai tenté à faire fonctionner le code. 3DES marche bien, mais j'ai pas d'exemple pour le AES...
def gen_subkeys(K, cipher):
    """Generate subkeys of cipher"""
    from struct import pack, unpack
    #L = "00000000000000000000000000000000"
    L = '0000000000000000'
    #print(bytes(L, encoding='utf8'))
    #print()
    L = cipher.encrypt(bytes(L, encoding='utf8'))

    LHigh = unpack(">Q", L[:8])[0]
    #print(len(L[8:]),L[8:])
    LLow = unpack(">Q", L[8:])[0]

    K1High = ((LHigh << 1) | (LLow >> 63)) & 0xFFFFFFFFFFFFFFFF
    K1Low = (LLow << 1) & 0xFFFFFFFFFFFFFFFF

    if (LHigh >> 63):
        K1Low ^= 0x87

    K2High = ((K1High << 1) | (K1Low >> 63)) & 0xFFFFFFFFFFFFFFFF
    K2Low = ((K1Low << 1)) & 0xFFFFFFFFFFFFFFFF

    if (K1High >> 63):
        K2Low ^= 0x87

    K1 = pack(">QQ", K1High, K1Low)
    K2 = pack(">QQ", K2High, K2Low)

    return K1, K2


def xor(data, key):
    """XOR function"""
    #from itertools import cycle
    #xored = "".join(chr(ord(str(x)) ^ ord(str(y))) for (x,y) in zip(data, cycle(key)))
    data = bytes(data)
    key = bytes(key)
    xored = bytes(a^b for a,b in zip(data,key))

    #print('xor',data.hex(),data,key.hex(),key,xored.hex())
    return xored.hex()
    #return bytearray(xored.hex(),encoding='utf8')


def cmac_div(key, UID, Sector_number):
    import os

    from Crypto.Cipher import AES
    iv = bytes('0000000000000000',encoding='utf8')
    #iv = os.urandom(16)
    #print('iv',len(iv),iv)
    cipher = AES.new(key, AES.MODE_CBC, iv)  ##AES in Cipher block Chaining mode, Init Vector=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    #print('cipher',cipher)
    K1, K2 = gen_subkeys(key, cipher)
    xorkey = K1

    M = "01" + UID + Sector_number
    M = bytes(M,encoding='utf8')
    padding = b'8000000000000000000000000000000000000000000000000000'
    #padding = bytes(padding, encoding='utf8')
    if len(M) < 64:  ## if padding needed
        M += bytes(padding)
        xorkey = K2

    if len(M) != 64:
        print("M != 32 byte!")
        exit()

    xordata = M[-32:]  ##last 16 bytes of M
    xoreddata = xor(xordata, xorkey)  ##xor xordata with K1 of K2

    M = M[:-32] + bytes(xoreddata,encoding='utf8')  ##replace last 16 bytes with xordata
    iv = bytes(b'0000000000000000')
    cipher = AES.new(key, AES.MODE_CBC, iv)  ##reset cipher
    divkey = cipher.encrypt(M)
    divkey = divkey[-32:-20]  ##AES M and slice out the right piece

    print("AES version")
    print("Masterkey:\t " + key.upper())
    print("UID:\t\t " + UID.upper())
    print("Sector:\t\t " + Sector_number.upper())
    print("Subkey 1:\t " + str(K1))
    print("Subkey 2:\t " + str(K2))
    print("Message:\t " + str(M))
    print("Diversified key:  " + str(divkey.upper()))
    print()

    return divkey


def des3_div(key, UID, Sector_number, MIFkey):
    """"""
    from Crypto.Cipher import DES3
    import codecs
    import struct

    trailerblock = 4 * int(Sector_number) + 3  ##van sector naar trailerblock van sector
    #trailerblock = "{:02x}".format(trailerblock)
    
    #print('tttt',trailerblock,type(trailerblock))
    #trailerblock=bytes(trailerblock,encoding='utf8')
    #trailerblock = b'\x07'
    trailerblock = eval("bytes.fromhex('0{}')".format(trailerblock))
    #print('trailer',trailerblock, type(trailerblock))

    M = MIFkey[:8]
    
    
    #M += xor(MIFkey[8:10].decode("hex"), UID[:2].decode("hex"))
    #M += xor(MIFkey[10:].decode("hex"), UID[2:4].decode("hex"))
    #M += xor(trailerblock.decode("hex"), UID[4:6].decode("hex"))
    
    M = bytes(bytes.fromhex(M))
    MIFkey = (bytearray.fromhex(MIFkey))
    #print('uid',UID)
    UID = bytearray.fromhex(UID)
    #print('uid',UID.hex())

    
    
    M = M + bytes.fromhex(xor(MIFkey[4:5], UID[:1]))
    #print(len(M), M)
    M = M + bytes.fromhex(xor(MIFkey[5:6], UID[1:2]))
    #print(len(M), M)
    M = M + bytes.fromhex(xor(trailerblock, UID[2:3]))
    #print(len(M), M)
    
    
    #print(xor(MIFkey[4:5], UID[:1]), xor(MIFkey[5:6], UID[1:2]),xor(trailerblock, UID[2:3]))
    
    M = M + UID[3:]
    #print(len(M), M,'end')
    key = bytearray(bytes.fromhex(key))
    #print('key',len(key),key)
    #print('M: ',len(M),len(bytes(M)), M.hex())
    
    cipher = DES3.new(bytes(key),DES3.MODE_ECB)
    #print(cipher.encrypt(bytes(M)))
    divkey = cipher.encrypt(bytes(M)).hex()[2:14]

    print("3DES version")
    print("Masterkey:\t " , key.hex())
    print("UID:\t\t " , UID.hex())
    print("Sector:\t\t " , Sector_number)
    print("Trailer Block:\t " , trailerblock)
    print("Mifare key:\t " , MIFkey.hex())
    print("Message:\t " , M.hex())
    print("Diversified key:  " + str(divkey))
    print()

    return divkey


if __name__ == "__main__":
    masterkey = '00112233445566778899aabbccddeeff'
    UID = "F4EA548E"
    Sector_number = "05"
    MIFkey = "A0A1A2A3A4A5"  ## Only needed for 3DES version(MF RC171)

    cmac_div(masterkey, UID, Sector_number)
    des3_div(masterkey, UID, "01", MIFkey)
Les utilisateur(s) suivant ont remercié: abou

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
14 Sep 2021 15:00 #2901 par lou
Abou, les italiens savent déjà recalculer les clefs des basges comestero, à partir de l'UID.

Tu as un UID à me passer pour que je vérifie si ça calcule les bonnes clefs ?

La vie est trop courte pour retirer sa clef USB en toute sécurité :p

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.117 secondes
Propulsé par Kunena