Wiki

Version 2 (pd0x, 09/26/2013 02:50 am)

1 1 pd0x
h1. Bazaar Wiki
2 1 pd0x
3 1 pd0x
p. Rough notes being transformed from a research journal to a more finely honed state.
4 1 pd0x
5 1 pd0x
h2. Kerplapp P.O.C
6 1 pd0x
7 1 pd0x
* *Kerplapp* - dropping apps onto droids.
8 1 pd0x
* In-progress code dumped to "a Github branch":https://github.com/binaryparadox/Kerplapp/tree/speculative
9 1 pd0x
10 1 pd0x
h2. F-droid Notes
11 1 pd0x
12 1 pd0x
* Results of looking at the F-Droid model for app delivery, specifically from a security audit angle.
13 1 pd0x
14 1 pd0x
h3. Overview
15 1 pd0x
16 1 pd0x
* How does F-Droid Work?
17 1 pd0x
18 1 pd0x
h3. Server
19 1 pd0x
20 1 pd0x
* Simple design that requires only a static HTTP(S) server.
21 1 pd0x
* Repos can be either so called "binary repos" or built from source
22 1 pd0x
** Binary repos host pre-built APKs (the Guardian Project repo is one such binary repo)
23 1 pd0x
** Source repos build APKs from source, signing all apps with a unique-per-pkg randomly generated signing key
24 1 pd0x
* Quickly stand up an F-droid repo dir with:
25 1 pd0x
<pre>
26 1 pd0x
cd /repo/dir; python -m http.server 
27 1 pd0x
</pre>
28 1 pd0x
* Metadata contained in index.xml
29 1 pd0x
** Signed repos also have a index.jar (detail later)
30 1 pd0x
** Hierarchy of repo -> app -> apk
31 1 pd0x
** Create a signer repo out of an unsigned repo with:
32 1 pd0x
<pre>
33 1 pd0x
jar cf index.jar index.xml
34 1 pd0x
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore mytest.keystore index.jar mykeyalias
35 1 pd0x
</pre>
36 1 pd0x
** If an index.jar is present the signed index.xml located within the JAR should be considered authoritative
37 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).
38 1 pd0x
* APK Signing for from-source repos has issues:
39 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
40 1 pd0x
** Keygen defaults are good, RSA2048
41 1 pd0x
** Key alias is auto generated by taking the MD5 of the pkg string and truncating it
42 1 pd0x
*** Decreases resilience of the hash
43 1 pd0x
*** Thankfully relies on second preimage resistance of MD5 to find a collision with another pkg string
44 1 pd0x
**** Should still be redesigned, MD5 has been demonstrated broken for realistic first pre-image attacks in the SSL/X509 space.
45 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.
46 1 pd0x
* Server relies on HTTPS for transport security
47 1 pd0x
** Should pin certificates, does not
48 2 pd0x
* Due to the way the index.xml metadata is signed, replay and freeze attacks are possible.
49 2 pd0x
** An adversary can archive the index.jar and matching APKs from the signed repo across several updates/releases.
50 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.
51 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)
52 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).
53 1 pd0x
54 1 pd0x
h3. Client
55 1 pd0x
56 1 pd0x
* Clients add repositories by URL
57 1 pd0x
** Index.xml is fetched first, used to TOFU a pubkey for the index.jar
58 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
59 1 pd0x
* APKs are subject to normal Android code signing policy
60 1 pd0x
** *MUST* be signed
61 1 pd0x
** TOFU, first install the pkg is associated with the certs used to sign it
62 1 pd0x
** Subsequent updates to the pkg must be signed with exact same set of certs
63 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
64 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.