blob: 5e8ff6eff09f9feeb88f9a6e339dde02590de31a [file] [log] [blame]
Christina Quast69d1f902015-04-03 11:41:23 +02001import usb.core
2import usb.util
Christina Quastfb91bb72015-04-18 13:31:42 +02003import array
Christina Quast69d1f902015-04-03 11:41:23 +02004
Christina Quast88c7fa12015-04-06 00:35:03 +02005from ccid_raw import SmartcardConnection
Christina Quast158c1dd2015-04-17 20:19:29 +02006from smartcard_emulator import SmartCardEmulator
Christina Quast425717d2015-05-14 17:20:55 +02007from gsmtap import gsmtap_send_apdu
Christina Quast95270b12015-04-04 19:59:03 +02008
Christina Quast88c7fa12015-04-06 00:35:03 +02009from contextlib import closing
10
Christina Quastf2e53f02015-04-11 08:42:38 +020011from util import HEX
Christina Quast9547e9f2015-04-14 22:18:30 +020012from constants import *
Christina Quast53840612015-04-16 11:10:59 +020013from apdu_split import Apdu_splitter, apdu_states
Christina Quast88c7fa12015-04-06 00:35:03 +020014
Christina Quast88c7fa12015-04-06 00:35:03 +020015def pattern_match(inpt):
16 print("Matching inpt", inpt)
Christina Quast94ddb912015-04-11 12:29:41 +020017 if (inpt == ATR_SYSMOCOM1) or (inpt == ATR_STRANGE_SIM):
18 print("ATR: ", inpt)
Christina Quast88c7fa12015-04-06 00:35:03 +020019 return NEW_ATR
20 elif (inpt == CMD_SEL_FILE):
Christina Quast94ddb912015-04-11 12:29:41 +020021 print("CMD_SEL_FILE:", inpt)
22 return CMD_SEL_ROOT
23 elif (inpt == CMD_GET_DATA):
24 print("CMD_DATA:", inpt)
Christina Quast88c7fa12015-04-06 00:35:03 +020025 return CMD_SEL_ROOT
26 else:
27 return inpt
Christina Quast69d1f902015-04-03 11:41:23 +020028
Christina Quast88c7fa12015-04-06 00:35:03 +020029def poll_ep(dev, ep):
30 try:
Christina Quast3a47a4f2015-04-11 18:16:14 +020031 return dev.read(ep, 64, 10)
Christina Quast88c7fa12015-04-06 00:35:03 +020032 except usb.core.USBError as e:
33 if e.errno != ERR_TIMEOUT:
34 raise
35 return None
Christina Quast69d1f902015-04-03 11:41:23 +020036
Christina Quast88c7fa12015-04-06 00:35:03 +020037def write_phone(dev, resp):
Christina Quastf2e53f02015-04-11 08:42:38 +020038 print("WR: ", HEX(resp))
Christina Quast3a47a4f2015-04-11 18:16:14 +020039 dev.write(PHONE_WR, resp, 10)
Christina Quast88c7fa12015-04-06 00:35:03 +020040
Christina Quast46a93672015-04-21 23:00:52 +020041def replace(data):
42 if data is None:
43 raise MITMReplaceError
44 else:
45 try:
46 if data[0] == 0x3B:
47 print("*** Replace ATR")
Christina Quastb6e005c2015-05-04 15:28:03 +020048 return array('B', NEW_ATR)
Christina Quast46a93672015-04-21 23:00:52 +020049 elif data[0] == 0x9F:
50 print("*** Replace return val")
51# return array('B', [0x60, 0x00])
Christina Quast34d4eb32015-05-04 17:50:32 +020052 elif data == PHONE_BOOK_RESP:
53 print("*** Replace phone book")
54 return PHONE_BOOK_RESP_MITM
Christina Quast46a93672015-04-21 23:00:52 +020055 except ValueError:
56 print("*** Value error! ")
57 return data
58
Christina Quast020e5d62015-05-14 18:11:23 +020059def do_mitm(dev, sim_emul=True):
Christina Quast158c1dd2015-04-17 20:19:29 +020060 if sim_emul == True:
61 my_class = SmartCardEmulator
62 else:
63 my_class = SmartcardConnection
64 with closing(my_class()) as sm_con:
Christina Quast6f664a32015-04-06 19:08:04 +020065 atr = sm_con.getATR()
Christina Quast53840612015-04-16 11:10:59 +020066
67 apdus = []
68 apdu = Apdu_splitter()
69
Christina Quast88c7fa12015-04-06 00:35:03 +020070 while True:
71 cmd = poll_ep(dev, PHONE_INT)
72 if cmd is not None:
Christina Quastf2e53f02015-04-11 08:42:38 +020073 print("Int line ", HEX(cmd))
Christina Quast88c7fa12015-04-06 00:35:03 +020074 assert cmd[0] == ord('R')
Christina Quast6f664a32015-04-06 19:08:04 +020075# FIXME: restart card anyways?
76# sm_con.reset_card()
Christina Quastf2e53f02015-04-11 08:42:38 +020077 print("Write atr: ", HEX(atr))
Christina Quast46a93672015-04-21 23:00:52 +020078 write_phone(dev, replace(atr))
Christina Quastfb91bb72015-04-18 13:31:42 +020079 apdus = []
80 apdu = Apdu_splitter()
Christina Quast69d1f902015-04-03 11:41:23 +020081
Christina Quast88c7fa12015-04-06 00:35:03 +020082 cmd = poll_ep(dev, PHONE_RD)
83 if cmd is not None:
Christina Quastf2e53f02015-04-11 08:42:38 +020084 print("RD: ", HEX(cmd))
Christina Quast53840612015-04-16 11:10:59 +020085 for c in cmd:
Christina Quastfb91bb72015-04-18 13:31:42 +020086 if apdu.state == apdu_states.APDU_S_FIN:
87 apdus.append(apdu)
Christina Quast425717d2015-05-14 17:20:55 +020088 gsmtap_send_apdu(apdu.buf)
Christina Quastfb91bb72015-04-18 13:31:42 +020089 apdu = Apdu_splitter()
90
Christina Quast53840612015-04-16 11:10:59 +020091 apdu.split(c)
Christina Quast08ea8612015-05-03 16:34:32 +020092 if apdu.state == apdu_states.APDU_S_FIN and apdu.pts_buf == [0xff, 0x00, 0xff]:
Christina Quastb6e005c2015-05-04 15:28:03 +020093 #sim_data = sm_con.send_receive_cmd(apdu.pts_buf)
94 #write_phone(dev, replace(array('B', sim_data)))
95 write_phone(dev, replace(array('B', apdu.pts_buf)))
Christina Quast08ea8612015-05-03 16:34:32 +020096 continue;
Christina Quastfb91bb72015-04-18 13:31:42 +020097
Christina Quast53840612015-04-16 11:10:59 +020098 if apdu.state == apdu_states.APDU_S_SW1:
Christina Quastfb91bb72015-04-18 13:31:42 +020099 if apdu.data is not None and len(apdu.data) == 0:
Christina Quast53840612015-04-16 11:10:59 +0200100 # FIXME: implement other ACK types
Christina Quast46a93672015-04-21 23:00:52 +0200101 write_phone(dev, replace(array('B', [apdu.ins])))
Christina Quast53840612015-04-16 11:10:59 +0200102 apdu.split(apdu.ins)
103 else:
104 sim_data = sm_con.send_receive_cmd(apdu.buf)
Christina Quast46a93672015-04-21 23:00:52 +0200105 write_phone(dev, replace(sim_data))
Christina Quast53840612015-04-16 11:10:59 +0200106 for c in sim_data:
107 apdu.split(c)
Christina Quastca0ebfd2015-06-19 13:29:14 +0200108 if apdu.state == apdu_states.APDU_S_SEND_DATA:
109 sim_data = sm_con.send_receive_cmd(replace(apdu.buf))
110 #sim_data.insert(0, apdu.ins)
111 write_phone(dev, replace(sim_data))
112 #apdu.state = apdu_states.APDU_S_SW1
113 for c in sim_data:
114 apdu.split(c)