Wiki

Version 6 (hans, 10/23/2013 09:39 pm)

1 1 pd0x
h1. Bazaar Wiki
2 1 pd0x
3 3 hans
* [[Auditing Existing APKs]]
4 4 hans
* [[Bootstrapping Trust]]
5 4 hans
* [[Local Data Transfer]]
6 5 hans
* [[Trusted Intent Interaction]]
7 6 hans
* [[Signing the Local APK Index]]
8 3 hans
9 1 pd0x
p. Rough notes being transformed from a research journal to a more finely honed state.
10 1 pd0x
11 1 pd0x
h2. Kerplapp P.O.C
12 1 pd0x
13 1 pd0x
* *Kerplapp* - dropping apps onto droids.
14 1 pd0x
* In-progress code dumped to "a Github branch":https://github.com/binaryparadox/Kerplapp/tree/speculative
15 1 pd0x
16 1 pd0x
h2. F-droid Notes
17 1 pd0x
18 1 pd0x
* Results of looking at the F-Droid model for app delivery, specifically from a security audit angle.
19 1 pd0x
20 1 pd0x
h3. Overview
21 1 pd0x
22 1 pd0x
* How does F-Droid Work?
23 1 pd0x
24 1 pd0x
h3. Server
25 1 pd0x
26 1 pd0x
* Simple design that requires only a static HTTP(S) server.
27 1 pd0x
* Repos can be either so called "binary repos" or built from source
28 1 pd0x
** Binary repos host pre-built APKs (the Guardian Project repo is one such binary repo)
29 1 pd0x
** Source repos build APKs from source, signing all apps with a unique-per-pkg randomly generated signing key
30 1 pd0x
* Quickly stand up an F-droid repo dir with:
31 1 pd0x
<pre>
32 1 pd0x
cd /repo/dir; python -m http.server 
33 1 pd0x
</pre>
34 1 pd0x
* Metadata contained in index.xml
35 1 pd0x
** Signed repos also have a index.jar (detail later)
36 1 pd0x
** Hierarchy of repo -> app -> apk
37 1 pd0x
** Create a signer repo out of an unsigned repo with:
38 1 pd0x
<pre>
39 1 pd0x
jar cf index.jar index.xml
40 1 pd0x
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore mytest.keystore index.jar mykeyalias
41 1 pd0x
</pre>
42 1 pd0x
** If an index.jar is present the signed index.xml located within the JAR should be considered authoritative
43 1 pd0x
** The index.xml is loaded on first-add of the repository, if it defines a public key attribute for the repository subsequent repository requests will use index.jar pinned to the public key (TOFU).
44 1 pd0x
* APK Signing for from-source repos has issues:
45 1 pd0x
** When a new pkg is seen and there isn't a key in the keystore for the pkg (more on that follows) a new key must be generated and put in the keystore
46 1 pd0x
** Keygen defaults are good, RSA2048
47 1 pd0x
** Key alias is auto generated by taking the MD5 of the pkg string and truncating it
48 1 pd0x
*** Decreases resilience of the hash
49 1 pd0x
*** Thankfully relies on second preimage resistance of MD5 to find a collision with another pkg string
50 1 pd0x
**** Should still be redesigned, MD5 has been demonstrated broken for realistic first pre-image attacks in the SSL/X509 space.
51 1 pd0x
*** If you could find a colliding pkg string you could have the source code for your app built and signed with the private key of another app in the same repo, allowing you to utilize the shareduserid feature of Android to access the data of the other app.
52 1 pd0x
* Server relies on HTTPS for transport security
53 1 pd0x
** Should pin certificates, does not
54 2 pd0x
* Due to the way the index.xml metadata is signed, replay and freeze attacks are possible.
55 2 pd0x
** An adversary can archive the index.jar and matching APKs from the signed repo across several updates/releases.
56 2 pd0x
** On a subsequent MITM they can replace the current signed index.jar with a previous version. The signature on the metadata will verify and the APKs can be replaced with the version that matched the old index.jar.
57 2 pd0x
** This attack allows an adversary to perform a 'freeze' attack (i.e. keep all clients at a fixed repository state, regardless of updates)
58 2 pd0x
** This attack also allows an adversary to pick an exact moment in history to freeze clients at. This gives the adversary the flexibility to decide which version of apps 'first install' clients get (choosing an old version of an apk only works on first install clients as we assume anyone running a version newer than the frozen app at install time can't be forced to downgrade their installation due to Android update semantics).
59 1 pd0x
60 1 pd0x
h3. Client
61 1 pd0x
62 1 pd0x
* Clients add repositories by URL
63 1 pd0x
** Index.xml is fetched first, used to TOFU a pubkey for the index.jar
64 1 pd0x
*** No technical reason why the index.xml must exist. Perhaps facilitates in-browser viewing, but an attacker can replace index.xml without knowing the signing key, meaning it shouldn't be used to make decisions about the repo in the presence of a index.jar
65 1 pd0x
* APKs are subject to normal Android code signing policy
66 1 pd0x
** *MUST* be signed
67 1 pd0x
** TOFU, first install the pkg is associated with the certs used to sign it
68 1 pd0x
** Subsequent updates to the pkg must be signed with exact same set of certs
69 1 pd0x
* APK hashes and the first signature on the APK are included in the index.xml metadata for the app. Client app verifies that the hash of the binary matches, and that the hash of the first signature on the APK matches. Note: F-Droid only processes single certificates for signed APKs. This seems to be an assumption based on the F-droid build process signing all pkgs with one unique randomly generated signing certificate. A so called "binary" repo could have apps that are signed with multiple certificates, only the first is included in the index.xml and authenticated by clients
70 1 pd0x
** This allows a (rather pointless) attack in which an adversary can add their signature to applications from the repo in a MITM attack. If they MITM the first install, the APK will install as the first certificate matches the one in the index.xml and the second signature is ignored. Subsequent updates from the un-MITM'd repo are unable to be installed as they lack the 2nd signature and break the Android code signing policy. If the client had previously installed the single-signed app, the adversaries MITM'd double signed copy won't install. An adversary in a persistent MITM role could repeat this process for every APK on the wire, preventing timely updates.