tweaselORG / meta

(Currently) only used for the issue tracker.
2 stars 0 forks source link

Document how to setup Android devices for traffic interception #18

Closed baltpeter closed 1 year ago

baltpeter commented 1 year ago

This means:

(cf. #20 for iOS)

baltpeter commented 1 year ago

A proxy can interactively be configured through the WiFi settings:

Screenshot_20230220-104441_Settings

Note how it warns that apps may ignore this, though.

baltpeter commented 1 year ago

Setting this does not set any of the settings we considered in https://github.com/tweaselORG/appstraction/issues/25#issuecomment-1434556407:

ocean:/ # settings get global http_proxy
null
ocean:/ # settings get global global_http_proxy_host
null
ocean:/ # settings get global global_http_proxy_port
null
ocean:/ # settings get global global_http_proxy_username
null
ocean:/ # settings get global global_http_proxy_password
null
ocean:/ # settings get global global_http_proxy_exclusion_list
null
ocean:/ # settings get global global_proxy_pac_url
null
baltpeter commented 1 year ago

In fact, this doesn't seem to be handled by the settings system at all:

ocean:/ # settings list system | grep 8080 
1|ocean:/ # settings list secure | grep 8080                                                                                                    
1|ocean:/ # settings list global | grep 8080                                                                                                    
1|ocean:/ # settings list system | grep "10.0.0.68"                                                                                             
1|ocean:/ # settings list global | grep "10.0.0.68"                                                                                             
1|ocean:/ # settings list secure | grep "10.0.0.68"                                                                                             
1
baltpeter commented 1 year ago

For manually setting the proxy through the GUI, I've tested the following two apps:

baltpeter commented 1 year ago

The next problem is installing our root CA.

Android has two kinds of CA stores: The system and the user certificate store. As the name implies, user CAs are intended to be installable by users, whereas system CAs are not. Crucially, apps don't trust user CAs unless they explicitly opt in to that via their manifest (which most apps unsurprisingly tend no to).

System CAs are stored in /system/etc/security/cacerts but since Android 10, /system is only mounted as read-only and cannot be written to even with root rights.

In the Android emulator, we can change that by starting the emulator with -writable-system and then performing this delightful little dance:

adb root
adb shell avbctl disable-verification
adb disable-verity
adb reboot
adb root
adb remount

But that doesn't work on physical devices. I've found two possible solutions:

[^1]: The actual implementation is really easy since Magisk already provides the necessary support to "write" to /system: https://github.com/NVISOsecurity/MagiskTrustUserCerts/blob/ed40b9ee64be2786af9a0f3aef7e9a652d469c1d/post-fs-data.sh

baltpeter commented 1 year ago

From a quick test, it seems like it might not even be necessary to install our CA:

When I start DB Navigator with objection, it looks like all requests by the app go through correctly. The only errors I see in the mitmproxy logs are for Google domains, which may well be from the system, not the app:

10.0.0.90:40660: Client TLS handshake failed. The client does not trust the proxy's certificate for connectivitycheck.gstatic.com (OpenSSL Error([('SSL routines', 'ssl3_read_bytes', 'sslv3 alert certificate unknown')]))
10.0.0.90:41600: Client TLS handshake failed. The client does not trust the proxy's certificate for www.google.com (OpenSSL Error([('SSL routines', 'ssl3_read_bytes', 'sslv3 alert certificate unknown')]))

But I can't say for sure that we're not missing anything that way. And since the method in the comment before is so elegant, it probably makes sense to install the CA anyway, just in case.

baltpeter commented 1 year ago

Though, I have to say: One benefit of not installing our CA and only relying on the cert pinning bypass: The amount of background noise from the system/other apps is cut back significantly. Barely any of that works over HTTP (seems to just be the connectivity check). :D

baltpeter commented 1 year ago

But I can't say for sure that we're not missing anything that way. And since the method in the comment before is so elegant, it probably makes sense to install the CA anyway, just in case.

Oh, and of course we also want users to be able to intercept traffic without a certificate pinning bypass if they so choose!