The advent of cross-platform development frameworks such as Apache Cordova breathed new life into the old slogan of „Write once, run anywhere“ then invented by Sun Microsystems.
Unfortunately, such cross-platform comfort comes at a price—reduced tamper resistance on the mobile device.
Of course, this is a known phenomenon. But awareness may still be lacking, especially among managers which assume that their developers can build high risk applications with a low-budget.
When developing an mobile app with Apache Cordova the content of the distributed app bundle will look like the following:
|_ XXX.app |_ Frameworks |_ www |_ assets |_ build |_ 0.js |_ 1.js |_ ... |_ main.js |_ plugins |_ cordova.js |_ corodva_plugins.js |_ manifest.json |_ service-worker.js |_ index.html |_ ... |_ config.xml |_ ...
Fortunately I discovered an alternative method, that proved to work on several apps (affected apps will not be disclosed here). When going back to the previous directory listing, showing the content of the mobile apps bundle, next to all the .js files there is also a file called config.xml that can be seen. This file must be present in every Apache Cordova app. It is created during an early stage of the development process and extended if needed. It provides information about the app and specifies e.g.the plugins that are used.
Let’s take a look at the following exemplary extract from such a config.xml file:
[…] <feature name=„Diagnostic“> <param name=„ios-package“ value=„Diagnostic“ /> <param name=„onload“ value=„true“ /> </feature> <feature name=„SSLCertificateChecker“> <param name=„ios-package“ value=„SSLCertificateChecker“ /> </feature> <feature name=„AppCenterShared“> <param name=„ios-package“ value=„AppCenterSharedPlugin“ /> <param name=„onload“ value=„true“ /> </feature> […]
As you can see in this specific app an ios-package called SSLCertificateChecker is included. This plugin is used to verify the identity of the corresponding backend by checking which certificate it presents. It will detect a Machine-in-the-Middle (MitM) attack, even if the victim of the attack has installed and trusted the attacker’s CA certificate. This method is called SSL-Pinning and is a common counter measurement against MitM attacks.
The following example shows a method to stop the app from successfully loading this protection-feature:
[...] <feature name="Diagnostic"> <param name="ios-package" value="Diagnostic" /> <param name="onload" value="true" /> </feature> <!-- Do not use SSLCertificateChecker <feature name="SSLCertificateChecker"> <param name="ios-package" value="SSLCertificateChecker" /> </feature> --> <feature name="AppCenterShared"> <param name="ios-package" value="AppCenterSharedPlugin" /> <param name="onload" value="true" /> </feature> [...]
As can be seen in the previous example, the SSL-Pinning feature element has been commented-out (it can also be deleted). This patch can be either applied to a config.xml file present in an app’s bundle path (/var/containers/Bundle/Application/xxx-xxx-…/XXX.app/config.xml) on the iOS device itself or to a dumped .ipa file. If the modification takes place in the .ipa file, the contents must be re-signed with a valid Apple-Developer account before installation. The modification of the config.xml file will be loaded on the next app start.
If the patch of the config.xml file worked, the SSL-Pinning check will no longer be present and the network-traffic can e.g. be analyzed with a HTTP-proxy like BurpSuite or OWASP Zed Attack Proxy (ZAP).
This patch also proved to work on the counterpart for Android affected by this same issue. The config.xml file can be found in the .apk (./res/xml/config.xml).
I downloaded many mobile apps for financial and medical stuff from the iOS App Store. 25% of the Apps that were build upon Apache Cordova suffered from the described vulnerability.
In summary, if your adversary model includes a local attacker with elevated privileges, you should verify that all plugins were loaded successfully, if not the app should shut-down immediately.
As always, the real objective here is to move the goalpost out of reach of opportunists and increase the cost incurred by advanced malicious actors. An advanced adversary will eventually be able to surpass even Apple’s binary code signature checks.
Thanks @mtschirs for review and recommendations for this text.