4 Commits

Author SHA1 Message Date
Christina Quast
2a5debfec4 Removed printfs from PIO Smartcard ISR 2015-11-10 12:14:02 +01:00
Christina Quast
557e287feb Send on Slot updates over USB on CCID init
When SIM card gets inserted into the SIM card slot, pinSmartCard is
connected to GND; otherwise a pullup connects the pin to VCC.
2015-11-10 12:08:46 +01:00
Christina Quast
899348ebbe Added state to replacing process 2015-11-10 09:36:27 +01:00
Christina Quast
442dc27bc9 Remove check for PIO_ISR interrue
At first I thought I had to check the interrupt source when my interrupt
handler was called. But then, the smart card insertion pin was never
marked as the interrupt source in the PIO_ISR.

It turns out, the ISR register is cleared on read, which is done by the
atmel lib function PioInterruptHandler.
2015-11-05 10:57:50 +01:00
4 changed files with 149 additions and 164 deletions

View File

@@ -2,6 +2,7 @@
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2009, Atmel Corporation
* Copyright (c) 2014, Christina Quast
*
* All rights reserved.
*
@@ -57,7 +58,6 @@ static const Pin pinsBus[] = {PINS_BUS_DEFAULT};
static const Pin pinsPower[] = {PWR_PINS};
/** ISO7816 RST pin */
static const Pin pinIso7816RstMC = PIN_ISO7816_RSTMC;
static uint8_t sim_inserted = 0;
static struct Usart_info usart_info = {.base = USART_SIM, .id = ID_USART_SIM, .state = USART_RCV};
@@ -74,33 +74,17 @@ static const Pin pinSmartCard = SMARTCARD_CONNECT_PIN;
*/
static void ISR_PioSmartCard( const Pin *pPin )
{
/* FIXME: why is pinSmartCard.pio->PIO_ISR the wrong number?
printf("+++++ Trying to check for pending interrupts (PIO ISR: 0x%X)\n\r", pinSmartCard.pio->PIO_ISR);
printf("+++++ Mask: 0x%X\n\r", pinSmartCard.mask);
Output:
+++++ Trying to check for pending interrupts (PIO ISR: 0x400)) = 1<<10
+++++ Mask: 0x100 = 1<<8
*/
// PA10 is DTXD, which is the debug uart transmit pin
printf("Interrupt!!\n\r");
/* Check all pending interrupts */
// FIXME: this if condition is not always true...
// if ( (pinSmartCard.pio->PIO_ISR & pinSmartCard.mask) != 0 )
/* Check current level on pin */
/* The interrupt is already erased on read from the PIO_ISR (PIO Interrupt
* Status Register) by the calling higher level interrupt handler
*/
if ( PIO_Get( &pinSmartCard ) == 0 )
{
/* Check current level on pin */
if ( PIO_Get( &pinSmartCard ) == 0 )
{
sim_inserted = 1;
printf( "-I- Smartcard inserted\n\r" ) ;
CCID_Insertion();
}
else
{
sim_inserted = 0;
printf( "-I- Smartcard removed\n\r" ) ;
CCID_Removal();
}
CCID_Insertion();
}
else
{
CCID_Removal();
}
}
@@ -164,10 +148,10 @@ void CCID_init( void )
/* Decode ATR and print it */
ISO7816_Decode_ATR( pAtr ) ;
// FIXME. what if smcard is not inserted?
if(PIO_Get(&pinSmartCard) == 0) {
printf("SIM card inserted\n\r");
CCID_Insertion();
} else {
CCID_Removal();
}
}

View File

@@ -1,98 +1,49 @@
import usb.core
import usb.util
#!/usr/bin/env python
import array
from ccid_raw import SmartcardConnection
from smartcard_emulator import SmartCardEmulator
from gsmtap import gsmtap_send_apdu
from contextlib import closing
from util import HEX
from constants import *
from apdu_split import Apdu_splitter, apdu_states
from replace import replace
def pattern_match(inpt):
print("Matching inpt", inpt)
if (inpt == ATR_SYSMOCOM1) or (inpt == ATR_STRANGE_SIM):
print("ATR: ", inpt)
return NEW_ATR
elif (inpt == CMD_SEL_FILE):
print("CMD_SEL_FILE:", inpt)
return CMD_SEL_ROOT
elif (inpt == CMD_GET_DATA):
print("CMD_DATA:", inpt)
return CMD_SEL_ROOT
else:
return inpt
# Address book entries
name = 'deine mudda'
phone = '0123456789abcdef'
def poll_ep(dev, ep):
try:
return dev.read(ep, 64, 10)
except usb.core.USBError as e:
if e.errno != ERR_TIMEOUT:
raise
return None
states = {ATR, PTS_BUF, APDU_INS, SIM_DATA}
def write_phone(dev, resp):
print("WR: ", HEX(resp))
dev.write(PHONE_WR, resp, 10)
class MitM:
def attack(self, state, data):
print(replace.last_req)
if data is None:
raise MITMReplaceError
else:
try:
if data[0] == 0xA0:
print("INS: ", hex(data[1]))
replace.last_req = data
return data
def do_mitm(dev, sim_emul=True):
if sim_emul == True:
my_class = SmartCardEmulator
else:
my_class = SmartcardConnection
with closing(my_class()) as sm_con:
atr = sm_con.getATR()
if data[0] == 0x3B:
return data
#print("*** Replace ATR")
#return array('B', NEW_ATR)
elif data[0] == 0x9F:
return data
# print("*** Replace return val")
# return array('B', [0x60, 0x00])
elif replace.last_req[1:5] == array('B', [0xB2, 0x01, 0x04, 0x1A]): # phone book request
print("*** Replace phone book")
# return array('B', [0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xff, 0xff, 0xff, 0xff, 0x09, 0x81, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xff, 0xff, 0xff, 0xff, 0x90, 0x00])
resp = map(ord, name) + ([0xff]*(12-len(name))) + [len(name) + 1] + [0x81]
for x in range(1,len(phone)/2+1):
list.append(resp, int(phone[x*2-2:2*x:], 16))
resp += ([0xff]*(replace.last_req[4]-len(resp))) + [0x90, 0x00]
return array('B', resp)
except ValueError:
print("*** Value error! ")
return data
apdus = []
apdu = Apdu_splitter()
replace.last_req = array('B')
while True:
cmd = poll_ep(dev, PHONE_INT)
if cmd is not None:
print("Int line ", HEX(cmd))
assert cmd[0] == ord('R')
# FIXME: restart card anyways?
# sm_con.reset_card()
print("Write atr: ", HEX(atr))
write_phone(dev, replace(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)
gsmtap_send_apdu(apdu.buf)
apdu = Apdu_splitter()
apdu.split(c)
if apdu.state == apdu_states.APDU_S_FIN and apdu.pts_buf == [0xff, 0x00, 0xff]:
#sim_data = sm_con.send_receive_cmd(apdu.pts_buf)
#write_phone(dev, replace(array('B', sim_data)))
write_phone(dev, replace(array('B', apdu.pts_buf)))
continue;
if apdu.state == apdu_states.APDU_S_SW1:
if apdu.data is not None and len(apdu.data) == 0:
# FIXME: implement other ACK types
write_phone(dev, replace(array('B', [apdu.ins])))
apdu.split(apdu.ins)
else:
sim_data = sm_con.send_receive_cmd(apdu.buf)
write_phone(dev, replace(sim_data))
for c in sim_data:
apdu.split(c)
if apdu.state == apdu_states.APDU_S_SEND_DATA:
sim_data = sm_con.send_receive_cmd(replace(apdu.buf))
#sim_data.insert(0, apdu.ins)
write_phone(dev, replace(sim_data))
#apdu.state = apdu_states.APDU_S_SW1
for c in sim_data:
apdu.split(c)
if __name__ == '__main__':
print("Replacing PHONE_BOOK_REQ", PHONE_BOOK_REQ, "with", replace(PHONE_BOOK_REQ))
print("Replacing PHONE_BOOK_RESP", PHONE_BOOK_RESP, "with", replace(PHONE_BOOK_RESP))

96
usb_application/mitm_io.py Executable file
View File

@@ -0,0 +1,96 @@
import usb.core
import usb.util
import array
from ccid_raw import SmartcardConnection
from smartcard_emulator import SmartCardEmulator
from gsmtap import gsmtap_send_apdu
from contextlib import closing
from util import HEX
from constants import *
from apdu_split import Apdu_splitter, apdu_states
def pattern_match(inpt):
print("Matching inpt", inpt)
if (inpt == ATR_SYSMOCOM1) or (inpt == ATR_STRANGE_SIM):
print("ATR: ", inpt)
return NEW_ATR
elif (inpt == CMD_SEL_FILE):
print("CMD_SEL_FILE:", inpt)
return CMD_SEL_ROOT
elif (inpt == CMD_GET_DATA):
print("CMD_DATA:", inpt)
return CMD_SEL_ROOT
else:
return inpt
def poll_ep(dev, ep):
try:
return dev.read(ep, 64, 10)
except usb.core.USBError as e:
if e.errno != ERR_TIMEOUT:
raise
return None
def write_phone(dev, resp):
print("WR: ", HEX(resp))
dev.write(PHONE_WR, resp, 10)
def do_mitm(dev, sim_emul=True):
if sim_emul == True:
my_class = SmartCardEmulator
else:
my_class = SmartcardConnection
with closing(my_class()) as sm_con:
atr = sm_con.getATR()
apdus = []
apdu = Apdu_splitter()
mitm = MitM()
while True:
cmd = poll_ep(dev, PHONE_INT)
if cmd is not None:
print("Int line ", HEX(cmd))
assert cmd[0] == ord('R')
# FIXME: restart card anyways?
# sm_con.reset_card()
print("Write atr: ", HEX(atr))
write_phone(dev, mitm.attack(ATR, (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)
gsmtap_send_apdu(apdu.buf)
apdu = Apdu_splitter()
apdu.split(c)
if apdu.state == apdu_states.APDU_S_FIN and apdu.pts_buf == [0xff, 0x00, 0xff]:
write_phone(dev, mitm.attack(PTS_BUF, array('B', apdu.pts_buf)))
continue;
if apdu.state == apdu_states.APDU_S_SW1:
if apdu.data is not None and len(apdu.data) == 0:
# FIXME: implement other ACK types
write_phone(dev, mitm.attack(APDU_INS, (array('B', [apdu.ins]))))
apdu.split(apdu.ins)
else:
sim_data = sm_con.send_receive_cmd(apdu.buf)
write_phone(dev, mitm.attack(SIM_DATA, (sim_data)))
for c in sim_data:
apdu.split(c)
if 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, mitm.attack(SIM_DATA, (sim_data)))
#apdu.state = apdu_states.APDU_S_SW1
for c in sim_data:
apdu.split(c)

View File

@@ -1,46 +0,0 @@
#!/usr/bin/env python
import array
from constants import *
# Address book entries
name = 'deine mudda'
phone = '0123456789abcdef'
def replace(data):
print(replace.last_req)
if data is None:
raise MITMReplaceError
else:
try:
if data[0] == 0xA0:
print("INS: ", hex(data[1]))
replace.last_req = data
return data
if data[0] == 0x3B:
return data
#print("*** Replace ATR")
#return array('B', NEW_ATR)
elif data[0] == 0x9F:
return data
# print("*** Replace return val")
# return array('B', [0x60, 0x00])
elif replace.last_req[1:5] == array('B', [0xB2, 0x01, 0x04, 0x1A]): # phone book request
print("*** Replace phone book")
# return array('B', [0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xff, 0xff, 0xff, 0xff, 0x09, 0x81, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xff, 0xff, 0xff, 0xff, 0x90, 0x00])
resp = map(ord, name) + ([0xff]*(12-len(name))) + [len(name) + 1] + [0x81]
for x in range(1,len(phone)/2+1):
list.append(resp, int(phone[x*2-2:2*x:], 16))
resp += ([0xff]*(replace.last_req[4]-len(resp))) + [0x90, 0x00]
return array('B', resp)
except ValueError:
print("*** Value error! ")
return data
replace.last_req = array('B')
if __name__ == '__main__':
print("Replacing PHONE_BOOK_REQ", PHONE_BOOK_REQ, "with", replace(PHONE_BOOK_REQ))
print("Replacing PHONE_BOOK_RESP", PHONE_BOOK_RESP, "with", replace(PHONE_BOOK_RESP))