Last active
October 13, 2016 10:53
-
-
Save bseibold/3627015 to your computer and use it in GitHub Desktop.
Read Uni Ulm Mifare Cards
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
from __future__ import print_function | |
from sys import exit | |
import struct | |
try: | |
from smartcard.System import readers | |
from smartcard.util import toHexString | |
except: | |
print("Dieses Script benötigt python-pyscard") | |
exit(1) | |
KEYA = [ | |
[0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5], | |
[0x46, 0x97, 0x19, 0x7c, 0xf3, 0xa2], | |
[0xbb, 0x85, 0x9d, 0xde, 0x23, 0x19], | |
[0xad, 0x7b, 0x45, 0x71, 0x9c, 0x69], | |
[0x51, 0xfd, 0x7a, 0xcc, 0x61, 0x88], | |
[0xad, 0x7b, 0x45, 0x71, 0x9c, 0x69], | |
[0xad, 0x7b, 0x45, 0x71, 0x9c, 0x69], | |
[0xad, 0x7b, 0x45, 0x71, 0x9c, 0x69], | |
[0xff, 0xff, 0xff, 0xff, 0xff, 0xff], | |
[0x0b, 0x63, 0x0f, 0x85, 0x5c, 0xd1], | |
[0x94, 0x99, 0xd4, 0xa2, 0x29, 0x28], | |
[0x24, 0x83, 0x45, 0xd9, 0xe1, 0x56], | |
[0xa0, 0xc6, 0xef, 0xf5, 0x41, 0x29], | |
[0xa3, 0x05, 0x9e, 0xf3, 0x48, 0xe2], | |
[0x9f, 0xe8, 0x35, 0xe5, 0x04, 0xfe], | |
[0x72, 0xb3, 0xbd, 0xf3, 0x74, 0xab], | |
] | |
r = readers()[0] | |
c = r.createConnection() | |
c.connect() | |
last_auth_sector = -1 | |
def decode_str(data): | |
#return ''.join([chr(x) for x in data]) # urgs, das muss doch schöner gehen | |
return str(bytearray(data)) | |
def decode_valueblock(data): | |
v0, v1, v2, a0, a1, a2, a3 = [b for b in struct.unpack('<iiibbbb', decode_str(data))] | |
v1 = ~v1 | |
a1 = ~a1 | |
a3 = ~a3 | |
if (v0 != v1 != v2): | |
raise ValueError | |
if (a0 != a1 != a2 != a3): | |
raise ValueError | |
return v0, a0 | |
def decode_int(data): | |
return struct.unpack('<i', decode_str(data)) | |
def read_block(nr): | |
global last_auth_sector | |
# load key if necessary | |
if (last_auth_sector != (nr/4)): | |
data, sw1, sw2 = c.transmit([0xFF, 0x82, 0x00, 0x60, 0x06] + KEYA[nr/4]) | |
if [sw1, sw2] != [0x90, 0x00]: | |
raise IOError | |
last_auth_sector = nr/4 | |
# authenticate. nicht nötig mit SCL011, aber vermutlich kompatibler | |
data, sw1, sw2 = c.transmit([0xFF, 0x86, 0x00, 0x00, 0x05, 0x01, 0x00, nr, 0x60, 0x01]) | |
if [sw1, sw2] != [0x90, 0x00]: | |
raise IOError | |
# read block | |
data, sw1, sw2 = c.transmit([0xFF, 0xB0, 0x00, nr, 0x10]) | |
if [sw1, sw2] != [0x90, 0x00]: | |
raise IOError | |
return data | |
b0_raw = read_block(0) | |
b4 = decode_str(read_block(4)) | |
b5 = decode_str(read_block(5)) | |
b6 = decode_str(read_block(6)) | |
print('Mifare UID: 0x%02x%02x%02x%02x' % (b0_raw[0], b0_raw[1], b0_raw[2], b0_raw[3])) | |
print('Maktrikelnummer: %s' % b4[0:8]) | |
print('Immatrikuliert bis: %s.%s.%s' % (b4[8:10],b4[10:12],b4[12:16])) | |
print('') | |
print('PIN-Hash: %s' % b5[0:6]) | |
print('SuperPIN-Hash: %s' % b5[8:16]) | |
print('Übrige Fehlversuche: %s' % b5[6:8]) | |
print('') | |
ulub = decode_str(read_block(8)) | |
bibd = decode_str(read_block(9)) | |
print('Bibliotheksnummer: %s' % ulub) | |
print('Gültig bis: %s.%s.%s' % (bibd[0:2],bibd[2:4],bibd[4:8])) | |
print('') | |
m1 = 'ERROR' | |
m2 = 'ERROR' | |
try: | |
(mensa, a) = decode_valueblock(read_block(48)) | |
m1 = '%.2f EUR' % (mensa/100.) | |
except ValueError: | |
m1 = 'INVALID' | |
except: | |
pass | |
try: | |
(mensa, a) = decode_valueblock(read_block(48)) | |
m2 = '%.2f EUR' % (mensa/100.) | |
except ValueError: | |
m2 = 'INVALID' | |
except: | |
pass | |
print('Mensa-Guthaben (1): %s' % m1) | |
print('Mensa-Guthaben (2): %s' % m2) | |
print('') | |
print('') | |
print('---- Unbekannte Felder ----') | |
print('-- Sektor 1 --') | |
print('block 6: "%s"' % b6) | |
print('') | |
print('-- Sektor 3 --') | |
print('block 12: %s' % toHexString(read_block(12))) | |
print('block 13: "%s"' % decode_str(read_block(13))) | |
print('block 14: "%s"' % decode_str(read_block(14))) | |
print('') | |
print('-- Sektor 7 --') | |
print('block 28: %s' % toHexString(read_block(28))) | |
print('block 29: "%s"' % decode_str(read_block(29))) | |
print('') | |
print('-- Sektor 11 --') | |
print('block 44: %s' % toHexString(read_block(44))) | |
print('block 45: %s' % toHexString(read_block(45))) | |
print('block 46: %s' % toHexString(read_block(46))) | |
print('') | |
print('-- Sektor 13 --') | |
print('block 52: %s' % toHexString(read_block(52))) | |
print('block 53: %s' % toHexString(read_block(53))) | |
print('block 54: %s' % toHexString(read_block(54))) | |
print('') | |
print('-- Sektor 14 --') | |
print('block 56: %s' % toHexString(read_block(56))) | |
print('block 57: %s' % toHexString(read_block(57))) | |
print('block 58: %s' % toHexString(read_block(58))) | |
print('') | |
print('-- Sektor 15 --') | |
print('block 60: value: %d, adr: %d' % decode_valueblock(read_block(60))) | |
print('') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment