--000000000000285b7106168fb465 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Mon, Apr 8, 2024 at 3:15=E2=80=AFPM Fay Stegerman wrote= : > Hi! > > This is published here: https://github.com/obfusk/fdroid-fakesigner-poc. > > I've attached the PoC and patch and included the text from the README > below. > > - Fay > > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D > > # F-Droid Fake Signer PoC > > PoC for fdroidserver AllowedAPKSigningKeys certificate pinning bypass. > > ## Background > > We started looking into Android APK Signing Block oddities at the request > of > F-Droid [1] on 2021-08-25; we opened F-Droid issue "APK Signing Block > considerations" [2] on 2022-10-19. No action was taken as a result. > > We published the "Android APK Signing Block Payload PoC" [3] to the > Reproducible Builds mailing list [4] on 2023-01-31. > > > But the Android APK Signature Scheme v2/v3 actually allows embedding > > arbitrary data (or code) in the signing block, meaning that two APKs wi= th > > the exact same valid signature -- though not a bit-by-bit identical > > signing block -- can behave differently. > > Jason Donenfeld reported "Potential security hazard: > apk_signer_fingerprint() looks at certs in reverse order that Android > checks > them" [5] on 2023-05-05; no action was taken to fix this bug. > > > However, there's a discrepancy between how these certificates are > > extracted and how Android actually implements signature checks. [...] > > Notice how [the google flowchart [6]] checks v3, then v2, and then v1. > > Yet the [F-Droid] code above looks at v1, then v2, and then v3, in > reverse > > order. So v1 could have a bogus signer that some versions of Android > never > > even look at, yet fdroid makes a security decision based on it. Yikes! > > Also, it's worth noting that apk_signer_fingerprint() also does not > bother > > validating that the signatures are correct. > > Andreas Itzchak Rehberg (IzzyOnDroid) reported about "BLOBs in APK signin= g > blocks" in "Ramping up security: additional APK checks are in place with > the > IzzyOnDroid repo" [7] on 2024-03-25. The accompanying German article > "Android-Apps auf dem Seziertisch: Eine vertiefte Betrachtung" [8] points > out that we noticed that that apksigner and androguard handle duplicate > signing blocks rather differently: the former only sees the first, the > latter only the last, which allows all kinds of shenanigans. > > ## Observations > > We observed that embedding a v1 (JAR) signature file in an APK with minSd= k > >=3D 24 will be ignored by Android/apksigner, which only checks v2/v3 in = that > case. However, since fdroidserver checks v1 first, regardless of minSdk, > and does not verify the signature, it will accept a "fake" certificate an= d > see an incorrect certificate fingerprint. > > We also realised that the above mentioned discrepancy between apksigner a= nd > androguard (which fdroidserver uses to extract the v2/v3 certificates) ca= n > be abused here as well. Simply copying the v2/v3 signature from a > different > APK and appending it to the APK Signing Block will not affect apksigner's > verification, but androguard, and thus also fdroidserver, will see only t= he > second block. Again, the signature is not verified, a "fake" certificate > accepted, and an incorrect fingerprint seen. > > As a result, it is trivial to bypass the AllowedAPKSigningKeys certificat= e > pinning, as we can make fdroidserver see whatever certificate we want > instead of the one Android/apksigner does. Note that we don't need a val= id > signature for the APK (we really only need a copy of the DER certificate, > though having another APK signed with the certificate we want to use make= s > things easy). > > ## PoC > > NB: you currently need the signing branch of apksigtool [9]. > > NB: the "fake" signer shown here is from the official F-Droid client (its > APK has a v1+v2+v3 signature), the one apksigner sees is randomly generat= ed > by make-key.sh; the app.apk used for testing had minSdk 26 and a v2 > signature only. Using APKs with other signature scheme combinations is > certainly possible, but might require adjusting the PoC code accordingly. > > ``` > $ ./make-key.sh # generates a dummy key > $ python3 make-poc-v1.py # uses app.apk (needs minSdk >=3D 24) as base= , > adds fake.apk .RSA > $ python3 fdroid.py # verifies and has fake.apk as signer > according to F-Droid > True > 43238d512c1e5eb2d6569f4a3afbf5523418b82e0a3ed1552770abb9a9c9ccab > $ python3 make-poc-v2.py # uses app.apk as base, adds signing block > from fake.apk > $ python3 fdroid.py # verifies and has fake.apk as signer > according to F-Droid > True > 43238d512c1e5eb2d6569f4a3afbf5523418b82e0a3ed1552770abb9a9c9ccab > $ apksigner verify -v --print-certs poc.apk | grep -E '^Verified > using|Signer #1 certificate (DN|SHA-256)' > Verified using v1 scheme (JAR signing): false > Verified using v2 scheme (APK Signature Scheme v2): true > Verified using v3 scheme (APK Signature Scheme v3): true > Verified using v4 scheme (APK Signature Scheme v4): false > Signer #1 certificate DN: CN=3Doops > Signer #1 certificate SHA-256 digest: > 029df1354735e81eb97c9bbef2185c8ead3bc78ae874c03a6e96e1e1435ac519 > ``` > > ``` > $ mkdir fakesigner > $ cd fakesigner > $ fdroid init -d oops --repo-keyalias fakesigner > $ mkdir metadata > $ printf 'Name: MyApp\nAllowedAPKSigningKeys: > 43238d512c1e5eb2d6569f4a3afbf5523418b82e0a3ed1552770abb9a9c9ccab\n' > > metadata/some.app.id.yml > $ cp /path/to/poc.apk repo/ > $ fdroid update > $ jq '.packages[].versions[].manifest.signer.sha256' < repo/index-v2.json > [ > "43238d512c1e5eb2d6569f4a3afbf5523418b82e0a3ed1552770abb9a9c9ccab" > ] > ``` > > ## Patch > > The fdroidserver.patch changes the order so it matches Android's v3 befor= e > v2 before v1, and monkey-patches androguard to see the first block instea= d > of the last one if there are duplicates. This is still likely to be > incomplete, but prevents the known bypasses described here. > > ## References > > * [1] https://salsa.debian.org/reproducible-builds/diffoscope/-/issues/24= 6 > * [2] https://gitlab.com/fdroid/fdroidserver/-/issues/1056 > * [3] https://github.com/obfusk/sigblock-code-poc > * [4] > https://lists.reproducible-builds.org/pipermail/rb-general/2023-January/0= 02825.html > * [5] https://gitlab.com/fdroid/fdroidserver/-/issues/1128 > * [6] https://source.android.com/docs/security/features/apksigning/v3 > * [7] https://android.izzysoft.de/articles/named/iod-scan-apkchecks > * [8] > https://www.kuketz-blog.de/android-apps-auf-dem-seziertisch-eine-vertieft= e-betrachtung/ > * [9] https://github.com/obfusk/apksigtool > > ## Links > > * https://github.com/obfusk/apksigcopier ASOP has been aware their APK signing lacked semantic authentication for decades. This is from the defunct and now removed android-security-discuss Google Group. It is a reply of mine on a thread the discusses APK signing from 2012: > You should also look at the threat model. [Partially] signed APKs only > provide the ability to update a previously published APK. The APK can > be updated *IFF* it was previously published under the same signing > key. In essence, the threat here is the bad guy will be able to > provide an update to a good guy's code (which can be farily > troublesome). Due to the signing model and process, there is no > effective identity assurances for the users of the APK. So we will > never really know who the good guy or bad guy is/was. > > I say "partially signed" because the signing process violates Schneier > and Wagner's semantic authentication > (http://www.schneier.com/paper-ssl.html). Confer: one signs an APK, > then zip aligns the APK. Will anyone be surprised when Apple and > Android code signing fails in the field like > http://www.kb.cert.org/vuls/id/845620 ? Or perhaps un-signed data will > be used/consumed by an application? A year later, the Bluebox "Master Key" exploit was released < https://www.esecurityplanet.com/mobile/inside-the-bluebox-android-master-ke= y-vulnerability/>. That was quickly followed by another "Master Key" exploit, < http://www.androidpolice.com/2013/07/11/second-all-access-apk-exploit-is-re= vealed-just-two-days-after-master-key-goes-public-already-patched-by-google= / >. And in 2024, we're again reading about more problems. (Your disclosure). Android signing will continue to be a problem until signing achieves the level of semantic authentication as discussed by Wagner and Schneier back in 1996, . Jeff --000000000000285b7106168fb465--