hiding data/code in Android APK embedded signatures
flx at obfusk.net
Wed Feb 1 23:24:22 UTC 2023
[... some context elided since this is getting quite long ...]
* "David A. Wheeler" <dwheeler at dwheeler.com> [2023-02-01 20:48]:
> > Unfortunately, you've left out the details of the archive format here,
> > when they are actually quite important.
> > You now need to unpack an archive (e.g. a .zip or .tar) before you can
> > verify the signature, leaving you potentially vulnerable to any
> > vulnerabilities (e.g. symlink, path traversal, zip bomb) in your
> > zip/tar implementation, before you have a chance to verify that the
> > signed thing came from a trusted source.
> That's true any time you want to download a *single* file that contains
> both signatures and the thing being signed.
> One solution is to not bundle them at all, which is fine by me. Any proposed
> article should stress that.
> However, many people *do* want to bundle the signatures and the things
> being signed into a single downloadable unit. In that case, we have 2 choices:
> 1. Use a normal archive format. To me this is the better option.
> Unarchiving programs must *already* have mechanisms that counter
> such attacks.
Last I checked, CVE-2007-4559 is still not fixed; and surely not the
only unfixed (let alone currently unknown) such vulnerability that may
suddenly become a problem when you switch to a scheme where you need
to unpack an archive before you can verify the authenticity of its
> Also, downloads typically already verify the distributing origin
> (using https), reducing the risks that the archive have such obvious
> direct attacks.
If HTTPS were enough we would not need additional signatures. I'm
glad e.g. GitHub uses HTTPS, as it does provide a useful additional
layer of security, but HTTPS only guarantees (to the extent it can
given the inherent weaknesses of PKI) that I'm downloading something
from GitHub; it does not in any way guarantee that any code or APKs I
download were actually created by the project's authors. Which is why
many projects use signed git tags and provide OpenPGP signatures for
downloads (though sadly, most people will indeed probably not bother
verifying those). And people rely on APK signatures for authenticity
> 2. "Hide" the signatures into many different complex formats like ELF or PE,
> and then figure out how to extract them. These other formats are typically
> as complex as archive formats, you have to write code for every different
> format, *and* the tools designed to exact data from them
> typically assume that they are *not* under attack.
> I think choice 1 is the better choice if you're going to combine
> them into 1 download.
As usual, what's the better choice depends on your threat model. And
ZIP/TAR vs ELF/PE as the only two alternatives (for distributing a
single file) seems like a false dichotomy: I find it hard to believe
there are no other options (though new custom formats have their own
issues of course).
For a system where the ability to hide data/code in the signature is
currently a non-issue, but e.g. zip bombs would in fact be a problem,
switching from embedded signatures to a ZIP file containing signature
+ artifact has in fact made things worse, not better.
And depending on how those ZIP/TAR files are handled -- e.g. whether
they are available to the program at runtime -- you may in fact
inadvertently introduce the possibility to hide something in the
ZIP/TAR when there was no possibility to hide anything in the
Also: Android APKs are in fact already ZIP files (with a custom APK
Signing Block  added), not ELF or PE executables. As the signing
block is read directly from the APK, the authenticity of the APK can
be verified before any files are unpacked or any code is run.
Interestingly, they are not necessarily unpacked before running as
AFAIK it is possible for Android to directly load the .dex (Java
bytecode) and .so (native code) files (which are stored in
uncompressed form) directly from the APK.
More information about the rb-general