niklashigi / apk-mitm

🤖 A CLI application that automatically prepares Android APK files for HTTPS inspection
https://npm.im/apk-mitm
MIT License
3.84k stars 346 forks source link

Zoom Video Issues #41

Open yoshimo opened 3 years ago

yoshimo commented 3 years ago

This is "work in progress" I have the feeling that something in the patching process has gone wrong. It is an XAPK split file into 3 and the result of the patch process is a few mb smaller compared to the original. Basically the error is the same as CandyCrush "uses its own CA list".

Within com.zipow.cmmlib.AppUtil ( AppUtil.smali) there is getCertificateFingerprintMD5 which compares the md5 hash signature of the package with a stored value in split_config.arm64_v8a.apk/lib/arm64-v8a libzLoader.so .

Evil function com.zipow.cmmlib.AppUtil

public static String getCertificateFingerprintMD5() {
   Signature[] signatures = ZMUtils.getSignatures(VideoBoxApplication.getNonNullInstance());
   return (signatures == null || signatures.length == 0 || signatures[0] == null) ? "" : StringUtil.safeString(ZMUtils.hexDigest(signatures[0].toByteArray(), MessageDigestAlgorithms.MD5)).toLowerCase();
}

libzWebService.so includes the sha256 hashes of trustworthy public keys

The Java function isIssuedByKnownRoot (us.zoom.net.AndroidCertVerifyResult) checks for root cas that are legimate cert pinning ca's

I am not sure how well apk-mitm deals with binary shared objects.

niklashigi commented 3 years ago

It is an XAPK split file into 3 and the result of the patch process is a few mb smaller compared to the original.

Here's what happens when apk-mitm patches an XAPK:

Apktool is not really aware of App Bundles at the moment, so it might be the culprit here, but the size difference could also be explained by differences in how the files were signed or compressed, so it might not even be a problem.

The Java function isIssuedByKnownRoot (us.zoom.net.AndroidCertVerifyResult) checks for root cas that are legimate cert pinning ca's

I am not sure how well apk-mitm deals with binary shared objects.

I'm sure why you're worried about the binary so much, can't you just patch that isIssuedByKnownRoot method to always return true by editing its code in Smali?

yoshimo commented 3 years ago

apk-mitm failed to do it standalone and there is https://www.kuketz-blog.de/zoom-analyse-des-datensendeverhaltens-der-android-app/ that successfully patched everything but Firebase. Github is international so i translated the parts i found relevant to english.

niklashigi commented 3 years ago

apk-mitm failed to do it standalone

Failed to do what standalone? :thinking: I'm not saying that isIssuedByKnownRoot will be patched automatically, that's a change you have to make manually. I'm not sure I'm following. :sweat_smile:

yoshimo commented 3 years ago

apk-mitm was not enough to get a working app that trusts the mitm proxy. nothing more nothing less

niklashigi commented 3 years ago

Alright, I think I understand now, but I'm not sure why you opened this issue. As the author of the blog post you linked to explained, Zoom uses custom code to perform their signature verification and certificate pinning, code that can only be found in the Zoom app. As much as I would like apk-mitm to work with every single APK out there, maintaining a database of patches specific to different apps would just not be sustainable.

That's why all of the patches that are currently included are either based on system features (like X509TrustManager) or libraries that are used in a lot of apps (like OkHttp). If there's a way to automatically patch the Zoom app without writing code that's tied to the Zoom app (for example by replacing calls to the system methods that return the package signature), then I'd be willing to include it, but that seems pretty difficult to achieve.

The blog post appears to be pretty detailed, so if you want to inspect Zoom's traffic yourself, I'd recommend following the author's steps and contacting him if you get stuck.

yoshimo commented 3 years ago

Well there are a couple of applications that have whitelisted fingerprints inside the code, which i think might be possible to replace automatically as a md5, sha1, sha256 can be found by its characteristics.

niklashigi commented 3 years ago

That's a fair point. I found the following lines in the source code of the latest Zoom XAPK:

.method public static f()Z
    .locals 2

    .line 1
    invoke-static {}, Lcom/zipow/cmmlib/AppUtil;->getCertificateFingerprintMD5()Ljava/lang/String;

    move-result-object v0

    const-string v1, "2762c874eafb8e94376855402628e842" # <-- They don't seem to be hiding it anymore

    invoke-virtual {v1, v0}, Ljava/lang/String;->equalsIgnoreCase(Ljava/lang/String;)Z

    move-result v0

    return v0
.end method

It wouldn't be difficult to:

yoshimo commented 3 years ago

Similar things could be done for TLS and involved public keys versus the favourite proxy ca

yoshimo commented 3 years ago

What also could be intresting is getting the cleartext or encryption keys from FCM in a later step