mirror of
https://gitea.osmocom.org/sim-card/simtrace2.git
synced 2026-03-18 22:38:32 +03:00
Compare commits
4 Commits
0.7.0
...
christina/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a5debfec4 | ||
|
|
557e287feb | ||
|
|
899348ebbe | ||
|
|
442dc27bc9 |
@@ -2,6 +2,7 @@
|
|||||||
* ATMEL Microcontroller Software Support
|
* ATMEL Microcontroller Software Support
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
* Copyright (c) 2009, Atmel Corporation
|
* Copyright (c) 2009, Atmel Corporation
|
||||||
|
* Copyright (c) 2014, Christina Quast
|
||||||
*
|
*
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -57,7 +58,6 @@ static const Pin pinsBus[] = {PINS_BUS_DEFAULT};
|
|||||||
static const Pin pinsPower[] = {PWR_PINS};
|
static const Pin pinsPower[] = {PWR_PINS};
|
||||||
/** ISO7816 RST pin */
|
/** ISO7816 RST pin */
|
||||||
static const Pin pinIso7816RstMC = PIN_ISO7816_RSTMC;
|
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};
|
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 )
|
static void ISR_PioSmartCard( const Pin *pPin )
|
||||||
{
|
{
|
||||||
/* FIXME: why is pinSmartCard.pio->PIO_ISR the wrong number?
|
/* Check current level on pin */
|
||||||
printf("+++++ Trying to check for pending interrupts (PIO ISR: 0x%X)\n\r", pinSmartCard.pio->PIO_ISR);
|
/* The interrupt is already erased on read from the PIO_ISR (PIO Interrupt
|
||||||
printf("+++++ Mask: 0x%X\n\r", pinSmartCard.mask);
|
* Status Register) by the calling higher level interrupt handler
|
||||||
Output:
|
*/
|
||||||
+++++ Trying to check for pending interrupts (PIO ISR: 0x400)) = 1<<10
|
if ( PIO_Get( &pinSmartCard ) == 0 )
|
||||||
+++++ 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 */
|
CCID_Insertion();
|
||||||
if ( PIO_Get( &pinSmartCard ) == 0 )
|
}
|
||||||
{
|
else
|
||||||
sim_inserted = 1;
|
{
|
||||||
printf( "-I- Smartcard inserted\n\r" ) ;
|
CCID_Removal();
|
||||||
CCID_Insertion();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sim_inserted = 0;
|
|
||||||
printf( "-I- Smartcard removed\n\r" ) ;
|
|
||||||
CCID_Removal();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,10 +148,10 @@ void CCID_init( void )
|
|||||||
/* Decode ATR and print it */
|
/* Decode ATR and print it */
|
||||||
ISO7816_Decode_ATR( pAtr ) ;
|
ISO7816_Decode_ATR( pAtr ) ;
|
||||||
|
|
||||||
// FIXME. what if smcard is not inserted?
|
|
||||||
if(PIO_Get(&pinSmartCard) == 0) {
|
if(PIO_Get(&pinSmartCard) == 0) {
|
||||||
printf("SIM card inserted\n\r");
|
|
||||||
CCID_Insertion();
|
CCID_Insertion();
|
||||||
|
} else {
|
||||||
|
CCID_Removal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,98 +1,49 @@
|
|||||||
import usb.core
|
#!/usr/bin/env python
|
||||||
import usb.util
|
|
||||||
import array
|
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 constants import *
|
||||||
from apdu_split import Apdu_splitter, apdu_states
|
|
||||||
|
|
||||||
from replace import replace
|
|
||||||
|
|
||||||
def pattern_match(inpt):
|
# Address book entries
|
||||||
print("Matching inpt", inpt)
|
name = 'deine mudda'
|
||||||
if (inpt == ATR_SYSMOCOM1) or (inpt == ATR_STRANGE_SIM):
|
phone = '0123456789abcdef'
|
||||||
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):
|
states = {ATR, PTS_BUF, APDU_INS, SIM_DATA}
|
||||||
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):
|
class MitM:
|
||||||
print("WR: ", HEX(resp))
|
def attack(self, state, data):
|
||||||
dev.write(PHONE_WR, resp, 10)
|
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 data[0] == 0x3B:
|
||||||
if sim_emul == True:
|
return data
|
||||||
my_class = SmartCardEmulator
|
#print("*** Replace ATR")
|
||||||
else:
|
#return array('B', NEW_ATR)
|
||||||
my_class = SmartcardConnection
|
elif data[0] == 0x9F:
|
||||||
with closing(my_class()) as sm_con:
|
return data
|
||||||
atr = sm_con.getATR()
|
# 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 = []
|
replace.last_req = array('B')
|
||||||
apdu = Apdu_splitter()
|
|
||||||
|
|
||||||
while True:
|
if __name__ == '__main__':
|
||||||
cmd = poll_ep(dev, PHONE_INT)
|
print("Replacing PHONE_BOOK_REQ", PHONE_BOOK_REQ, "with", replace(PHONE_BOOK_REQ))
|
||||||
if cmd is not None:
|
print("Replacing PHONE_BOOK_RESP", PHONE_BOOK_RESP, "with", replace(PHONE_BOOK_RESP))
|
||||||
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)
|
|
||||||
|
|||||||
96
usb_application/mitm_io.py
Executable file
96
usb_application/mitm_io.py
Executable 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)
|
||||||
@@ -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))
|
|
||||||
Reference in New Issue
Block a user