From fb91bb7069a8edb1a18beed27709e3570e8b2461 Mon Sep 17 00:00:00 2001 From: Christina Quast Date: Sat, 18 Apr 2015 13:31:42 +0200 Subject: [PATCH] Parsing ajusted: respond to phone requests --- usb_application/apdu_split.py | 31 +++++++++++++++++++-------- usb_application/ccid_raw.py | 2 +- usb_application/mitm.py | 22 ++++++++++++++----- usb_application/smartcard_emulator.py | 31 +++++++++++---------------- usb_application/util.py | 4 +++- 5 files changed, 56 insertions(+), 34 deletions(-) diff --git a/usb_application/apdu_split.py b/usb_application/apdu_split.py index 34c97c25..ef2e81d4 100755 --- a/usb_application/apdu_split.py +++ b/usb_application/apdu_split.py @@ -14,6 +14,8 @@ # GNU General Public License for more details. from enum import Enum +from util import HEX +from array import array class apdu_states(Enum): APDU_S_CLA = 1 @@ -21,17 +23,21 @@ class apdu_states(Enum): APDU_S_P1 = 3 APDU_S_P2 = 4 APDU_S_P3 = 5 - APDU_S_DATA = 6 - APDU_S_DATA_SINGLE = 7 - APDU_S_SW1 = 8 - APDU_S_SW2 = 9 - APDU_S_FIN = 10 + APDU_S_SEND_DATA = 6 + APDU_S_DATA = 7 + APDU_S_DATA_SINGLE = 8 + APDU_S_SW1 = 9 + APDU_S_SW2 = 10 + APDU_S_FIN = 11 class Apdu_splitter: def __init__(self): self.state = apdu_states.APDU_S_CLA self.buf = [] + self.data = [] + self.ins = array('B', []) + self.data_remainig = 0 def func_APDU_S_INS(self, c): self.ins = c @@ -45,14 +51,17 @@ class Apdu_splitter: def func_APDU_S_P3(self, c): self.buf.append(c) self.data_remaining = 256 if c == 0 else c - self.state = apdu_states.APDU_S_SW1 + if self.ins in self.INS_data_expected: + self.state = apdu_states.APDU_S_SEND_DATA + else: + self.state = apdu_states.APDU_S_SW1 def func_APDU_S_DATA(self, c): self.buf.append(c) self.data.append(c) self.data_remaining -= 1 if self.data_remaining == 0: - self.state = apdu_states.APDU_S_SW1; + self.state = apdu_states.APDU_S_SW1 def func_APDU_S_DATA_SINGLE(self, c): self.buf.append(c) @@ -81,7 +90,7 @@ class Apdu_splitter: def func_APDU_S_SW2(self, c): self.buf.append(c) self.sw2 = c - print("APDU:", hex(self.ins), ' '.join(hex(x) for x in self.buf)) + print("APDU:", HEX(self.ins), HEX(self.buf)) self.state = apdu_states.APDU_S_FIN Apdu_S = { @@ -90,12 +99,16 @@ class Apdu_splitter: apdu_states.APDU_S_P1 : func_APDU_S_CLA_P1_P2, apdu_states.APDU_S_P2 : func_APDU_S_CLA_P1_P2, apdu_states.APDU_S_P3 : func_APDU_S_P3, + apdu_states.APDU_S_SEND_DATA : func_APDU_S_DATA, apdu_states.APDU_S_DATA : func_APDU_S_DATA, apdu_states.APDU_S_DATA_SINGLE : func_APDU_S_DATA_SINGLE, apdu_states.APDU_S_SW1 : func_APDU_S_SW1, apdu_states.APDU_S_SW2 : func_APDU_S_SW2 } + INS_data_expected = [0xC0, 0xB0] + def split(self, c): + print("state: ", self.state, c) self.Apdu_S[self.state](self, c) @@ -114,4 +127,4 @@ if __name__ == '__main__': apdus.append(apdu) apdu = Apdu_splitter() for a in apdus: - print(' '.join(hex(x) for x in a.buf)) + print(HEX(a.buf)) diff --git a/usb_application/ccid_raw.py b/usb_application/ccid_raw.py index 4447e348..bd315e57 100755 --- a/usb_application/ccid_raw.py +++ b/usb_application/ccid_raw.py @@ -71,7 +71,7 @@ class SmartcardConnection: def send_receive_cmd(self, cmd): print("Cmd to SIM: " + HEX(cmd)) hresult, resp = SCardTransmit(self.hcard, self.dwActiveProtocol, - cmd.tolist()) + cmd) if hresult != SCARD_S_SUCCESS: raise SmartcardException('Failed to transmit: ' + SCardGetErrorMessage(hresult)) diff --git a/usb_application/mitm.py b/usb_application/mitm.py index 0c9efd85..bc011282 100755 --- a/usb_application/mitm.py +++ b/usb_application/mitm.py @@ -1,5 +1,6 @@ import usb.core import usb.util +import array from ccid_raw import SmartcardConnection from smartcard_emulator import SmartCardEmulator @@ -65,22 +66,33 @@ def do_mitm(sim_emul=True): # sm_con.reset_card() print("Write atr: ", HEX(atr)) write_phone(dev, atr) + apdus = [] + apdu = Apdu_splitter() cmd = poll_ep(dev, PHONE_RD) if cmd is not None: print("RD: ", HEX(cmd)) for c in cmd: + if apdu.state == apdu_states.APDU_S_FIN: + apdus.append(apdu) + apdu = Apdu_splitter() + apdu.split(c) + if apdu.state == apdu_states.APDU_S_SW1: - if len(apdu.data) == 0: + if apdu.data is not None and len(apdu.data) == 0: # FIXME: implement other ACK types - write_phone(dev, apdu.ins) + write_phone(dev, array('B', [apdu.ins])) apdu.split(apdu.ins) else: sim_data = sm_con.send_receive_cmd(apdu.buf) write_phone(dev, sim_data) for c in sim_data: apdu.split(c) - elif apdu.state == apdu_states.APDU_S_FIN: - apdus.append(apdu) - apdu = Apdu_splitter() + elif apdu.state == apdu_states.APDU_S_SEND_DATA: + sim_data = sm_con.send_receive_cmd(apdu.buf) + sim_data.insert(0, apdu.ins) + write_phone(dev, sim_data) + apdu.state = apdu_states.APDU_S_SW1 + for c in sim_data: + apdu.split(c) diff --git a/usb_application/smartcard_emulator.py b/usb_application/smartcard_emulator.py index aa401255..635f4eff 100644 --- a/usb_application/smartcard_emulator.py +++ b/usb_application/smartcard_emulator.py @@ -4,32 +4,22 @@ import constants import array INS = 1 -CNT = 4 +LEN = 4 class SmartCardEmulator: def getATR(self): return array.array('B', constants.ATR_SYSMOCOM2) def send_receive_cmd(self, cmd): - if len(cmd) == 5: # Received cmd from phone - if cmd[INS] == 0xA4: - resp = [cmd[INS]] # Respond with INS byte - elif cmd[INS] == 0xC0: - data = [0x00, 0x00, 0x00, 0x00, - 0x7F, 0x20, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x09, 0x91, 0x00, 0x17, - 0x04, 0x00, 0x83, 0x8A, - 0x83, 0x8A] - SW = [0x90, 0x00] - resp = [cmd[INS]] + data + SW # Respond with INS byte - #state = WAIT_RST - else: - print("Unknown cmd") - resp = [0x60, 0x00] - elif len(cmd) == 2: + if cmd[INS] == 0xA4: resp = [0x9F, 0x16] + elif len(cmd) == 5 and cmd[INS] == 0xC0: + data = self.ans_from_len[cmd[LEN]] + SW = [0x90, 0x00] + resp = data + SW # Respond with INS byte + #state = WAIT_RST else: + print("Unknown cmd") resp = [0x60, 0x00] print("Cmd, resp: ") @@ -43,3 +33,8 @@ class SmartCardEmulator: def close(self): pass + + ans_from_len = {0x16: [0x00, 0x00, 0x00, 0x00, 0x7F, 0x20, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x09, 0x91, 0x00, 0x17, + 0x04, 0x00, 0x83, 0x8A, 0x83, 0x8A], + } diff --git a/usb_application/util.py b/usb_application/util.py index b6ef5a7f..15906bf5 100644 --- a/usb_application/util.py +++ b/usb_application/util.py @@ -1,5 +1,7 @@ def HEX(vals): if vals is not None: + if type(vals) is int: + return "%.2x"%vals return ' '.join('%.2x'%x for x in vals) - + return ''