CellularPrivacy/Android-IMSI-Catcher-Detector

SIM card File System Access

E3V3A opened this issue · 65 comments

We need to be able to access the SIM card filesystem in order to work some magic while collecting relevant and necessary network data, not available from AOS API.

There may be many ways to read the file system on a SIM card. We have previously looked at the possibility of using the modem AT command interface, but we need other alternatives in those cases when baseband does not present an available and proper AT command interface. There are 3 other alternatives for reading the SIM EF / DF (Elemenary Files / Dedicated Files):

  1. Using the SIM Application Toolkit (STK aka CAT/SAT):
    https://android.googlesource.com/platform/packages/apps/Stk.git/+/master
  2. Similarly we should be able to open a RIL socket and use the RIL_REQUEST_SIM_IO to read/write to SIM EF.
  3. Using NFC ports: UrienNFC.PDF

The preferred way would probably be to incorporate (1) into our app, since it is already written in Java, but would need to circumvent the signatures in the same way as the ServiceMode "multiRIL-client" does its access. But (1) is risking to use non-available or OEM dependent STK.apks. Thus (2) might actually be a better choice, from simplicity point of view....

If you have any better or further insight, please let us know ASAP!

https://code.google.com/p/seek-for-android/wiki/SCAPI_modules_png
scapi_modules 1


References:
http://www.kandroid.org/online-pdk/guide/stk.html
http://osxr.org/android/source/packages/apps/Stk/src/com/android/stk/StkAppService.java?!v=android-4.4.4_r1
http://simhacks.github.io/android-emulator/#introduction
https://github.com/shadytel/sim-tools
https://code.google.com/p/seek-for-android/wiki/EmulatorExtension
https://code.google.com/p/seek-for-android/wiki/SecureFileManager
https://groups.google.com/forum/#!forum/seek-for-android

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

Perhaps users like: @chronomex , @illarionov , @andr3jx can be of help with this issue?

The approaches for extracting Kc and TMSI I found use AT+CSIM command to issue raw APDUs. We can't send APDUs to the SIM, because AT-commands like +CSIM are not supported in Android. It is necessary to modify the RIL to make them work, which is what Seek for Android does. SIM IO commands in android are issued using +CRSM, look into reference-ril.c code.

We can't use STK because we can't install JavaCard applets onto SIM without a key, which only the operator of the SIM has. You can only install an applet if you have a developer SIM where you know the key or if you have somehow the luck to get a SIM where you don't need the key.

So I looked into +CRSM command to see how it works and what it can do. We use this command already to obtain the ciphering indicator. I managed to read TMSI and LAI. For T3212 value I got 00.

Demo:

AT+CRSM=176,28542,0,0,11                * read EF-LOCI
+CRSM: 144,0,18055A1B05F5101030FF00
* decode at GSM 11.11, 10.3.17
* 18055A1B TMSI
* 05F5101030 LAI: 50501 4144
* FF current T3212 value (used on phase 1 devices only)
* 00 location update status

176 is for READ Binary, 28542 is decimal representation of EF fileid 0x6F7E. Other parameters should specify the record number and length of response.

This should read Kc from file 0x6F20, doesn't work on my SIM

AT+CRSM=176,28448,0,0,9

This should obtain BCCH info from file 0x6F74, also doesn't work on my SIM:

AT+CRSM=176,28532,0,0,16

When I issue this commands I get 106, 130 as reply.
I'm guessing you have a 3G sim. Refer to 'Table 10.14: Status byte
coding - wrong parameters' in ETSI 102.221. Literally 106 means '6A',
130 means '82' -> File Not Found.
- source

Identifier Name             Length
6FAD       Administrative   3
6F38       Service Table    4
6F07       IMSI             9
6F7B       Forbidden PLMN   12
6F7E       TMSI LAI         11
6F20       Kc, n            9
6F30       PLMN Selector    24
6F74       BCCH Information 16
6F78       Access Control   2

- source

AT+CRSM - Restricted SIM access

By using this command instead of Generic SIM Access +CSIM TE application has easier but more limited access to the SIM database. Set command transmits to the ME the SIM and its required parameters. ME handles internally all SIM-ME interface locking and file selection routines. As response to the command, ME sends the actual SIM information parameters and response data. ME error result code +CME ERROR may be returned when the command cannot be passed to the SIM, but failure in the execution of the command in the SIM is reported in and parameters. Coordination of command requests to SIM and the ones issued by GSM application inside the ME is implementation dependent. However the TE should be aware of the precedence of the GSM application commands to the TE commands.

AT+CRSM= <command> [,<fileid> [,<P1>,<P2>,<P3> [,<data>]]] 

Execution command transmits to the ME the SIM <command> and its 
required parameters. ME handles internally all SIM-ME interface locking and 
file selection routines. As response to the command, ME sends the actual 
SIM information parameters and response data. 
Parameters: 
<command> - command passed on by the ME to the SIM 
 176 - READ BINARY 
 178 - READ RECORD 
 192 - GET RESPONSE 
 214 - UPDATE BINARY 
 220 - UPDATE RECORD 
 242 - STATUS 

<fileid> - identifier of an elementary data file on SIM. Mandatory for every 
command except STATUS. 
<P1>,<P2>,<P3>  0..255 - parameter passed on by the ME to the SIM; they are 
mandatory for every command except GET 
RESPONSE and STATUS 

<data> - information to be read/written to the SIM (hexadecimal character 
format). 

The response of the command is in the format: 
+CRSM: <sw1>,<sw2>[,<response>] 
where: 
<sw1>,<sw2> - information from the SIM about the execution of the actual 
command either on successful or on failed execution. 
<response> - on a successful completion of the command previously 
issued it gives the requested data (hexadecimal character 
format). It’s not returned after a successful UPDATE BINARY 
or UPDATE RECORD command. 

Note: this command requires PIN authentication. However commands 
READ BINARY and READ RECORD can be issued before PIN 
authentication and if the SIM is blocked (after three failed PIN authentication 
attempts) to access the contents of the Elementary Files. 
Note: use only decimal numbers for parameters <command>, <fileid>, 
<P1>, <P2> and <P3>. 

References

CRSM
Examples for CRSM commands:
link1
link2
link3 - gtranslate
link4 - gtranslate
link5
link5
link6

No APDU support:
Supported STK RIL requests

Most RIL (radio interface layer) implementation for Android is relying on the +CRSM (restricted SIM access) AT command for providing SIM IO service. I was wondering if anyone knows a Android RIL implementation (and platform) that does use something other than +CRSM (like +CSIM, or some other type of raw SIM access). - source

you can see how requestSIM_IO () method reads sim card contacts, the android code uses the AT+CRSM command. AT commands can be seen in 3gpp 27.007 document - source translated

AT+CSIM Command: This one is the eldest and most well-known command: some phones allow you to use one of the standard-defined-but-not-always-implemented AT command AT+CSIM which let’s you to send raw APDUs (=”commands”) to the SIM-card via the modem. The amount of phones supporting this is very limited, according to some people older Siemens and Alcatel phones let you do this. Also older iPhone’s (3GS/3G/2G) let you do this if you are jailbroken (you need to install minicom from Cydia then connect to the device /dev/tty.debug). Newer iPhone’s don’t really let you do this, iPhone 5 owners – we all are out of luck. - source

Seek for Android:
Communication with the SIM card is provided by the baseband processor over AT commands (e.g. AT+CPIN, AT+CRSM) defined by 3GPP 27.007 specification or through an proprietary IPC interface.

In order to access card applications on the SIM card like any other Secure Element using the SmartcardAPI the baseband processor must provide some additional AT commands to enable transparent APDU exchange. For security reasons the APDU exchange must be limited to logical channels between the Android world and the card applications. The basic channel of the UICC must be reserved to the baseband processor.
The 3GPP TS 27.007 Technical Specification describes all required AT commands.

The AT+CSIM command transmits the command APDU to the SIM card, and returns the response APDU to the caller. This command allows exchange of any APDU, and should be handled with great care. The baseband must limit the range of command APDUs to the essential needs. - source

The RIL implementation on current Android phones do not support the required AT commands. For this reason the UICC patch includes an emulator extension (emulator.patch), which adds support for the required AT commands to the emulator's RIL implementation (reference-ril).

On real devices, the proprietary RIL library is very restrictive in terms of APDU access to the SIM or STK support and (normally) needs to be extended. However, on the emulator a patch can be applied in order to provide full SIM access through the host PC/SC system. - source
smartcard-api.patch - patch the Java sources for SmartCard API support - always required - source

Seek on Galaxy S2 / S3

Android RIL supported AT commands for SIM IO:
ril.h reference-ril.c
other reference-ril.c for seek( supports +CSIM)

Installing JavaCard applet onto SIM:

Loading Java Card Apps:

  • Cards support multiple applications
  • Applications are selected by their AID, These are officially allocated, but you can make one up
  • There is an app on the card that is the card manager – use it to load your app
  • The card manager is defined by the GlobalPlatform spec

"All apps are loaded and authorized by the Issuer Security Domain – in practice this means that you can’t load apps onto a card you didn’t issue yourself :(
On pure GlobalPlatform cards, the ISD is the default app on pre-personalized cards
Accessing it on our SIM cards is a lot harder"
- source (slide 20+)
JavaCard, Global Platform and SIM vulnerabilities
Global Platform Card Specifications
GlobalPlatform usage
STK applets
Installing JavaCard applet diagramm Optional authentication process

The AOSP version of Android does not provide a standard API to use the SIM card as a SE, but many vendors do, and as long as the device baseband and RIL support APDU exchange, one can be added by using the SEEK for Android patches. This allows to improve the security of Android apps by using the SIM as a secure element and both store sensitive data and implement critical functionality inside it. Commercial SIM do not allow for installing arbitrary user applications, but applets can be automatically loaded by the carrier using the SIM OTA mechanism and apps that take advantage of those applets can be distributed through regular channels, such as the Play Store. - source

"You just need a valid SIM with the correct PKCS#15 access control rules set for your applet, http://code.google.com/p/seek-for-android/wiki/AccessControlIntroduction or an Access Rule Application (ARA) that allows all apps to send APDUs to any AIDs."
-"Thanks. I guess we are going to see more device that work with UICC as more carrier-driven payment services are rolled out. Still, I don't think you will have access to the Card Manager keys for a 'real' operator SIM. What SIM are you using?"
-"I don't own any of those phones, but in order to store anything on the SE, you need the Card Manager key, which are not available for commercial devices." - source

Before loading an applet, you must to do an authentication with the Card Manager on Smartcard. In order to do the authentication, you have to know the card issuer keys. There is a limit number of attempt to authenticate. Usually this number is 10. If you exceed this limit, the card will block. Once you do a successfully authentication this limit is reset. - source

Vodafone UK do not allow any third party to load any SIM Toolkit applications to any of their SIM cards. This is also 1 for most Vodafone companies around the world but please check with your local company for confirmation. The main reasons for this are: 1) The SIM card belongs to Vodafone and is a secure device that is protecting our revenue. Applications on the SIM could compromise this security. [...] - source

Really strange for me but I did this without entering any key. - source

SIM cards for cellular networks: An introduction to SIM card application development - Uploading / Installing an applet to the SIM (page 34 / doc-page 41)

Java Card applet developer guide: Java Card Applet Installation (page 33)

Reprogrammable SIMs
Oracle Java Card SIM Development

SIM OTA attacks / key cracking:
link1
link2
link3
link4

I know now why I couldn't obtain Kc and BCCH. I have a USIM which has an other file structure.
tk-uicc-df-gsm-access
- source
Complete File Structure of USIM

I could obtain Kc using

AT+CRSM=176,20306,0,0,9

The file for CPBCCH is also present, but it needs additional parameters to read it.
Another interesting file which has BCCH info is EFnetpar (Network Parameters), it needs also more research to find out how to read it.

I have a USIM which has an other file structure.

Interesting stuff! Is there a way of detecting which type of SIM someone has? How do you issue those commands, @andr3jx? Via the AT Command Injector of AIMSICD, or through an ADB root shell?

@SecUpwN
It's a little more complicated. There can be multiple applications on the SIM (UICC) which have different file structures. USIM was developed for 3G networks.
"SIM cards" in developed countries are today usually UICCs containing at least a SIM and a USIM application. This configuration is necessary because older GSM only handsets are solely compatible with the SIM [application] and some UMTS security enhancements do rely on the USIM [application].
The USIM brought, among other things, security improvements like the mutual authentication and longer encryption keys and an improved address book.
- source
If the SIM is not too old it should have USIM support. I think it is possible to check EF_DIR for USIM presence.

tk-uicc-mf
SIM & UICC file structure (you can click in the diagram on different elements to learn more)

I simply used MTK engineer app to send commands and logcat to read the response. But we had already the discussions about how to send AT commands and I'm sure every Android RIL should have support for +CRSM command.

I went through EVAs post about the CRSM command. Reading the ciphering indicator works, but the command for enabling the ciphering indicator doesn't change anything. When I execute AT+CRSM=214,28589,0,0,3,"010001" for writing to the SIM, I get 105, 130. So the question is how to write to the SIM using +CRSM command.

EDIT: It is not possible to write / change EF-AD from outside. The reason is that the access condition for updating this file is ADM (Administrative). So we can't do this without having a special key, which only the operator has. The same problem as with installing javacard applets.

That's correct. You need a JavaCard (or whatever else they call them) and copy your original card to it, including keys etc. For this you need special SIM MiTM tools. This, however, is out far beyond what we're trying to do here. We only want to read the SIM files (already mentioned above).

@andr3jx You're using the MTK based modem, which are more properly corresponding to AT Command set 3GPP standards, therefore you have no problem reading EFs using +CRSM. However, on the Snapdragon MSM8974/8960/8930 modems, there seem to be something else going on. As already mentioned above, these are probably "blocked" in either AOS, RIL or in Modem. It is very unlikely they are blocked in modem, since one way of blocking is by using PIN2 as is indicated in the ril sources:

From comments in: ril.cpp Line: 696

* Callee expects const RIL_SIM_IO *
* Payload is:
* int32_t command
* int32_t fileid
* String path
* int32_t p1, p2, p3
* String data
* String pin2
* String aidPtr

and from ril_commands.h Line: 45

{RIL_REQUEST_SIM_IO, dispatchSIM_IO, responseSIM_IO},

But most Network Operator supplied SIMs doesn't come with a PIN2/PUK2 these days, so I simply don't have it, and is investigating how Qualcomm is dealing with EF reading.

For example, on my MSM8930 device:

# say at+cpin?
at+cpin?
+CPIN: READY
OK

# say at\$qcsimstat?
at$qcsimstat?
$QCSIMSTAT: 0,SIM INIT COMPLETED
OK

# say AT+CRSM=176,28542,0,0,11
AT+CRSM=176,28542,0,0,11
ERROR

# say at\$qcpinstat?
at$qcpinstat?
$QCPINSTAT: READY,READY,READY,READY,READY,READY,SIM PIN2
OK

# say at+qcpwd=?
at+qcpwd=?
+QCPWD: ("SC",8),("P2",8)
OK

# say at+cpwd=?
at+cpwd=?
+CPWD: ("AB",4),("AC",4),("AG",4),("AI",4),("AO",4),("IR",4),("OI",4),("OX",4),("SC",8),("P2",8)
OK

There we see that we need to supply PIN2 on item 7, and that SC (PIN1 change) and P2 (PIN2) are 8 characters long. (This need confirmation.) The items from the AT$QCPINSTAT command, sends to the ME the status of all PINs for all cards, like this:

    PH-SIM      - Phone Specific SIM PIN1
    PH-FSIM     - Lock phone to first SIM PIN
    PH-NET      - Network personalization PIN
    PH-NETSUB   - Network Subset personalization PIN
    PH-SP       - Service Provider personalization PIN
    PH-CORP     - Corporate personalization PIN
    SIM PIN2    - PIN2
  • You can't clone a SIM card to another with the keys. The SIM Card is performing security checks to prevent this.
  • It would be great to have a possibility to see which commands get send, when the phone wants to read from SIM. Have you tried injectord?
  • I see the problem with +CRSM. We need to find a way to send these SIM_IOs.

The thing with PIN2 is not a problem because PIN2 can be NULL.

typedef struct {
    int command;    /* one of the commands listed for TS 27.007 +CRSM*/
    int fileid;     /* EF id */
    char *path;     /* "pathid" from TS 27.007 +CRSM command.
                       Path is in hex asciii format eg "7f205f70"
                       Path must always be provided.
                     */
    int p1;
    int p2;
    int p3;
    char *data;     /* May be NULL*/
    char *pin2;     /* May be NULL*/
} RIL_SIM_IO_v5;

typedef struct {
    int command;    /* one of the commands listed for TS 27.007 +CRSM*/
    int fileid;     /* EF id */
    char *path;     /* "pathid" from TS 27.007 +CRSM command.
                       Path is in hex asciii format eg "7f205f70"
                       Path must always be provided.
                     */
    int p1;
    int p2;
    int p3;
    char *data;     /* May be NULL*/
    char *pin2;     /* May be NULL*/
    char *aidPtr;   /* AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. */
} RIL_SIM_IO_v6;

in ril.h, you have also this comment:

/**
 * RIL_REQUEST_SIM_IO
 *
 * Request SIM I/O operation.
 * This is similar to the TS 27.007 "restricted SIM" operation
 * where it assumes all of the EF selection will be done by the
 * callee.
 *
 * "data" is a const RIL_SIM_IO *
 * Please note that RIL_SIM_IO has a "PIN2" field which may be NULL,
 * or may specify a PIN2 for operations that require a PIN2 (eg
 * updating FDN records)
 *
 * "response" is a const RIL_SIM_IO_Response *
 *
 * Arguments and responses that are unused for certain
 * values of "command" should be ignored or set to NULL
 *
 * Valid errors:
 *  SUCCESS
 *  RADIO_NOT_AVAILABLE
 *  GENERIC_FAILURE
 *  SIM_PIN2
 *  SIM_PUK2
 */

Maybe I am missing something, but I don't see the need to implement this with AT commands or manual SIM IO. Android's telephony layer already has SIM file access, for example loadEFTransparent() issues the READ BINARY command with a file ID and size, as you are doing with AT commands. fetchSimRecords() reads several files this way.

It's probably not exposed to normal apps, but this app requires root, right? Seems like it should be easier to gain access to these code paths, than implementing modem-specific stuff for all the vendors. Once it gets down to the closed-source RIL libraries, they probably issue AT commands, but I don't see why you need to know how that works in order to use it from Java. Or have you tried these API's, and maybe access to the files you want is restricted by the RIL? Sorry if I'm not suggesting anything new, or this conversation is out of date.

Welcome @scintill! Thanks for your input. What you're seeing is a rather clueless and desperate development team, who's trying to figure out how to access the EF files mentioned below. We haven't even tried to use the internal functions, since we simply do not know how to use them properly. So this conversation is certainly not out of date.

Just to summarize. We would simply like to READ from any commercial SIM card, the following EF files:

Name id(hex) id(dec) Size(bytes) Our Use
EF-SST (EF_UST) 6F38 28472 allocated/activated SIM services (USIM Service Table)
EF-Kc 4F20 20256 DF / GSM-ACCESS Ciphering key
EF-Kc 6F20 28448 GSM Ciphering key
EF-BCCH 6F74 28532 BCCH (TS 44.018)
EF-FPLMN 6F7B 28539 n Forbidden PLMNs (FPLMN).
EF-LOCI 6F7E 28542 3+X TMSI, LAI
EF-AD 6FAD 28589 3+X Ciphering Indicator
EF-NETPAR 6FC4 28612 X >=46 GSM/FDD/TDD Cell + Neighbour Frequency Information + Scrambling code + BCCH

Any suggestions, guidance or help on how to do this would be extremely appreciated.

Ha, well I feel clueless too, as I've now realized how hard my idea would be to do. I'm pretty sure those objects are living in the com.android.phone process. It would be one thing to define some reflection wrappers to get ahold of otherwise-hidden classes, it's another to cross the process boundary and invoke stuff inside another VM. I think an Xposed module might allow us to inject some code into that process, but would you want to have that dependency? Something to think about.

Luckily, other options you've discussed seem feasible: the SEEK API, or injecting RIL_REQUEST_SIM_IO in the ril socket. I will start with SEEK, because CyanogenMod 11 is supposed to support SEEK and I have that. If it does work, it would probably be the most stable way to go, but it won't be supported on all devices. We could then try adding the RIL socket request method, or Xposed injection, as a fallback for devices without SEEK.

@scintill Yes, we just had an Xposed discussion. We like Xposed very much, but we are worried about this code dependence, and would like to avoid it if possible. In addition, we still don't understand their code or how to implement it in our case. In addition, we were also hoping to be able to run our App on stock firmware without root, in the future, and Xposed requires root.

Also, I think we're already hooking some internal stuff using OEM_HOOK_RAW, but I don't know to what extent this can be used for SIM EF access.

I've also been "looking" at trying to better understand how and if SEEK can be used. But so far no particular clarity or success. I'm trying to get some help on the SEEK for Android email list, but so far no breakthrough, and things are moving too slow.

What is strange with your original post, is that there is no reference in API's lower than 21, to use those calls, even if present in JB4.2.2, and somewhat explained here:

/**
 * This class is responsible for keeping all knowledge about
 * Universal Integrated Circuit Card (UICC), also know as SIM's,
 * in the system. It is also used as API to get appropriate
 * applications to pass them to phone and service trackers.
 *
 * UiccController is created with the call to make() function.
 * UiccController is a singleton and make() must only be called once
 * and throws an exception if called multiple times.
 *
 * Once created UiccController registers with RIL for "on" and "unsol_sim_status_changed"
 * notifications. When such notification arrives UiccController will call
 * getIccCardStatus (GET_SIM_STATUS). Based on the response of GET_SIM_STATUS
 * request appropriate tree of uicc objects will be created.
 *
 * Following is class diagram for uicc classes:
 *
 *                       UiccController
 *                            #
 *                            |
 *                        UiccCard
 *                          #   #
 *                          |   ------------------
 *                    UiccCardApplication    CatService
 *                      #            #
 *                      |            |
 *                 IccRecords    IccFileHandler
 *                 ^ ^ ^           ^ ^ ^ ^ ^
 *    SIMRecords---| | |           | | | | |---SIMFileHandler
 *    RuimRecords--- | |           | | | |----RuimFileHandler
 *    IsimUiccRecords--|           | | |-----UsimFileHandler
 *                                 | |------CsimFileHandler
 *                                 |----IsimFileHandler
 *
 * Legend: # stands for Composition
 *         ^ stands for Generalization
 *
 * See also {@link com.android.internal.telephony.IccCard}
 * and {@link com.android.internal.telephony.IccCardProxy}
 */

Yeah, I agree it's good to avoid requiring root or Xposed.

I see in your SEEK post that you apparently have its SmartcardService installed, so hopefully that's at least one other person who can test anything I manage to produce.

Right, those APIs are not part of the public API. We could use them with reflection or API .jar hacking, but it doesn't do a lot of good, since we eventually need the live RIL to actually do the SIM I/O anyway.

What I am working on now is copying these classes into AIMSICD, and implementing a minimal "RIL" to use SEEK's UiccTerminal.simIOExchange() to send the file-reading commands. The benefit of using the telephony classes is that they already handle the parsing, and a bit of structure for different types of SIMs. Perhaps once I get something working, I'll be able to strip down the telephony classes to only require what we need. I linked to CyanogenMod's SEEK -- I'm a bit uncertain if SIM I/O will be supported in all versions of SEEK, but I guess we'll find out.

API 21 is for Android 5 and it is good news to see that there is now a public API for transmitting APDUs.

@scintill Awesome! But what are you saying here?

Right, those APIs are not part of the public API. We could use them with reflection or API .jar hacking, but it doesn't do a lot of good, since we eventually need the live RIL to actually do the SIM I/O anyway.

From my logcat in that SEEK thread, it seem that something is indeed working but not finding something else...

 V/PerformanceTester( 7412): Open Logical Channel to Applet: d2 76 00 01 18 01 01
 I/SmartcardService( 1689): Binder_1Checking Access...
 W/AccessControl( 1689): -- Validating connection...
 D/AccessControl( 1689): Secure Element: SIM: UICC
 D/AccessControl( 1689): AID:  0xd2 0x76 0x00 0x01 0x18 0x01 0x01
 D/AccessControl( 1689): Hash: ... 0xc6 0xe2 0x90 0xec 0x76 0x58 0x5d 0xbf 0x11 0xa4
 W/AccessControl( 1689): - isConnectionAllowed...
 D/AccessControl( 1689): isConnectionAllowed ::
 W/AccessControl( 1689): openLogicalChannel Start
 D/PhoneInterfaceManager( 1211): [PhoneIntfMgr] response came
 E/UICCTerminal( 1689): lastError : 1
 E/AccessControl( 1689): openLogicalChannel exception: open channel failed
 W/AccessControl( 1689): GAC/PKCS#15 ADF not found!!
...

(logcat from running PerformanceTester.apk )

I've also tried running the OMAPIsuite.apk from SIMalliance. (But you need signup there, so you can get hundreds of of other documents.) That kind of works to some extent.

See:
OMAPI Spec
OMAPI Test Spec for Transport API
OMAPI Test App Coverage

For easy access you can download all of above, consisting of: OMAPIsuite.apk + applets (*.cap) + README + above documents. Please download and try this! We may learn something from it...

NOTE: Unless you have a developer SIM/SC you probably cannot upload the applets to your SIM.

I don't know why this should be relevant. Stock ROMs don't offer a SmartCard API so you can't communicate with the SIM card. Without patching Android source code for Smartcard API you won't be able to talk to the SIM card.

But what are you saying here?

Right, those APIs are not part of the public API...

I mean it's not as straightforward as I originally thought, because you can't simply re-use those objects in the app, since the RIL is in another process. I'm trying to adapt the classes to SEEK, though.

Stock ROMs don't offer a SmartCard API so you can't communicate with the SIM card.

I don't know how prevalent stock support is, but at least Galaxy S3 reportedly has this API in stock.

Right, according to this doc - slide 8 the API should be available on these devices, but the list could also just refer to NFC support, so not sure:

  • Acer: Liquid Express C6
  • Alcatel (TCL): Smart III-4
  • HTC: One X
  • LG: P940 (Prada)
  • Motorola: Droid RAZR (XT926)
  • Samsung: Galaxy S2, Galaxy S3, Galaxy S4
  • Sony: Xperia Z
  • ZTE: P728

I don't know how many percent of the android market these devices make up so not sure if it is worth it. Still I'm optimistic about Android 5's new API.

Ok, either I'm very confused here, or you are, but more likely all of us. :D

First, @andr3jx we're not doing any form of authentication, so that document is irrelevant for this issue. We're just trying to read from SIM card. That's it. Every phone obviously supports some kind of SIM card reading and access mechanisms. We just have to find out to what extent this has been standardized, and try to hook into it, or find out how RIL is communicating with it, and try to circumvent any restrictions. In addition we're trying to support from API 17 and up, so what is only available on "L" (API 21), is not so interesting at this point. All what they have done there, is making some of the already existing binary code available to the AOS API.

The SIMAlliance's Open Mobile API (OMAPI) seem to be the current and future way of UICC communication. So if you have a stock device, please try to install and run the app I posted and let me know what happens. It should go through an arsenal of ~100 tests and present the results. In addition the source code, used for each test is shown in the app. That app probably requires the device to use the SmartcardService:org.simalliance.openmobileapi.service. On my phone this arsenal seem to pass most tests, but not all, so something is working. (probably due to old OMAPI version.)

On my Samsung S4 mini (GT-I9195) I have the following SIM related packages:

Package Version Path
SIM Toolkit 4.2.2-I9195XXUBML4 com.android.stk
SmartcardManager 1.6 com.sec.smartcard.pinservice
SmartcardService 2.4.0 org.simalliance.openmobileapi.service

On my GT-I9100, AOSP KK4.4.2, this doesn't even install, and fails with:

W/ActivityManager ( 2346): No content provider found for permission revoke: file:///storage/sdcard0/OMAPISuite.apk
I/PackageManager  ( 2346): Copying native libraries to /data/app-lib/vmdl-793337515
E/PackageManager  ( 2346): Package org.simalliance.android.testenv requires unavailable shared library org.simalliance.openmobileapi; failing!
W/PackageManager  ( 2346): Package couldn't be installed in /data/app/org.simalliance.android.testenv-1.apk

Then trying SIM lock from settings (still on I9100), I find this in the logs:

I/am_restart_activity( 2346): [0,1103378688,108,com.android.settings/.IccLockSettings]
W/SharedPreferencesImpl( 2631): Attempt to read preferences file /data/data/com.android.settings/shared_prefs/com.android.settings_preferences.xml without permission

which show that its accessing ICC through settings, while the radio logcat indicates that most RIL logs are originating from the com.android.phone app, started by zygote.

So what I'm saying here, is that there must be a smarter way to do this than compiling AOS from sources, just to get SEEK to work, so we can read a damn simple EF card.

@scintill Yes! I've seen that post as well, look very promising. They provide code and explanation. In addition, some guy also post code on both SEEK and Stackexchange. And with the post explaining how to Accessing Smart Card File Structure, we should be able to write an idiot-proof PoC app that does, only one thing. For example, reading the EF-LOCI file. We can then use this to extend functionality on other models and phones using other standards. Finally implementing it into our app.

@E3V3A I know we don't do authentication but I searched for a list of devices which have Open Mobile API available, which they mention there because it enables communication with a Secure Element ( and SIM cards are Secure Elements). I don't have a device where the SmartCard Service is installed, so PerformenceTester.apk doesn't work and there is also no Open Mobile API available. I assume only a small number of devices offers them. If the device offers Open Mobile API then you can use it to communicate with the SIM card.
The "Accessing Smart Card File Structure"-Post is not relevant for us, because this code is platform independent. You can plugin a PC/SC reader and write on your PC Java programs which communicate with the SIM attached to the reader.

@E3V3A and @andr3jx, not sure if this helps us any, but have you seen the UICCTester by @PMTM?

First off, I posted some really rough code here (direct link to SIM I/O part), in the form of a patch to the app that tries to logcat out a file's contents. See the commit message at the top for rundown of what it does and needs to do. If you're familiar with Binder, or the "service" command-line app and its output, I could use your help. I suggest we keep discussion about that code on its commit page, to keep this thread clear.

Some good information here. Nice spotting the Android 5 API -- we could use it when it's available, but it would be nice to have fallbacks too.

So, I found that the OpenMobile service in CyanogenMod 11 is not built by default, and I couldn't get it to build when I enabled it. Seems to depend on some closed-source stuff that CM doesn't handle right now. However, stock Android 4.4.4 on Sony Xperia Z1 Compact has it.

I tried out the test apps. PerformanceTester app crashes with this:

E/AndroidRuntime( 9041): java.lang.OutOfMemoryError: java.lang.String[] of length 1935813253 exceeds the VM limit
E/AndroidRuntime( 9041):    at android.os.Parcel.createStringArray(Parcel.java:955)
E/AndroidRuntime( 9041):    at org.simalliance.openmobileapi.service.ISmartcardService$Stub$Proxy.getReaders(ISmartcardService.java:280)

A 1.8GB String?! I guess it's a mismatch between the version it was built for, and what I have. The service APK's version is 3.1.0.

The OMAPISuite seems to work, as well as it can. What I mean is, it seems to be written for certain smartcards that we don't necessarily have (for example, some tests try to connect to certain Application IDs [reference to apps running on the card] that seem to be test applications that won't be on our SIM cards). Some tests also fail with errors like this in logcat:

I/SmartcardService( 2652): No ARA applet found in: SIM1
V/SmartcardService ACE ARF( 2652): - Loading SIM1 rules...
V/ACE ARF EF_Dir( 2652): Analysing EF_DIR...
D/SmartcardService ACE ARF( 2652): SelectFile [1*32b]
D/SmartcardService ACE ARF( 2652): ReadRecord [1/32b]
I/SmartcardService ACE ARF( 2652): Cannot use ARF: cannot select PKCS#15 directory via EF Dir
E/SmartcardService ACE ARF( 2652): SIM1 rules not correctly initialized! Cannot select PKCS#15     directory via EF Dir
I/SmartcardService( 2652): Deny any access to:SIM1

I tracked that down to here, and the comment makes me believe this is more of a problem with my SIM than anything else, but I think all SIMs would have this problem, unless they are meant to also be used as a secure element, as mentioned. We can't really depend on that. Even then, it might not grant us access to the SIM's actual GSM application, which is what we want. Interestingly, this security limitation appears to be a later addition to the services, so maybe some of you have an older version that won't enforce it. You can try out the disabled OpenMobile code in my patch linked at the top.

Nice find on the UICCTester. It gives me the same access-denied error, though.

I just read my phone number from the SIM card with SIM I/O! New code here. Requires root and SEEK (but not OpenMobile service), and probably adjustment of the user ID that calls the service. I know the phone number isn't very exciting, but it was the easy test case, and I don't have more time tonight to try others. It should be fairly straightforward to read the other files now...

Unfortunately, I'm thinking root is an unavoidable requirement for reading these files, unless some devices allow access through the OpenMobile API, or someone figures out how my test of that was flawed (there's disabled code for it in my last commit.) Or maybe there are less-privileged vendor-specific ways.

There is no way to do this reliably, unless you are using a custom ROM and are running as system or some other privileged user. The OpenMobile API won't allow you to open a basic channel (it's reserved for the phone application), and even if you manage to open a logical channel you are subject to access control restrictions. The rules are encoded in the SIM, so you can't change them. You can only patch OpenMobile to ignore them, again back to custom ROM.

If you tried really hard, you could probably get a root daemon started on boot (ala SuperSU) and pipe commands to it via a local socket. But this would be a giant hack, probably device dependent also. Access to the daemon might be subject on SELinux restrictions on newer devices and be blocked though. If you tried even harder, you could write a privileged native Binder service (ala keystore) and access it through Binder. But that's basically installing a backdoor on your device, again back to custom ROM.

Not clear what the end goal is here, but even if you got reliable file read access, you still won't be able to read protected files.

@scintill

Both PerformanceTester and the OMAPIsuite relies on trying to install some accompanying applets (*.cap) on to the USIM card, for some of the tests. This will obviously fail on MNO provided SIM cards as we do not have the key to install to those. So don't expect all tests to pass, unless you have a developer JavaCard (or whatever they call them.)

The permission denied issue is lightly related to the issue above, and is almost the same problem as I had when trying to run PerformanceTester above. The common logcat error: GPAC/PKCS#15 ADF not found!! is from the Global Platform Access Control function, that is looking for some files in the DF PKCS-15 directory, which is not present on all SIM cards. So PKCS-15 is essentially a required SIM directory structure for using the SC features, as specified in the documents:

  1. Secure Element Access Control v1.1 | GPD_SPE_013
  2. PKCS #15 v1.1: Cryptographic Token Information Syntax Standard (With other versions here. )

The structure is something like this:

pkcs15_file_structure

MF (3F00)
|-EF DIR (2F00)                 --> reference DF PKCS-15
|
|-DF PKCS-15 (7F50)
  |-ODF (5031)                  --> reference DODF
  |-DODF (5207)                 --> reference EF ACMain
  |-EF ACMain (4200)            --> reference EF ACRules
  |-EF ACRules (4300)           --> reference EF ACConditions...
  |-EF ACConditions1 (4310)
  |-EF ACConditions2 (4311)
  |-EF ACConditions3 (4312)

And thanks to Daniel Alberts SEEK forum post you can create this structure yourself (on compatible developer cards.), in order to grant full APDU access for all applications on devices, modify the card in this way:

- update EF DIR with a PKCS#15 application in a new record
- create an ADF with the PKCS#15 AID: 
    A0 00 00 00 63 50 4B 43 53 2D 31 35

- create the ODF (5031) under the ADF with 64bytes length and update
  the content with :
    A7 06 30 04 04 02 50 32 
    - rest padded with FF

- create the EF 5032 in the same ADF with 64 bytes length put:
    A1 29 30 00 30 0F 0C 0D 53 45 45 4B 20 50 52 4F 46 49 4C 45 20 
    A1 14 30 12 06 0A 2A 86 48 86 FC 6B 81 48 01 01 30 04 04 02 43 
    00 
    - in the file (same padding)

- create the EF 4300 in the same ADF - 20 bytes with the content: 
    30 10 04 08 01 02 03 04 05 06 07 08 30 04 04 02 43 01

- create the EF 4301, 16bytes, with 30 08 82 00 30 04 04 02 43 12
- create the EF 4312, 16bytes, with 30 00 

(Provided only for reference, since this is overkill and OT for this project.)

Having root is one of our requirements. Trying your service call without doing anything on my I9195, will result in this:

u0_a202@MSM8960:home # service call phone 55 i32 28480 i32 178 i32 1 i32 4 i32 64 s16 3F007F10
Result: Parcel(
  0x00000000: ffffffff 00000022 006e004f 0079006c '...."...O.n.l.y.'
  0x00000010: 00530020 0061006d 00740072 00610063 ' .S.m.a.r.t.c.a.'
  0x00000020: 00640072 00410020 00490050 006d0020 'r.d. .A.P.I. .m.'
  0x00000030: 00790061 00610020 00630063 00730065 'a.y. .a.c.c.e.s.'
  0x00000040: 00200073 00490055 00430043 00000000 's. .U.I.C.C.....')

(I also tried by prefixing with su -cn u:r:platform_app:s0 -c "..." with same result.)

In regard to all this, it seems that a modified version of "SEEK adaptations in RIL for Galaxy S3" method may be the way to go. We're already using RIL_REQUEST_OEM_HOOK_RAW in our multi-client-ril adaptation in SamsungMulticlientRilExecutor.java and OemRilExecutor.java.

Sounds like we are on the same page about PKCS#15 stuff preventing the OpenMobile API from being useful to us. However, that doesn't rule out the SEEK telephony service call.

"Only Smartcard API may access the UICC" is expected if you're running it as an unprivileged user. You have to run it as the user that owns the OpenMobile service package. The good news is that it does no further access checks, so we circumvent the PKCS#15 stuff!

Can you test my latest code? It should work without modification on any device with root and the OpenMobile service, including CM11. I've tested on Xperia Z1 Compact with stock and CM11. I haven't had a chance to re-test on stock, but the technique was working, and if there's something wrong, it should just be a matter of tweaking the configuration-sniffing stuff.

Welcome @nelenkov! Thanks for bringing your knowledge and experience to our issue discussion. (For those of you who follow this thread, his blog piece and book chapter Using the SIM card as a secure element in Android is a must read, from "Android Security Internals".

Your write:

You can only patch OpenMobile to ignore them, again back to custom ROM.

Can you not patch this without custom ROMs?

...you could probably get a root daemon started on boot (ala SuperSU) and pipe commands to it via a local socket.

Well, if you already have SuperSU (as we assume), then why add another one? What would that daemon do?

Access to the daemon might be subject on SELinux restrictions on newer devices and be blocked though.

Another project of mine is looking into how to inject SELinux policies...(and Chainfire has already done that.)

...you could write a privileged native Binder service (ala keystore) and access it through Binder.

Is this similar to how Xposed does it?

Not clear what the end goal is here, but even if you got reliable file read access, you still won't be able to read protected files.

Which files are those? I doubt the files we're interested in are read protected.

The end goal is to get important and current cell/network/RF parameters from phone, that are not available elsewhere, like TMSI etc.

In regards to making our own daemon/service, I am considering embedding a permissive version of the OpenMobile service into the app. With root, we should be able to start it up under the user that the phone service's transmitIccSimIO() checks for. This would still depend on that call existing in the phone service, which I think is not a standard part of Android, though it should be there on devices that support the OpenMobile API.

The main motivation is that what I've got now, using the "service" command line utility, is kind of a horrific hack. Its output isn't meant to be parsed, so that could break, and it's annoying to invoke a new process for every SIM I/O. Dealing with a proper privileged service could be a lot of work though, so for now I'll probably hold off.

Another alternative, which should be more widely supported but more difficult, is injecting into the Java RIL process to hijack its SIM I/O routines. That has the advantage of not requiring SEEK, nor depending on vendor extensions. Hopefully they don't modify the Java RIL too much, or this would be brittle too.

@scintill
Everything is brittle these days, and the only ones breaking stuff is Google, so our code is never safe! That said, I think what you suggest above is just fine.

Also. What kind of work is required to make it privileged? Can you clarify what you mean with "inject" the java RIL process? (Any examples?)

@nelenkov I want to add that we already managed to read the SIM Card using AT+CRSM command, described in an older post. But we still haven't found a way how to send AT commands that works on many devices.

Well, part of the problem is, I don't know what would be required to launch the service from our app, running under a specific Linux user ID (which is required to get through the access check in the service call.) Maybe there will ultimately be a security restriction we can't get around.

To back up a bit, what I want to achieve is have a proper interface for passing the SIM I/O requests, because the weird byte-swapping I have to do to parse the parcel hex output is scary. It's a Binder service I'm calling, so pretty easy to access from Java, the issue with doing that from our app is just the user ID requirement. I started considering some way to spawn a little app that runs under the special user ID and proxies messages between us and the telephony service, then I realized: that's basically what the OpenMobile service does (but gets in the way with access checks), so why not re-use most of it?

Anyway, I think for now I'd rather just use this relatively simple hack that works (for me at least), so we can develop the idea and see what's possible with reading the files, then consider making it more robust later.

@scintill, I enjoy following your development on our project here. Feel free to create a pull request!

@SecUpwN Please do not add untested code. I've already tested above, and it breaks the rest of the app on my I9195 device. Like I said before:

...we should be able to write an idiot-proof PoC app that does, only one thing. For example, reading the EF-LOCI file. We can then use this to extend functionality on other models and phones using other standards. Finally implementing it into our app.

So let's try to move the relevant new code into a new app that does only that. This is what Illarionov did for the SamsungRilMulticlient scraper, that we then implemented. So let's try to create an "readsim.apk" that:

  1. Hit the button
  2. Read EF-LOCI
  3. Dump progress and results to screen and logcat.

That would make multi-device testing very easy and clear.

@scintill Please have another look at issue #27, in particular this post and links. And consider looking into how to use the OEM_HOOK stuff to get SIM access.

At the "end-of-the-day" we should have a couple of methods for reading the SIM's, depending on the device and support. For example, on MTK, we can use AT CoP (as Andre3xj can), on XMM (I9100/9300/Note etc) we can use the Multiclient, and on Qualcomms we should be able to use a modified Multiclient or OMAPI/SEEK code.

PMTM commented

Let me comment on the library, openmobileapi as specified by the Sim Alliance. As mentioned above it was part of seek project, thus available only in AOSP based Android distros. There are some phone manufacturers like samsung or sony that have included this library on production devices for various trials mostly payment and transport use cases. Unfortunately there is also UICC access control system in place to verify HASH of signer of the app is registered to access particular AID on sim card (see globalplatform device specification site). This code actually requires the HASH of cert signer of app on phone to be stored on UICC and verified by the System (java library controlling the open logical channel). Therefore better way to access secure store is actully to use HW backed secureElement i.e. PN65x on Nexus5 (http://nelenkov.blogspot.co.uk/2013/08/credential-storage-enhancements-android-43.html) via "AndroidKeyStore" as JCE provider. It can do RSA encryption and key gen on HSM/SE.

PMTM commented

There is one other way, use two phones and so called RSAP or SAP (https://developer.bluetooth.org/TechnologyOverview/Pages/SAP.aspx). It is used by GSM modules in cars to access GSM ALGO (2g or 3g) inside owners phone, while disabling the GSM inside the phone meanwhile. But in general an attempts to gain access to Ki or any other private information on UICC might be/is a viloation of UICC use policy set by operators. Other option is transfer of identity legaly. Such case could be solved by eSE (remote perso or swap perso using bootstrap perso) - long term of big fruit company. Could improve user experience but raises other issues.

Hello @PMTM, thanks for joining. However, we're still trying to understand what you and @nelenkov mean, when you say that "app" has to be signed and that files are "protected". To me that sound like you're talking about an SE applet, and I fail to see the connection of reading and running SE applets with just reading EF files (like LOCI, FPLMN etc.) on a MNO provided USIM? Are you saying those files are protected? If so, then it doesn't rhyme with either @andr3jx or @scintill 's recent progress of reading those files. Please clarify.

@E3V3A There are two basic ways to get privileged access on Android: [1] be signed with the platform certificate and [2] be a system app (i.e. reside on the system partition). You cannot generally fake a platform signature, so that leaves [us to use (2), by] installing stuff on the system partition. You can only do that reliably via an OTA package in recovery (like how SuperSU is installed), but this, of course, requires an unlocked bootloader. You cannot patch OpenMobile [apk] in place without invalidating the signature, so that leaves replacing the whole thing, which would change the package signature and might break some of the builtin vendor apps. If you don't care about this, you should be able to get your app working with a patched SmartcardService.apk installed via OTA. There might be differences in different devices though, so you have to account for that.

[3] The third way is to start a privileged service daemon on startup (like daemonsu). You will be able to specify the user the service runs as, so you can choose one that is allowed to connect to telephony and read the SIM.

You cannot inject SELinux polices without modifying the boot image, which is another can of worms. Once you do this, you are getting even closer to a custom ROM...

[E:V:As EDIT's in square brackets, for readability. Sorry, but we're all new to this.]

Read http://www.globalplatform.org/specificationform.asp?fid=7825 regarding access control/ARA

Also this code regarding the meaning of 'signature'.

https://code.google.com/p/seek-for-android/source/browse/trunk/src/smartcard-api/src/org/simalliance/openmobileapi/service/security/AccessController.java

'Signature' here means the signature/certificate of the app (APK) that is a client of the OpenMobile API. What the SmartCardService does is read the access rules from the SIM and compare the certificate of each client application with the one in the rules. That is why vendor apps work (because their signing certificate is referenced in the access rules, on the SIM), and 'homebrew' ones get access denied.

PMTM commented

When reading a file from UICC, you are actually talking to file serving app, which means you are selecting AID of that file serving app. Actually there are multiple aproaches to reach the UICC, AT commands is just one of them, but there are also pipes and binary commands doing the same depending on how the control channel to the UICC is established. PKCS#15 files that contain access control (old way) or ARA-C/M (trying to hide the file structure and extend it to merge model where Security domains might provide their sub ACLs). PKCS#15 contains besides Java SATSA, Android AC also Certs and keys - thus interesting for other uses. Thus some structures might be available without AC because those are used for AC itself (yes it is weird!) All that depends on how good design and modularization was done in the OS, actually user app should never get access to the files directly, unfortunately either rooting or poor design could cause to cause failure to those attempt to protect the UICC against malicious attacks. There is also one funny thing. It is called basic and logical channel. As the UICC aging technology tried to resurect itself the manufacturers tried to bring USB (2 additional pads - bottom ones when having UICC/smart card contact pads) to serve faster connection and ethernet over USB - search for supersim presentations - webserver on sim (SCWS - simtoolkit 2.0), also SWP aka use of UICC for CLF/NFC secure element is such attempt... but comming back to ...channels. The sim card has actually one ISO 7816 interface through which you can access its contents, it has no interrupt line towards host/card reader this notifications has to be pulled from the card (same as USB device/peripheral). But the ISO 7816 was enhanced with so called logical channel that extended the ability to select multiple applets on sim while running multiple OS applications (but still limited to few 3-16 depending on setup and card manufacturer). The worst message comes that applets cannot be usually selected twice. Thus as many things is handled through single applet even attempt to access such applet while being in use by GSM modem (auth algo) or so might cause either fail of both or fail of your app or unpredictable behavior... and at the end your data connection might break in such case. Safe way is to stop RIL in certain cases = drop connection and have full access to the UICC.

PMTM commented

To the how to sign an app:
Sign as usual but put the HASH of the cert into ARA/PKCS#15

to get current CERT has to put there use:

keytool -list -keystore $HOME/.android/debug.keystore -v -storepass android

then the line like:

SHA1: 11:ED:DB:7F:44:24:17:F0:7D:9F:92:8A:7E:E8:77:00:B9:28:1D:D9

lists the SHA1 which should land in android AC together with either wildcard or particular AID, optionally you could also replace the hash with wildcard but not sure whether any-hash to any-aid is generally supported.

PMTM commented

not always AT commands search for "/dev/qmi"...

@nelenkov
I've uploaded a bunch of SIM related GP documents HERE to download. (90 days and ~20 MB). I think the one you refer to is called: "GPD_SE_Access_Control_v1.1.pdf"?

and @PMTM:

not always AT commands search for "/dev/qmi"...

What does that mean? I think you're referring to the Qualcom QMI interface, and trying to use that to read USIM, but if we have that, then we don't need to read SIM, as all we need is present in that API. So yes, we're interested in looking into that very soon...

Ok, so apart from trying option (2) or (3) from Nikolay, it seems rather futile trying this, while other experiments seem to show some possibility...but very hard to manage.

So what would you suggest doing?

There is currently no portable way to do this. Two basic options:

  1. Low-level: bypass SmartCardService/TelephonyService and talk directly to the RIL/serial interface. Device-specific and probably not documented (standard AT commands may not work on all devices). That said, if you can cover the 2-3 major SoCs/manufacturers, you'll cover a lot of devices.
  2. High-level: go through the SmartCardService/TelephonyService. Those will manage the low-level details for you, so no need to implement/search for raw protocols. To go around access restrictions you have to install/run something with system privileges, or may monkey-patch using Xposed, etc. to short circuit the access control flow. Doing this with TelephonyService might be quite dangerous though, because it doesn't have a stable interface and vendors customize. SmartCardService is similar, but lower risk.

@nelenkov I've essentially written Option 2, targeting TelephonyService. See here. The short explanation is that I use the "service call phone ..." command line utility, run under the privileged UID (which is the only access check in this endpoint, in the implementations I've seen) with su, to call the telephony service, and scrape its output. This was the most straightforward way I could think to do a Binder call under another UID. It's messy, but it's pretty stable for me on a stock ROM or CyanogenMod 11. I don't think it's worked for anyone else, though, and I haven't gotten to the bottom of that yet... but I may abandon this method.

I'm now tinkering with using ddi to inject code into com.android.phone to add some kind of IPC mechanism that will allow us to remotely invoke SIM I/O and maybe other RIL stuff. This way could be really unstable, but it's fun to experiment with at least.

It seem that development on this topic has stopped completely. Perhaps we could have a status update from @andr3jx and @scintill, who was working on this? If not, perhaps @thomascannon could have some valuable knowledge about how to get this working?

In addition it seem that we may need the following permissions to be able to use the NFC device path to get to SE.

<uses-permission android:name="android.permission.NFC"/>
...
<service android:name=".MyOffHostApduService" android:exported="true"
         android:permission="android.permission.BIND_NFC_SERVICE">

and some more...to select AID.

I have a solution with ddi injecting into the com.android.phone process, code here (the repository is now mis-named, as the active code doesn't use SEEK.) It's been tested on 3-5 phones. As I recall, on one it silently fails injecting (logs show part of the process working, then no further logs and the SIM file reading doesn't work; I was stumped by this several weeks ago and haven't looked at it again.) I also have a report (and maybe seen for myself a time or two) that it doesn't work for the first time, but does if the test activity is re-launched. This may just be a timing issue, of not waiting long enough between injecting and trying to call the new service. I am thinking I will have the injected code signal back to the application when it's ready, which could help.

In theory it could work on all pre-Lollipop devices (I assume ART breaks ddi) with root, but may need adjustment on some versions, or for vendors that change the telephony code (such as Mediatek, which is accounted for in the current code.) So, we've got something working, but it needs more polishing, and I haven't really had the time or insight to do it yet.

If we get AT commands working robustly on most devices, we might implement SIM file reading on top of that instead. The code is structured to be adaptable to different methods of SIM I/O.

Joey, Was that on my phone? Did you try it on other Samsungs? (Which?)

If we get AT commands working robustly on most devices, we might implement SIM file reading on top of that instead. The code is structured to be adaptable to different methods of SIM I/O.

We will use both (and more). We'll have to use whatever is available on the device AIMSICD is running on, and for whatever stuff we want to look at.

I currently do not have anything technical to add yet beyond the great work and opinions expressed here. But wanted to add some other thoughts.

It is hard now to access the SIM directly, and will surely get harder. The SIM is sometimes used as a secure element for things like 2FA precisely because it is hard for malware to access it, so it is in the user's interest for Google to protect access to it.

So I think a lot of energy will be burned trying to find and maintain workarounds for a menagerie of handsets. Another option is to select one or a few devices that will be fully researched and developed for, and every year or so select the next device in the upgrade path. Selection criteria would highly rate any device which is more easily hackable, such as MTK based.

The energy saved could be better spent developing new features and making a more complete solution. One downside is that the target device might not be your daily driver, and while it can operate as a standalone solution, you might need to discover if your daily driver is being specifically targeted with IMSI selection.

@E3V3A can you please share the GlobalPlatformOrg.7z again?

can you please share the GlobalPlatformOrg.7z again?

May I ask you if you're just interested in that .zip, or actually helping with this Issue, @rena2019? I've seen your Twitter account and noticed you're from a town near me. Herzlich Willkommen im Projekt! ;-)

E3V3A commented

can you please share the GlobalPlatformOrg.7z again?

@rena2019, we've already got SIM access, so we just need someone to do the code. So those doc's are not gonna help you and you can download them yourself at their website. (They've been updated.)

@SecUpwN I'm interested in all the mobile stuff. yesterday I read about Open Moblie API and found this site. @E3V3A Are all documents inside your zip also available free for download from GP site?

WoW, I haven't understand anything up there, how can get a course to read this???

What was that??

hi i want to work with file systems of sim cards ,how i can access to som files like ef imsi that i need the adm access wich key is ralated to this ??please help me thanks

do you have any resource to i read about keys in sim and usim

Is it possible to mount the sim card filesystem so that android can write to it as if it was an external card?
I think this could be achieved with collaboration of a sim manufacturer.

Hello there,
I didn't find any app ( Android IMSI-Catcher Detector)in f-droid or github or aptoid can you provide me??
Thanks

we were trying to extract the Kc from the SIM card on an Android A72 - A7 using minicom on ubuntu 20.04 connected with the charger cable.

  • A7 wasn't running CISM nor CRSM and after searching it doesn't support them
    *Not sure because the CMEE is giving OK but it is not working (errors doesn't show any number or string )
  • A72 is working properly with CRSM but not CISM is not supported, so we went with CRSM
    we tried fileid of SIM file structure and we got not found
    AT+CRSM=176,28448,0,0,9 +CRSM: 106,130,""
    then, we came across your answer and we made some tries using both EFkc fileid and EFkcGPRS and we are getting the same error
    AT+CRSM=176,20306,0,0,9 +CME ERROR: memory failure
    Any guesses why this is happening ?

@hayabaq Have you tried AT+CRSM=176,20256,0,0,9 ? I also found a table with an overview of AT commands here

@andr3jx yes we got the same error
here is the file structure that we were referring to. we tested multiple files with USIM file structure and all of them are working fine except for the GSM-ACCESS and its subs
we still wondering what would be the cause of the failure

@hayabaq Maybe you can try an other command instead of READ BINARY. Read Binary requires "transparent" structure of file, not sure if this can be a problem here. Try READ RECORD / GET STATUS / GET RESPONSE to understand what is going on. Also check this reply.

Another possibility might be that the file has beed deactivated for whatever reason. In this case only the SELECT command will work and you should be able to use ACTIVATE / REHABILITATE command to activate the file.

You can also try to run the GSM algorithm which provides Kc as response.