def read_response(self, msg, resp): # VERIFY if msg.startswith(from_hex("00 20 00 81 10")): pin = msg[5:].rstrip('\x00') logger.info("PIN: %s", pin) # Read binary of file 00 01 if msg == from_hex("00 B0 00 00 08"): self.crypto.parse_card_identifier(resp) # Sending challenge elif msg == from_hex("80 84 00 00 08"): self.crypto.parse_card_challenge(resp) # Responding to challenge elif msg.startswith(from_hex("80 82 00 00 48")): self.crypto.parse_lib_challenge(msg) elif self.crypto.lib_nonce and msg == from_hex("80 C0 00 00 48"): self.crypto.parse_card_ch_response(resp) self.crypto.calc_mac_params() # MAC verification for class 0C elif msg[0] == "\x0C": self.crypto.check_message_mac(msg) self.crypto.check_response_mac(resp)
def __init__(self): self.file = None self.data_tag = None self.crypto = GemaltoCrypto() self.crypto.card_identifier = from_hex("00 11 22 33 44 55 66 77") "30 40 00 1A 66 83 29 71 90 00" # card 1 "30 40 00 19 67 C3 29 71 90 00" # card 2 self.crypto.calc_cr_params() self.crypto.card_challenge = from_hex("00 11 22 33 44 55 66 77") self.crypto.card_nonce = "".join(chr(i) for i in range(32))
def apdu(msg, description=None): if description: print('>>', description) # print('>>', msg) resp = relay.execute(from_hex(msg)) # print('<<', to_hex(resp)) return resp
def test_challenge_response_make(): c = GemaltoCrypto() c.card_identifier = os.urandom(8) c.calc_cr_params() c.card_challenge = os.urandom(8) c.card_nonce = os.urandom(32) c.lib_nonce = os.urandom(32) c.lib_random = os.urandom(16) c.lib_constant = from_hex('22 34 00 00 AF 04 E3 A9') card_challenge = c.make_card_challenge() c.parse_card_challenge(card_challenge) lib_challenge = c.make_lib_challenge() c.parse_lib_challenge(lib_challenge) card_ch_response = c.make_card_ch_response() c.parse_card_ch_response(card_ch_response) c.calc_mac_params() msg = c.make_message('\xAA\xBB\xCC\xDD\xEE\xFF' * 10, '\x01' * 4) c.mac_counter -= 1 assert c.check_message_mac(msg) msg = c.make_response('\xAA\xBB\xCC\xDD\xEE\xFF' * 10, '\x01' * 2) assert c.check_response_mac(msg)
def test_challenge_response(): challenge = from_hex('53 30 77 04 FB 36 DD 39') lib_msg = from_hex(''' 80 82 00 00 48 74 91 3E 6A 34 54 3F 85 05 D0 A6 FE E6 F3 52 1B 02 FB 4F 5B 9A B4 63 42 EF 04 13 B7 3D 94 9A F6 A3 99 E2 E0 0D 6B 06 6B DD E0 B0 AD 5A AE 9F 9F 65 44 F7 37 2D 33 41 E2 32 1E 0E CD 0D 54 78 87 EE 39 DC 4D AC 29 3D 7B ''') card_msg = from_hex(''' 14 F5 06 49 D8 3B 86 CC 16 97 53 87 45 AC 2A C7 DC 6A 54 84 26 77 FF 31 0A B2 51 3E 39 CB 59 CA 0E 9B D3 4F 60 55 3B 93 0D 48 8C 50 04 28 5A F9 6B C4 B8 B2 7B 3D 00 EB CB A7 23 25 63 B1 93 B9 34 92 28 9D 81 01 78 E6 90 00 ''') c = GemaltoCrypto() c.card_identifier = from_hex('30 40 00 1A 66 83 29 71') c.calc_cr_params() lib_encr = lib_msg[5:-8] lib_mac = lib_msg[-8:] card_encr = card_msg[:-10] card_mac = card_msg[-10:-2] lib_decr = c.decrypt_cr(lib_encr) card_decr = c.decrypt_cr(card_encr) logger.info("lib decr\n%s", to_hex_blocks(lib_decr)) logger.info("card decr\n%s", to_hex_blocks(card_decr)) lib_mac_calc = c.mac_cr(lib_encr) card_mac_calc = c.mac_cr(card_encr) assert challenge == lib_decr[16:24] assert challenge == card_decr[:8] assert lib_mac == lib_mac_calc assert card_mac == card_mac_calc
def test_mac_message(): c = GemaltoCrypto() c.card_challenge = from_hex(""" 00 11 22 33 44 55 66 77 """) c.card_nonce = from_hex(""" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F """) c.lib_random = from_hex(""" CE D9 89 9E 95 A7 BA 4B 0F 07 C7 0C 49 A0 55 46 """) c.lib_constant = from_hex(""" 22 34 00 00 AF 04 E3 A9 """) c.lib_nonce = from_hex(""" 5A AF CC A9 F5 13 C3 F0 D5 EF 41 3A FE 29 11 63 9E C2 D4 F4 EE A2 B4 D9 35 29 B0 87 DB 64 03 1F """) message = from_hex(''' 0C D6 00 00 2C 81 20 2E 35 37 38 5A 00 30 36 31 31 32 37 33 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 8E 08 25 F0 9B ED D2 A6 07 42 ''') c.calc_mac_params() assert c.check_message_mac(message)
def test_second_mac_message(): c = GemaltoCrypto() c.card_challenge = from_hex(""" 00 11 22 33 44 55 66 77 """) c.card_nonce = from_hex(""" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F """) c.lib_random = from_hex(""" A3 BB 03 14 37 06 A0 DC 3E 2D 8B CF 6C 2B F4 A1 """) c.lib_constant = from_hex(""" 22 34 00 00 AF 04 E3 A9 """) c.lib_nonce = from_hex(""" 4F 27 FB F2 8C E5 EC 1F 44 2E D1 06 E0 F1 29 1D 97 2F 0F E2 E7 1E 3B C1 ED 1B 01 B3 74 9D 18 48 """) message = from_hex(''' 0C D6 00 00 30 81 24 30 22 30 04 03 02 06 40 30 0E 04 01 7B 03 02 00 8B 03 02 03 48 02 01 0A A1 0A 30 08 30 02 04 00 02 02 04 00 8E 08 FC 13 48 3C 8F 35 44 C7 ''') c.calc_mac_params() c.mac_counter = 2 assert c.check_message_mac(message)
def test_parse_challenge_response(): crypto = GemaltoCrypto() crypto.parse_card_identifier(from_hex('30 40 00 1A 66 83 29 71 90 00')) crypto.parse_card_challenge( from_hex(''' C9 93 6F E0 48 29 B5 43 90 00 ''')) crypto.parse_lib_challenge( from_hex(''' 80 82 00 00 48 10 49 F7 E3 08 0A 93 D1 B5 E6 20 AF 68 1A 7E 5E 78 5C 50 5D 52 BD 2C E9 2C CB 64 BE 8F DD 17 C2 EC 5B 70 59 6C 9E ED 01 84 67 B9 54 EA 68 1D 08 A2 0A D0 A0 FC 22 2E 9E 47 E8 FC 7C EF 9F CB 57 2F 5B 26 09 90 68 B8 9E ''')) crypto.parse_card_ch_response( from_hex(''' BD 23 61 C3 DE 90 C4 88 89 CD B0 99 BA 50 23 90 9D B5 A3 97 98 14 92 59 19 CC 91 BB 6A A0 7F C2 8A C3 78 99 6F DE FD 4B 4A B8 66 86 F9 FF 57 CC F2 9D 30 C4 0B 42 5D 51 E7 FB 6D 74 95 D7 FA CF 1C DE 4C 98 19 8A 20 0A 90 00 ''')) crypto.calc_mac_params() assert crypto.check_message_mac( from_hex(''' 0C D6 00 00 2C 81 20 2E 32 30 37 5A 00 32 37 30 39 33 31 34 35 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 8E 08 30 CF B2 A8 4C 19 A2 AF ''')) assert crypto.check_message_mac(from_hex(''' 0C C0 00 00 0E ''')) assert crypto.check_response_mac( from_hex(''' 99 02 90 00 8E 08 EA 65 1F 43 05 A5 E0 D3 90 00 '''))
def respond_to_message(self, msg): if msg == from_hex('00 47 00 9A 05 AC 03 80 01 07'): logger.info( '>>> Intercepting GENERATE ASYMMETRIC KEY PAIR slot 9a') for cmd in ATTACKER_PRIVK_IMPORT_ASYMM: if self.attacker_execute(from_hex(cmd)) != from_hex('90 00'): return Resp.FAILURE self.responding_generate_asymm = True return from_hex(ATTACKER_PUBK_RESPONSE_GENERATE_ASYMM[0]) elif self.responding_generate_asymm: self.responding_generate_asymm = False if msg == from_hex('00 C0 00 00 00'): logger.info('>>> Intercepting GET RESPONSE') return from_hex(ATTACKER_PUBK_RESPONSE_GENERATE_ASYMM[1]) else: logger.info('>>> Expected GET RESPONSE') return Resp.FAILURE
def test_cr_keys(): c = GemaltoCrypto() CR_CARD_IDENTIFIER_CARD1 = from_hex('30 40 00 1A 66 83 29 71') CR_MAC_KEY_CARD1 = from_hex(""" 4d 81 a4 2f 34 fd 05 7c 44 43 6c 1b 45 1f b3 b5 """) CR_DES3_KEY_CARD1 = from_hex(''' 13 36 b7 d5 58 16 29 b9 21 8d 6e f7 eb a8 ff 45 ''') c.card_identifier = CR_CARD_IDENTIFIER_CARD1 c.calc_cr_params() assert c.cr_mac_key == CR_MAC_KEY_CARD1 assert c.cr_des3_key == CR_DES3_KEY_CARD1 CR_CARD_IDENTIFIER_CARD2 = from_hex("30 40 00 19 67 C3 29 71") CR_MAC_KEY_CARD2 = from_hex(''' 0x82 0x5c 0x73 0xf5 0x38 0xf4 0xd4 0x23 0x00 0x5b 0xa9 0x14 0x0c 0x7e 0x07 0x6a ''') CR_DES3_KEY_CARD2 = from_hex(''' 0x0d 0x15 0x33 0x8e 0x7e 0xce 0xef 0x89 0x88 0x1b 0xec 0x86 0xa7 0x78 0xe9 0x78 ''') c.card_identifier = CR_CARD_IDENTIFIER_CARD2 c.calc_cr_params() assert c.cr_mac_key == CR_MAC_KEY_CARD2 assert c.cr_des3_key == CR_DES3_KEY_CARD2
import logging import sys from apdu_printer import APDUPrinter from util import from_hex logger = logging.getLogger() logger.addHandler(logging.StreamHandler(sys.stdout)) logger.setLevel(logging.DEBUG) transmitted = 'transmitted:' received = 'received:' printer = APDUPrinter() for line in open('windows_apdu.log'): line = line.strip() if line.startswith(transmitted): printer.show_command(from_hex(line[len(transmitted):]), 'Command') elif line.startswith(received): printer.show_response(from_hex(line[len(received):]), 'Response')
def magic(value): return from_hex(""" 2E """ + value + """ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90 00 """)
def getATR(self): return from_hex("3B7D00000080318065B08300000083009000")
def execute(self, msg): # SELECT FILE AID if msg == from_hex( "00 A4 04 00 0C A0 00 00 00 18 0E 00 00 01 63 42 00"): return Resp.FILE_NOT_FOUND if msg == from_hex( "00 A4 04 00 0C A0 00 00 00 18 0C 00 00 01 63 42 00"): return Resp.SUCCESS # GET DATA if msg == from_hex("00 CA 9F 7F 2D"): x = "AF 04" # card1 # x = "B5 6A" # card2 return from_hex(""" 9F 7F 2A 47 90 50 81 12 91 11 02 02 01 22 34 00 00 """ + x + """ E3 A9 40 82 30 23 12 93 30 23 20 05 30 23 00 00 00 14 00 00 00 00 00 00 00 00 90 00 """) if msg == from_hex("00 CA DF 30"): return from_hex("6C 08") if msg == from_hex("00 CA DF 30 08"): return from_hex("DF 30 05 76 33 2E 30 33 90 00") # SELECT FILE if msg == from_hex("00 A4 08 0C 02 2F 00"): self.file = from_hex("2F 00") return Resp.SUCCESS if msg == from_hex("00 A4 08 00 02 2F 00"): self.file = from_hex("2F 00") return Resp.SUCCESS_FILE_INFO_AVAILABLE if self.file == from_hex("2F 00") and msg == from_hex( "00 C0 00 00 15"): return from_hex(""" 6F 13 81 02 00 17 82 01 01 83 02 2F 00 8A 01 05 8C 03 03 FF 00 90 00 """) if msg == from_hex("00 A4 08 0C 04 50 00 50 31"): self.file = from_hex("50 00 50 31") return Resp.SUCCESS if msg == from_hex("00 A4 08 00 04 50 00 50 31"): self.file = from_hex("50 00 50 31") return Resp.SUCCESS_FILE_INFO_AVAILABLE if self.file == from_hex("50 00 50 31") and msg == from_hex( "00 C0 00 00 15"): return from_hex(""" 6F 13 81 02 00 54 82 01 01 83 02 50 31 8A 01 05 8C 03 03 FF 00 90 00 """) if msg == from_hex("00 A4 08 0C 04 50 00 50 06"): self.file = from_hex("50 00 50 06") return Resp.SUCCESS if msg == from_hex("00 A4 08 00 04 50 00 50 06"): self.file = from_hex("50 00 50 06") return Resp.SUCCESS_FILE_INFO_AVAILABLE if self.file == from_hex("50 00 50 06") and msg == from_hex( "00 C0 00 00 15"): return from_hex(""" 6F 13 81 02 00 C0 82 01 01 83 02 50 06 8A 01 05 8C 03 03 13 00 90 00 """) if msg == from_hex("00 A4 08 0C 04 50 00 50 32"): self.file = from_hex("50 00 50 32") return Resp.SUCCESS if msg == from_hex("00 A4 08 00 04 50 00 50 32"): self.file = from_hex("50 00 50 32") return Resp.SUCCESS_FILE_INFO_AVAILABLE if self.file == from_hex("50 00 50 32") and msg == from_hex( "00 C0 00 00 15"): return from_hex(""" 6F 13 81 02 00 2B 82 01 01 83 02 50 32 8A 01 05 8C 03 03 D2 00 90 00 """) if msg == from_hex("00 A4 08 0C 04 50 00 50 33"): self.file = from_hex("50 00 50 33") return Resp.SUCCESS if msg == from_hex("00 A4 08 00 04 50 00 50 33"): self.file = from_hex("50 00 50 33") return Resp.SUCCESS_FILE_INFO_AVAILABLE if self.file == from_hex("50 00 50 33") and msg == from_hex( "00 C0 00 00 15"): return from_hex(""" 6F 13 81 02 06 00 82 01 01 83 02 50 33 8A 01 05 8C 03 03 C1 00 90 00 """) if msg == from_hex("00 A4 08 0C 02 00 01"): self.file = from_hex("00 01") return Resp.SUCCESS if msg == from_hex("00 A4 08 00 02 00 01"): self.file = from_hex("00 01") return Resp.SUCCESS_FILE_INFO_AVAILABLE if self.file == from_hex("00 01") and msg == from_hex( "00 C0 00 00 15"): return from_hex(""" 6F 13 81 02 00 08 82 01 01 83 02 00 01 8A 01 05 8C 03 03 FF 00 90 00 """) if msg == from_hex("00 A4 08 0C 02 00 02"): self.file = from_hex("00 02") return Resp.SUCCESS if msg == from_hex("00 A4 08 00 02 00 02"): self.file = from_hex("00 02") return Resp.SUCCESS_FILE_INFO_AVAILABLE if self.file == from_hex("00 02") and msg == from_hex( "00 C0 00 00 15"): return from_hex(""" 6F 13 81 02 00 20 82 01 01 83 02 00 02 8A 01 05 8C 03 03 00 00 90 00 """) if msg == from_hex( "00 A4 02 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" ): return Resp.WRONG_LENGTH if msg == from_hex("00 A4 08 0C 04 50 00 50 34"): self.file = from_hex("50 00 50 34") return Resp.SUCCESS if msg == from_hex("00 A4 08 00 04 50 00 50 34"): self.file = from_hex("50 00 50 34") return Resp.SUCCESS_FILE_INFO_AVAILABLE if self.file == from_hex("50 00 50 34") and msg == from_hex( "00 C0 00 00 15"): return from_hex(""" 6F 13 81 02 03 A4 82 01 01 83 02 50 34 8A 01 05 8C 03 03 FF 00 90 00 """) if msg == from_hex("00 A4 08 0C 04 50 00 50 02"): self.file = from_hex("50 00 50 02") return Resp.SUCCESS if msg == from_hex("00 A4 08 00 04 50 00 50 02"): self.file = from_hex("50 00 50 02") return Resp.SUCCESS_FILE_INFO_AVAILABLE if self.file == from_hex("50 00 50 02") and msg == from_hex( "00 C0 00 00 15"): return from_hex(""" 6F 13 81 02 06 00 82 01 01 83 02 50 02 8A 01 05 8C 03 03 C1 00 90 00 """) # READ BINARY if msg == from_hex("00 B0 00 00 08") and self.file == from_hex( "00 01"): return self.crypto.make_card_identifier() if msg == from_hex("00 B0 00 00 20") and self.file == from_hex( "00 02"): return magic("30 30 30 5A 00 30 30 30 30 30 30 30 30") return magic("35 34 36 5A 00 32 39 31 39 32 34 32 39") return magic("33 31 32 5A 00 30 33 31 36 32 32 33 39") return magic("35 35 34 5A 00 30 33 31 35 31 33 31 30") return magic("33 39 31 5A 00 33 30 31 33 32 33 30 31") if msg == from_hex("00 B0 00 00 17") and self.file == from_hex( "2F 00"): return from_hex(""" 61 15 4F 0D E8 28 BD 08 0F 01 47 65 6D 20 50 31 35 51 04 3F 00 50 00 90 00 """) if msg == from_hex("00 B0 00 00 54") and self.file == from_hex( "50 00 50 31"): return from_hex(""" A8 0A 30 08 04 06 3F 00 50 00 50 06 A0 0A 30 08 04 06 3F 00 50 00 50 01 A1 0A 30 08 04 06 3F 00 50 00 50 02 A4 0A 30 08 04 06 3F 00 50 00 50 03 A7 0A 30 08 04 06 3F 00 50 00 50 04 A7 0A 30 08 04 06 3F 00 50 00 50 05 A3 0A 30 08 04 06 3F 00 50 00 50 07 90 00 """) if msg == from_hex("00 B0 00 00 C0") and self.file == from_hex( "50 00 50 06"): return from_hex(''' 30 31 30 11 0C 08 55 73 65 72 20 50 49 4E 03 02 06 C0 04 01 82 30 03 04 01 81 A1 17 30 15 03 03 04 8C 10 0A 01 02 02 01 06 02 01 10 80 02 00 81 04 01 00 30 2C 30 0C 0C 06 53 4F 20 50 49 4E 03 02 06 C0 30 03 04 01 82 A1 17 30 15 03 03 04 9D 10 0A 01 02 02 01 06 02 01 10 80 02 00 82 04 01 00 02 00 82 04 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90 00 ''') if msg == from_hex("00 B0 00 00 2B") and self.file == from_hex( "50 00 50 32"): x = "1A 66 83" # card1 # x = "19 67 C3" # card2 return from_hex(''' 30 29 02 01 01 04 08 30 40 00 ''' + x + '''29 71 0C 0C 47 65 6D 61 6C 74 6F 20 53 2E 41 2E 80 08 47 65 6D 50 31 35 2D 31 03 02 05 60 90 00 ''') if self.file == from_hex("50 00 50 33"): if msg == from_hex("00 B0 00 00 EE"): return from_hex(""" 30 11 30 0F 04 06 3F 00 50 00 50 40 02 01 00 80 02 75 30 30 14 30 0F 04 06 3F 00 50 00 50 50 02 01 00 80 02 0F A0 04 01 81 30 0A 30 02 04 00 04 01 81 02 01 07 30 0A 30 02 04 00 04 01 81 02 01 08 30 0A 30 02 04 00 04 01 81 02 01 0D 30 0A 30 02 04 00 04 01 81 02 01 0E 30 0A 30 02 04 00 04 01 81 02 01 09 30 0A 30 02 04 00 04 01 81 02 01 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90 00 """) """ 30 11 30 0F 04 06 3F 00 50 00 50 40 02 01 00 80 02 75 30 30 14 30 0F 04 06 3F 00 50 00 50 50 02 01 00 80 02 0F A0 04 01 81 30 0A 30 02 04 00 04 01 81 02 01 03 30 0A 30 02 04 00 04 01 81 02 01 04 30 0A 30 02 04 00 04 01 81 02 01 05 30 0A 30 02 04 00 04 01 81 02 01 07 30 0A 30 02 04 00 04 01 81 02 01 08 30 0A 30 02 04 00 04 01 81 02 01 09 30 0A 30 02 04 00 04 01 81 02 01 0D 30 0A 30 02 04 00 04 01 81 02 01 0E 30 0A 30 02 04 00 04 01 81 02 01 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90 00 """ if msg in [ from_hex(x) for x in [ "00 B0 00 EE EE", "00 B0 01 DC EE", "00 B0 02 CA EE", "00 B0 03 B8 EE", "00 B0 04 A6 EE" ] ]: return from_hex(""" 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90 00 """) if msg == from_hex("00 B0 05 94 6C"): return from_hex(''' 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90 00 ''') if self.file == from_hex("50 00 50 34"): contents = [ ''' 00 B0 00 00 EE ''', ''' 30 4B 30 23 0C 1A 52 53 41 20 50 72 69 76 61 74 65 20 31 2D 32 30 34 38 2D 44 65 63 2D 53 69 67 03 02 06 C0 04 01 81 30 16 04 09 52 53 41 20 70 72 6B 20 31 03 02 02 74 03 02 04 B0 02 01 03 A0 00 A1 0A 30 08 30 02 04 00 02 02 08 00 30 4B 30 23 0C 1A 52 53 41 20 50 72 69 76 61 74 65 20 32 2D 32 30 34 38 2D 44 65 63 2D 53 69 67 03 02 06 C0 04 01 81 30 16 04 09 52 53 41 20 70 72 6B 20 32 03 02 02 74 03 02 04 B0 02 01 04 A0 00 A1 0A 30 08 30 02 04 00 02 02 08 00 30 4B 30 23 0C 1A 52 53 41 20 50 72 69 76 61 74 65 20 33 2D 32 30 34 38 2D 44 65 63 2D 53 69 67 03 02 06 C0 04 01 81 30 16 04 09 52 53 41 20 70 72 6B 20 33 03 02 02 74 03 02 04 B0 02 01 05 A0 00 A1 0A 30 08 30 02 04 00 02 02 08 00 30 4B 30 23 0C 1A 52 90 00 ''', ''' 00 B0 00 EE EE ''', ''' 53 41 20 50 72 69 76 61 74 65 20 34 2D 32 30 34 38 2D 44 65 63 2D 53 69 67 03 02 06 C0 04 01 81 30 16 04 09 52 53 41 20 70 72 6B 20 34 03 02 02 74 03 02 04 B0 02 01 06 A0 00 A1 0A 30 08 30 02 04 00 02 02 08 00 30 4B 30 22 0C 16 52 53 41 20 50 72 69 76 61 74 65 20 35 2D 32 30 34 38 2D 53 69 67 03 02 06 C0 04 01 81 02 01 01 30 17 04 09 52 53 41 20 70 72 6B 20 35 03 03 06 30 40 03 02 04 B0 02 01 07 A0 00 A1 0A 30 08 30 02 04 00 02 02 08 00 30 4B 30 22 0C 16 52 53 41 20 50 72 69 76 61 74 65 20 36 2D 32 30 34 38 2D 53 69 67 03 02 06 C0 04 01 81 02 01 01 30 17 04 09 52 53 41 20 70 72 6B 20 36 03 03 06 30 40 03 02 04 B0 02 01 08 A0 00 A1 0A 30 08 30 02 04 00 02 02 08 00 30 4B 30 23 0C 1A 52 53 41 20 50 72 69 76 90 00 ''', ''' 00 B0 01 DC EE ''', ''' 61 74 65 20 37 2D 31 30 32 34 2D 44 65 63 2D 53 69 67 03 02 06 C0 04 01 81 30 16 04 09 52 53 41 20 70 72 6B 20 37 03 02 02 74 03 02 04 B0 02 01 09 A0 00 A1 0A 30 08 30 02 04 00 02 02 04 00 30 4B 30 23 0C 1A 52 53 41 20 50 72 69 76 61 74 65 20 38 2D 31 30 32 34 2D 44 65 63 2D 53 69 67 03 02 06 C0 04 01 81 30 16 04 09 52 53 41 20 70 72 6B 20 38 03 02 02 74 03 02 04 B0 02 01 0A A0 00 A1 0A 30 08 30 02 04 00 02 02 04 00 30 4B 30 23 0C 1A 52 53 41 20 50 72 69 76 61 74 65 20 39 2D 31 30 32 34 2D 44 65 63 2D 53 69 67 03 02 06 C0 04 01 81 30 16 04 09 52 53 41 20 70 72 6B 20 39 03 02 02 74 03 02 04 B0 02 01 0B A0 00 A1 0A 30 08 30 02 04 00 02 02 04 00 30 4D 30 24 0C 1B 52 53 41 20 50 72 69 76 61 74 65 20 31 30 2D 90 00 ''', ''' 00 B0 02 CA DA ''', ''' 31 30 32 34 2D 44 65 63 2D 53 69 67 03 02 06 C0 04 01 81 30 17 04 0A 52 53 41 20 70 72 6B 20 31 30 03 02 02 74 03 02 04 B0 02 01 0C A0 00 A1 0A 30 08 30 02 04 00 02 02 04 00 30 4D 30 23 0C 17 52 53 41 20 50 72 69 76 61 74 65 20 31 31 2D 31 30 32 34 2D 53 69 67 03 02 06 C0 04 01 81 02 01 01 30 18 04 0A 52 53 41 20 70 72 6B 20 31 31 03 03 06 30 40 03 02 04 B0 02 01 0D A0 00 A1 0A 30 08 30 02 04 00 02 02 04 00 30 4D 30 23 0C 17 52 53 41 20 50 72 69 76 61 74 65 20 31 32 2D 31 30 32 34 2D 53 69 67 03 02 06 C0 04 01 81 02 01 01 30 18 04 0A 52 53 41 20 70 72 6B 20 31 32 03 03 06 30 40 03 02 04 B0 02 01 0E A0 00 A1 0A 30 08 30 02 04 00 02 02 04 00 00 00 90 00 ''', ] contents = [from_hex(x) for x in contents] contents = dict(zip(contents[::2], contents[1::2])) if msg in contents.keys(): return contents[msg] if msg == from_hex("00 B0 00 00 EE") and self.file == from_hex( "50 00 50 02"): return from_hex(''' 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90 00 ''') # VERIFY if msg == from_hex("00 20 00 81 00"): return from_hex("63 C3") if msg == from_hex("00 20 00 82 00"): return from_hex("63 C3") if msg == from_hex( "00 20 00 81 10 31 32 33 34 35 36 00 00 00 00 00 00 00 00 00 00" ): return Resp.SUCCESS # MANAGE SECURITY ENVIRONMENT if msg == from_hex("00 22 41 A4 06 83 01 01 95 01 80"): return Resp.SUCCESS # Sending challenge if msg == from_hex("80 84 00 00 08"): return self.crypto.make_card_challenge() # Responding to challenge if msg.startswith(from_hex("80 82 00 00 48")): self.crypto.parse_lib_challenge(msg) self.crypto.calc_mac_params() return from_hex("61 48") if self.crypto.lib_nonce and msg == from_hex("80 C0 00 00 48"): return self.crypto.make_card_ch_response() # MAC verification for class 0C if msg[0] == "\x0C": self.crypto.check_message_mac(msg) if self.file == from_hex("00 02"): if msg.startswith(from_hex("0C D6 00 00 2C")): return from_hex("61 0E") if msg == from_hex("0C C0 00 00 0E"): return self.crypto.make_response(from_hex("99 02 90 00"), Resp.SUCCESS) if self.file == from_hex("50 00 50 02"): if msg.startswith(from_hex("0C D6 00 00 30")): # UPDATE BINARY return from_hex("61 0E") if msg == from_hex("0C C0 00 00 0E"): return self.crypto.make_response(from_hex("99 02 90 00"), Resp.SUCCESS) # if msg.startswith(from_hex("0C CB 00 FF 16 81 0A B6 03 83 01")): # 0C 7F 49 02 81 00 8E 08 30 29 18 19 0A 2B 32 B4 # self.data_tag == msg[11] + msg[15] # if msg[15] == '\x81': # return from_hex("61 9B") # if msg[15] == '\x82': # return from_hex("61 11") # if self.data_tag and msg == from_hex("00 C0 00 00 8E"): # return from_hex(''' # 81 81 8E B6 03 83 01 ''' + self.data_tag[0] + ''' 7F 49 82 00 84 81 82 00 # 80 93 FE 70 51 AE DE F6 E4 AC 52 36 B7 B6 F1 3F # 90 4C 2B 9B EA 81 2C 32 67 E3 DF 6E F6 A3 BF 87 # F9 CD E4 27 C8 01 61 CC 61 A6 CB 2F 21 67 5E B8 # 46 BB 98 F9 54 06 B4 05 4B 2A 2C C1 F3 3E 1D A2 # 38 BB 0B E9 A6 38 46 CE D0 1B 01 B9 3C 53 37 10 # 79 42 3B 9D 66 B7 00 0E F2 AB 8A 0A 04 DD 72 3D # B1 86 4C 64 CE 96 18 8B 68 E7 66 A6 1A 3E 96 C7 # DC 08 71 EA 09 D6 73 73 3E D2 A9 F2 2E 03 A9 76 # 1F 8E 08 E1 47 93 FF D8 18 E2 27 90 00 # ''') # if self.data_tag and msg == from_hex("00 ") # yolo return from_hex("DEADDEADDEADDEAD")
relay = RelayOS(0) apdu('00 A4 04 00 0C A0 00 00 00 18 0C 00 00 01 63 42 00', 'Select DF by label AID') # apdu('00 CA 9F 7F 2D') # apdu('00 A4 08 00 02 00 01') # apdu('00 C0 00 00 15') apdu('00 20 00 81 10 31 32 33 34 35 36 00 00 00 00 00 00 00 00 00 00', 'Verify PIN') c = GemaltoCrypto() c.lib_nonce = os.urandom(32) c.lib_random = os.urandom(16) c.lib_constant = from_hex('22 34 00 00 AF 04 E3 A9') apdu('00 22 41 A4 06 83 01 01 95 01 80', 'MSE') card_challenge = apdu('80 84 00 00 08', 'get challenge') print("!! parse card challenge") c.parse_card_challenge(card_challenge) print("!! make lib challenge") lib_challenge = c.make_lib_challenge() print("!! parse lib challenge") c.parse_lib_challenge(lib_challenge) ret = apdu(to_hex(lib_challenge), 'lib challenge') assert ret == '\x61\x48'
from __future__ import print_function import logging from Crypto.Cipher import AES, DES, DES3 from Crypto.Hash import SHA from util import from_hex, to_hex_blocks, sxor, str8_to_int, int_to_str8 logger = logging.getLogger(__name__) AES_KEY = "Yy32echR8gWImxqKKqxmIWg8Rhce23yY" AES_CIPHERTEXT = from_hex(""" 58 dc e2 03 c6 63 d1 ac 42 a0 e9 8e 70 32 a9 18 71 47 79 06 c5 6f 8b 76 41 f6 b8 be d1 20 f4 6a """) AES_IV = from_hex(""" c2 fd fa 6b 6f b4 87 38 07 89 10 40 6e d7 fa 2a """) CR_MAC_SEED = '\x00' * 8 CR_DES3_IV = '\x00' * 8 def pad(blocks): last_len = len(blocks) % 8 blocks += "\x80" + "\x00" * (7 - last_len)