Open E3V3A opened 10 years ago
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
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>.
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 requestSIMIO () 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
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:
"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)
I know now why I couldn't obtain Kc and BCCH. I have a USIM which has an other file structure. - 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.
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
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:
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:
The structure is something like this:
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:
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.
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.
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'.
'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.
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.
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.
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:
@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.
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):
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
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.