Important!

Blog moved to https://blog.apdu.fr/

I moved my blog from https://ludovicrousseau.blogspot.com/ to https://blog.apdu.fr/ . Why? I wanted to move away from Blogger (owne...

Showing posts with label sim. Show all posts
Showing posts with label sim. Show all posts

Wednesday, February 24, 2021

Writing a SIM card phone book in Python

In the previous article "Reading a SIM card phone book in Python" I presented a program to read the phone book from a SIM card. I will now present the writing part.

 

Source code

The source code is in 2 parts: usim.py and usim_write.py files.

usim.py is the exact same file as in the previous article.

usim_write.py is:

#!/usr/bin/env python3

from smartcard.util import toBytes, padd
import random
import usim


def get_name():
    # List of firstnames from https://www.data.gouv.fr/fr/datasets/liste-de-prenoms/
    with open(random.choice(['f', 'm'])) as fd:
        lines = list(map(str.strip, fd.readlines()))
    return " ".join([random.choice(lines), random.choice(lines),
                    random.choice(lines)])


def get_number():
    numbers = "0123456789"
    phone = list()
    phone.append(random.choice(numbers) + random.choice(numbers))
    phone.append(random.choice(numbers) + random.choice(numbers))
    phone.append(random.choice(numbers) + random.choice(numbers))
    phone.append(random.choice(numbers) + random.choice(numbers))
    phone.append(random.choice(numbers) + random.choice(numbers))
    return " ".join(phone)


def new_record(size):
    # size-14 characters for the name
    name = get_name()[0:size-14]
    phone = get_number()
    print("name:", name)
    print("phone:", phone)
    record = padd(list(map(ord, name)), size-14) \
        + padd(toBytes("06 A1 " + phone), 14)
    return record


def usim_write(reader_nb):
    # Select the EF ADN
    (size, connection) = usim.usim(reader_nb)

    for nbr in range(1, 250):
        record = new_record(size)
        #  Update record
        header = [0xA0, 0xDC]
        record_idx = nbr
        cmd = header + [record_idx, 0x04, size] + record
        data, sw1, sw2 = connection.transmit(cmd)
        if (sw1, sw2) != (0x90, 0x00):
            return


if __name__ == "__main__":
    import sys
    if 2 == len(sys.argv):
        reader_nb = int(sys.argv[1])
    else:
        reader_nb = 0
    usim_write(reader_nb)


Comments

I wanted to have reasonable names and phone numbers in my phone book. So I generate names by randomly selecting 3 first names from 2 lists: the 50 first (by frequency of use) male first names in French stored in the m file, and the 50 first female first names in French stored in the f file. I got the data from https://www.data.gouv.fr/fr/datasets/liste-de-prenoms/. The original list also contains first names from other languages.

The first 10 lines of m are:

Pierre
Juste
Julien
Olivier
Henri
Jacques
Philippe
Nicolas
Aime
Antoine
[...]

The first 10 lines of f are:

Marie
Victoire
Claire
Marine
Reine
Virginie
Vienne
Solange
Jolie
Marguerite
[...]

For the phone number I just select a random 10-digits number.

Maybe the entries I created are non functional in a real phone. First check it works for you if you want to reuse this code. Also if you plan to reuse my source code you must read "My blog source code license" first.


Output

$ ./usim_write.py 
Available readers:
- Gemalto PC Twin Reader
Using: Gemalto PC Twin Reader
connecting to Gemalto PC Twin Reader
Select MF
> A0 A4 00 00 02 3F 00
<  [] 9F 22
Select DF Telecom
> A0 A4 00 00 02 7F 10
<  [] 9F 22
Select EF ADN
> A0 A4 00 00 02 6F 3A
<  [] 9F 0F
Get Response
> A0 C0 00 00 0F
< 00 00 21 34 6F 3A 04 00 11 FF 22 01 02 01 22 90 00
name: Juliette Claire Fran
phone: 50 47 00 17 44
> A0 DC 01 04 22 4A 75 6C 69 65 74 74 65 20 43 6C 61 69 72 65 20 46 72 61 6E 06 A1 50 47 00 17 44 FF FF FF FF FF FF FF
<  [] 90 00
name: Luc Nicolas Regis
phone: 83 46 67 10 73
> A0 DC 02 04 22 4C 75 63 20 4E 69 63 6F 6C 61 73 20 52 65 67 69 73 FF FF FF 06 A1 83 46 67 10 73 FF FF FF FF FF FF FF
<  [] 90 00
name: Julien Jeremie Serge
phone: 89 07 17 20 07
> A0 DC 03 04 22 4A 75 6C 69 65 6E 20 4A 65 72 65 6D 69 65 20 53 65 72 67 65 06 A1 89 07 17 20 07 FF FF FF FF FF FF FF
<  [] 90 00
[...]

The output is truncated. I do not want to include all the 255 phone numbers.

If I use usim_read.py (with debug disabled) I get:

$ ./usim_read.py 
Available readers:
- Gemalto PC Twin Reader
Using: Gemalto PC Twin Reader
Select MF
Select DF Telecom
Select EF ADN
Get Response
1: Name: Juliette Claire Fra, phone: 0574007144
2: Name: Luc Nicolas Regis.., phone: 3864760137
3: Name: Julien Jeremie Serg, phone: 9870710270
[...]

Note that the phone numbers are reversed by group of 2 digits. 50 47 00 17 44 becomes 0574007144.


Conclusion

It is as easy to write than to read a SIM phone book.

My goal here was to be able to write "realistic" phone book entries so that the usim_read.py has "real" data to read and display.

usim_read.py will be used again in the next episode.

Monday, February 22, 2021

Reading a SIM card phone book in Python

I already wrote a SIM phone book dumper program in 2004. This first version was in Perl and was presented in "SIM card phone book listing".

You can also find more advanced tools in articles with the SIM label, like cardpeek, monosim or PSSI.

I now present a version in Python using the PySCard wrapper

 

Source code

The source code is in 2 parts: usim.py and usim_read.py files.

usim.py is:

#!/usr/bin/env python3

from smartcard.System import readers
from smartcard.util import toBytes
from smartcard.CardConnectionObserver import ConsoleCardConnectionObserver

debug = True

def usim(reader_nb):
    # get all the available readers
    r = readers()
    print("Available readers:")
    for reader in r:
        print("-", reader)

    reader = r[reader_nb]
    print("Using:", reader)

    connection = reader.createConnection()
    if debug:
        observer = ConsoleCardConnectionObserver()
        connection.addObserver(observer)
    connection.connect()

    SELECT = "A0 A4 00 00 02 "
    GET_RESPONSE = "A0 C0 00 00 "

    # Select MF
    print("Select MF")
    data, sw1, sw2 = connection.transmit(toBytes(SELECT + "3F 00"))
    if sw1 != 0x9F:
        raise(Exception("Error"))

    # Select DF Telecom
    print("Select DF Telecom")
    data, sw1, sw2 = connection.transmit(toBytes(SELECT + "7F 10"))
    if sw1 != 0x9F:
        raise(Exception("Error"))

    # Select EF ADN
    print("Select EF ADN")
    data, sw1, sw2 = connection.transmit(toBytes(SELECT + "6F 3A"))
    if (sw1, sw2) != (0x9F, 0x0F):
        raise(Exception("Error"))

    # Get Response
    print("Get Response")
    data, sw1, sw2 = connection.transmit(toBytes(GET_RESPONSE) + [sw2])
    if (sw1, sw2) != (0x90, 0x00):
        raise(Exception("Error"))

    size = data[-1]

    pin = None
    if pin:
        print(pin)
        pin = list(map(ord, pin))
        padd(pin, 8)

        # Verify CHV
        VERIFY = "A0 20 00 01 08"
        cmd = toBytes(VERIFY) + pin
        data, sw1, sw2 = connection.transmit(cmd)
        if (sw1, sw2) != (0x90, 0x00):
            raise(Exception("Wrong PIN:" + pin))

    return size, connection


if __name__ == "__main__":
    usim(0)

usim_read.py is:

#!/usr/bin/env python3

from smartcard.util import toBytes, toASCIIString
import usim


def decode_record(record):
    """
    decode_record(toBytes("43 75 73 74 6F 6D 65 72 20 43 61 72 65 FF 06 A1 80 00 07 70 00 FF FF FF FF FF FF FF"))
    >> ['Customer Care', '0800700700']
    """
    X = len(record) - 14
    name = toASCIIString(record[0:X - 1]).replace("ΓΏ", "")
    # number of bytes for the phone number
    tel_size = record[X]
    phone = record[X + 2:X + tel_size + 1]

    decoded = ""
    for n in phone:
        hex = "%02X" % n
        high = hex[0]
        low = hex[1]
        decoded += low + high
    # if the number of digits is odd we suppress the padding
    if decoded[-1] == "F":
        decoded = decoded[:-1]
    phone = decoded

    return name, phone


def usim_read(reader_nb):
    # Select the EF ADN
    (size, connection) = usim.usim(reader_nb)

    for nbr in range(1, 250):
        #  Read record
        header = [0xA0, 0xB2]
        record_idx = nbr
        cmd = header + [record_idx, 0x04, size]
        data, sw1, sw2 = connection.transmit(cmd)
        if (sw1, sw2) != (0x90, 0x00):
            return

        name, phone = decode_record(data)
        if name != "":
            print(f"{record_idx}: Name: {name}, phone: {phone}")


if __name__ == "__main__":
    import sys
    if 2 == len(sys.argv):
        reader_nb = int(sys.argv[1])
    else:
        reader_nb = 0
    usim_read(reader_nb)


Comments

The debug is enabled. So you can see the communication between the application and the card.
You ned to change only one line to remove the APDU log if needed. 

The phone book record size is not fixed for all the SIM cards. The record size is returned in the last byte of the GET RESPONSE command after the SELECT EF (Elementary File) ADN (Abbreviated dialling numbers).

You can get more details about the EF ADN and the record coding in the document ETSI TS 131 102 V16.6.0 (2021-01) chapter "4.4.2.3 EF_ADN (Abbreviated dialling numbers)". It is important to note that ETSI (European Telecommunications Standards Institute) standards are public and free.

By default the first PC/SC reader is used. But you can select another reader by passing a number as argument to the program. We will use this feature later.

No PIN is defined and verified. I am using a sysmocom sysmoUSIM-SJS1 card. This card has the user PIN disabled by default.
You can enable PIN verification by defining a PIN in usim.py. The code is already present.

USIM (Universal Subscriber Identity Module) is a new application introduced for GSM version 3 (3G) to replace/improve the SIM (subscriber identity/identification) application. The code should work the same with a SIM card or a USIM card (but untested).

Output

$ ./usim_read.py 
Available readers:
- Gemalto PC Twin Reader
Using: Gemalto PC Twin Reader
connecting to Gemalto PC Twin Reader
Select MF
> A0 A4 00 00 02 3F 00
<  [] 9F 22
Select DF Telecom
> A0 A4 00 00 02 7F 10
<  [] 9F 22
Select EF ADN
> A0 A4 00 00 02 6F 3A
<  [] 9F 0F
Get Response
> A0 C0 00 00 0F
< 00 00 21 34 6F 3A 04 00 11 FF 22 01 02 01 22 90 00
> A0 B2 01 04 22
< 4C 61 75 72 65 20 46 72 61 6E E7 6F 69 73 65 20 59 76 6F 6E 06 A1 24 66 85 10 22 FF FF FF FF FF FF FF 90 00
1: Name: Laure Francoise Yvo, phone: 4266580122
> A0 B2 02 04 22
< 4C 75 63 69 65 6E 6E 65 20 48 65 6C 65 6E 65 20 4C 75 63 69 06 A1 76 45 65 28 77 FF FF FF FF FF FF FF 90 00
2: Name: Lucienne Helene Luc, phone: 6754568277
> A0 B2 03 04 22
< 55 72 62 61 69 6E 20 47 69 6C 6C 65 73 20 4A 75 73 74 65 FF 06 A1 80 38 74 16 54 FF FF FF FF FF FF FF 90 00
3: Name: Urbain Gilles Juste, phone: 0883476145
> A0 B2 04 04 22
< 4A 65 72 6F 6D 65 20 50 61 73 63 61 6C 20 46 65 72 6E 61 6E 06 A1 80 53 42 10 86 FF FF FF FF FF FF FF 90 00
4: Name: Jerome Pascal Ferna, phone: 0835240168
[...]

The output is truncated. I do not want to include all the 255 phone numbers. 

Note that the names and numbers are random. More on that later.


Conclusion

It is easy to dump the phone book from a SIM card.

The SIM phone book is very limited (no birthday, no email address). The real phone book is, in general, in the phone itself and synchronised using CardDav with a server like Nextcloud.

Sunday, October 18, 2020

sysmoOCTSIM: 8 slots reader

Sysmocom designed and sells a smart card reader with 8 slots for SIM sized cards (2FF form factor). It is the sysmoOCTSIM

sysmoOCTSIM


 

I received such a reader a few days ago (thanks Harald W.). In my case the reader has a nice aluminium casing to protect the electronic.

I added the reader in my list at: sysmocom_sysmoOCTSIM.

 

8 slots

The reader has 8 slots. From the CCID USB descriptor:

  bMaxSlotIndex: 0x07

The index starts at 0 so a maximum of 7 indicates 8 slots.

 

And it declares that it can support 8 slots busy at the same time.

  bMaxCCIDBusySlots: 8

So it is possible to use the 8 slots at the same time.

This device is the only one to have 8 slots in my list: https://ccid.apdu.fr/select_readers/?bMaxSlotIndex=7

You can also display the reader list sorted by bMaxSlotIndex field to easily see the other readers that have more than 1 slot.

 

Free Software Firmware

The reader firmware is free software (or open source if you prefer this denomination). The license is GNU GPL 2 or a later version.

The git repository is https://git.osmocom.org/osmo-ccid-firmware/
The bug tracker is https://osmocom.org/projects/osmo-ccid-firmware

The only other free software CCID firmware I know of is Tian Tian Xiang Shang used in the GnuK project (An Implementation of USB Cryptographic Token for GnuPG).


CCID driver limitation

My CCID driver does support multi-slots readers since version 0.9.2 released in 2004.

But the driver is limited because it does not support using the slots at the same time, even if the reader declares it supports it.

pcsc-lite has support for simultaneous multi-slot. But the driver tells pcsc-lite that simultaneous multi-slot is not supported. See this code: https://salsa.debian.org/rousseau/CCID/-/blob/master/src/ifdhandler.c#L490

Of course I tried to modify the code of the CCID driver to tell pcsc-lite that simultaneous multi-slot can be used. But then the driver is confused by mixed USB frames. I then remembered why this support was disabled.

 

Improvement

Adding support of simultaneous multi-slots is possible. That will require some work on the CCID driver.

If you want or plan to use such a reader with pcsc-lite on GNU/Linux or another Unix system then contact me so we can discuss what you can do.


Conclusion

I sometimes receive requests about configurations with a lot of smart card readers. Using an 8 slots reader can be part of the solution. This reader requires the use of only one USB port and has its own power supply unit.

The reader firmware is Free Software and I like that. It can only be a good point in the selection of a smart card reader.

Wednesday, May 1, 2013

cardpeek now available as a Debian package


The nice cardpeek software I presented in "cardpeek: A tool to read the contents of smartcards" is now available as the cardpeek Debian package. You do not need to install lua and rebuild the application yourself anymore.

cardpeek is a graphical application to read EMV, SIM and other types of smart cards.

Friday, October 26, 2012

cardpeek: A tool to read the contents of smartcards

A few days ago I discovered a nice tool: cardpeek.






Project

The project is hosted at http://code.google.com/p/cardpeek/.
It is Free Software and uses the GNU GPL v3 licence.

From the project web site:
Cardpeek is a Linux/Windows tool to read the contents of ISO7816 smartcards. It features a GTK GUI to represent card data is a tree view, and is extendable with a scripting language (LUA).

The goal of this project is to allow smartcard owners to be better informed about what type of personal information is stored in these devices.

The tool currently reads the contents of :
  • EMV cards, including NFC ones.
  • Navigo public transport cards (partially supports MOBIB as well)
  • The French health card "Vitale 2"
  • Electronic/Biometric passports in BAC security mode.

It can also read the following cards with limited interpretation of data:
  • Some Mifare cards (such as the Thalys card);
  • Moneo, the French electronic purse;
  • GSM SIM cards.

More info on the Wiki here: http://code.google.com/p/cardpeek/wiki/Main

Installation

It is easy to install under Debian GNU/Linux. You may need to install some dependencies related to the lua language. The program is written in C and lua. The parts sending smart card commands are lua scripts. I do not yet have lua in my list of languages for PC/SC.

You may be unable to run the ./configure script. I already reported this problem. run autoreconf -vis to get correct symlinks.

Examples

EMV

I tried with an EMV card.

The application gives a lot of information. For example you have access to the card transaction records.
In this example I payed 48.11€ on the August 30th of 2012. This transaction was to fil the tank with gasoline but the card do not store information about the merchant.

Navigo Pass

I do not have a Navigo Pass myself so I reused the screen copy from the cardpeek project navigo page.

From the project:
The "calypso" script included in cardpeek can read the content of Navigo cards used in Paris. It provides enhanced "event log" analysis notably with subway/train station names, as illustrated in the screenshot above. It has been successfully tested on Navigo DΓ©couverte, Navigo and Navigo IntΓ©grale cards.

SIM

The support is SIM card is indicated as beta but does work quiet well.

For example you can dump the phone book stored in your SIM card.

I guess it is in beta mode because not all the fields are parsed and displayed in a human readable format.

Conclusion

Cardpeek is a very nice tool to explore many common kinds of smart cards. It is tech savvy oriented.

Tuesday, April 26, 2011

Monosim: SIM card phone book listing (part 3)

In my article SIM card phone book listing of November 2010 a reader left a comment about the existence of the Monosim project.

" what is monosim ?
14-06-2007 18.20
...is a simple application that can be used to read, write, update, delete and backup your sim card contacts. It open and save also some format files to manage your contacts also in a text files. To connect monosim to your smartcard you need use a standard PCSC smartcard reader as towitoko, acs, athena, blutronics, etc. "

The monosim project is from Armando Basile and uses the GNU GPL v2 license. The project started in 2007. The latest version 1.5.2 is from July 2009.

Installation

The installation is quiet easy on a Debian system. The documentation is enough.

Just use the clasical:
$ ./configure
$ make

If a dependency is missing install it and go to the previous step.

Use

$ mono monosim/bin/Release/monosim.exe 





Monosim is the most user friendly and usable application I found:
  • The application is using a GUI (and not just text like PSSI).
  • The application allows to edit the SIM card, not just dump it content. It is possible to same the phone book in a text file and copy-paste between the SIM and the file.

Technical side

Monosim uses the PC/SC API using its own C# wrapper also written by Armando Basile. Maybe because many PCSC C# wrapper where did not exists in 2007 when the monosim project was started.

After writing a phone book to my SIM the program now always crashes when reading the SIM. I filed a bug. Maybe you will have more luck with your own SIM :-)

Conclusion

Monosim is a nice project. It may help you manage your phone books.

Thursday, November 11, 2010

PSSI: SIM card phone book listing (part 2)

Just a week after my post about a missing SIM card explorer in free software I discover in a the French MISC magazine article "Python Simple Smartcard Interpreter" that such a project exists.


PSSI: Python Simple Smartcard Interpreter


The project is hosted at http://code.google.com/p/pssi/ and uses GNU GPLv3 licence.
" Python script that provides an abstract layer for smartcard reading. Thanks to it, it is possible to read a smartcard by simply adding its structure in the form of a plugin, without taking care of the communication layer. The tool comes with several plugins, namely SIM, EMV, and NAVIGO. "
The project is quiet new. The project was created 30 July 2010 on code.google.com and the first commit occured on 19 Sept 2010. No stable/numbered release is available.

Plugins


The software is not just for SIM cards but is generic and uses plugins.

SIM

This plugin displays a lot of information about the SIM:
  • Telecom provider
  • Phone book
  • SMS

EMV

This plugin also displays a lot of information about the bank card:

Applications on the card



 ATR                         : 3B 65 00 00 66 04 6C 90 00
 Content                    
    Applications List          
       ====   1   ====
          ====   1   ====
             Application information    
                EMV Application information
                   Application ID              : a0 00 00 00 42 10 10 
                   Application name            : CB
                   Application priority        : 1
          ====   2   ====
             Application information    
                EMV Application information
                   Application ID              : a0 00 00 00 03 10 10 
                   Application name            : VISA
                   Application priority        : 2

Card holder name


Application information    
   Track 2 data                : 49 78 38 00 XX XX XX XX YY YY YY YY 
   Cardholder                  : MR ROUSSEAU LUDOVIC       
   Track 1 discretionary data  : 329627000000000673000000

Card validity dates and card number


Application information    
   Validity beginning          : 01 / 09 / 08
   Validity end                : 30 / 09 / 10
   Card number                 : 49 78 38 00 XX XX XX XX 
   PAN sequence number         : 4

The card number has been obscured by me. Even if the card expired a few months ago I think it is safer like this :-)

Transactions


====   1   ====
====   2   ====
   Amount          : 126.63          ()
   CID             : 64              (Cryptogram Information Data)
   Country         : FRANCE          (Country where the terminal is located)
   Currency        : Euro            ()
   Date            : 18 / 09 / 10    ()
   Type            : Payment         ()
====   3   ====
   Amount          : 36.80           ()
   CID             : 64              (Cryptogram Information Data)
   Country         : FRANCE          (Country where the terminal is located)
   Currency        : Euro            ()
   Date            : 31 / 08 / 10    ()
   Type            : Payment         ()
====   4   ====
   Amount          : 202.60          ()
   CID             : 64              (Cryptogram Information Data)
   Country         : FRANCE          (Country where the terminal is located)
   Currency        : Euro            ()
   Date            : 25 / 08 / 10    ()
   Type            : Payment         ()


NAVIGO

Navigo is the smart card used by the RATP in Paris public transport system. I do not have such a card so could not use this plugin.

ccid-utils

Another project to dump an EMV card is ccid-utils but this project did not work with my French bank card so I thought my card was not EMV compliant. But I was wrong since PSSI works great with this card.

Another problem with ccid-utils is that even if the program uses Python the core of the project uses C and directly talks to a CCID reader instead of using the PC/SC API through Pyscard. ccid-utils is also very limited regarding the CCID readers it supports.

Conclusion

PSSI is much more than a SIM card explorer. It also works for EMV and Navigo cards. The display of information is nice. The code is Python only so I had no problem using it on Mac OS X. I think I will continue playing with the software and maybe implement other features.


Flattr this

Wednesday, November 3, 2010

SIM card phone book listing

During the Debian minconf Paris 2010 I was asked for a program to use a SIM card.

I do not know any program to correctly manage a SIM card in free software on Unix (but I have not really search for it).

SIM explorer v3.0

In 2004 I wrote a simple Perl program to dump the phone book of a SIM card using the PC/SC Perl wrapper. The program is available on my web site.

The program is very rude and only displays the phone book. No way to edit the phone book.

Conclusion

I am surprised to see so little interest in the area of SIM/USIM cards. The market penetration of GSM was already above 100% in 22 European markets in 2006. So I guess every smart card hacker also has one GSM/3G phone. So we do not lack developers.

Note: I do not have a GSM/3G/smart phone myself :-)


Flattr this