Centralize config parameters and document the use of each script

This commit is contained in:
Tim Perry
2023-09-19 20:40:21 +02:00
parent 653cb60b9e
commit 6ee3d4ebb1
4 changed files with 56 additions and 28 deletions
+16 -4
View File
@@ -1,16 +1,28 @@
// Default emulator address for now:
const PROXY_HOST = '192.168.104.248';
const PROXY_PORT = 8000;
/**
* The first step in intercepting HTTP & HTTPS traffic is to set the default proxy settings,
* telling the app that all requests should be sent via our HTTP proxy.
*
* In this script, we set that up via a few different mechanisms, which cumulatively should
* ensure that all connections are sent via the proxy, even if they attempt to use their
* own custom proxy configurations to avoid this.
*
* Despite that, this still only covers well behaved apps - it's still possible for apps
* to send network traffic directly if they're determined to do so, or if they're built
* with a framework that does not do this by default (Flutter is notably in this category).
* To handle those less tidy cases, we manually capture traffic to recognized target ports
* in the native connect() hook script.
*/
setTimeout(() => {
Java.perform(() => {
// Set default JVM system properties for the proxy address:
Java.use('java.lang.System').setProperty('http.proxyHost', PROXY_HOST);
Java.use('java.lang.System').setProperty('http.proxyPort', PROXY_PORT.toString());
Java.use('java.lang.System').setProperty('https.proxyHost', PROXY_HOST);
Java.use('java.lang.System').setProperty('https.proxyPort', PROXY_PORT.toString());
// Configure the proxy indirectly, by overriding the return value for all ProxySelectors everywhere:
const Collections = Java.use('java.util.Collections');
const ArrayList = Java.use('java.util.ArrayList');
const ProxyType = Java.use('java.net.Proxy$Type');
const InetSocketAddress = Java.use('java.net.InetSocketAddress');
const ProxyCls = Java.use('java.net.Proxy'); // 'Proxy' is reserved in JS
+15 -21
View File
@@ -1,23 +1,17 @@
const CERT_PEM = `-----BEGIN CERTIFICATE-----
MIIDTzCCAjegAwIBAgIRClDpdJeylUmDvNyq5qq+plcwDQYJKoZIhvcNAQELBQAw
QTEYMBYGA1UEAxMPSFRUUCBUb29sa2l0IENBMQswCQYDVQQGEwJYWDEYMBYGA1UE
ChMPSFRUUCBUb29sa2l0IENBMB4XDTIyMTIyNTE5MDQ1MFoXDTIzMTIyNjE5MDQ1
MFowQTEYMBYGA1UEAxMPSFRUUCBUb29sa2l0IENBMQswCQYDVQQGEwJYWDEYMBYG
A1UEChMPSFRUUCBUb29sa2l0IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAz4pwm0pLDvf8qVmAiOi2cvu8xDgboetoLWBoONOY2wvoEFRylLUGaieP
UG5Yuofcj798uYPEqPLoF2ugnw8J/lhYhkMqTEbuqoyZT7DooBiqtSbm4b++T/Zt
F6YnpkYeWIkv88UJaRvLG8OHytVbiC71JQ/DFCEjzNzATCKT7UFqyF4ZsT3cnGJe
3x1iiSzWxJsnDkNZmiQ+IDYSM/dx7RJYwrXO5oWbAHC7otdC66O9eB1uBYq9I8gU
4FcVKHbWAH1BYbsoF/pQJLz2mAXD7E92/Vvho7FgTKYOUq0b58LF9UHt+gDRUGUC
L4HtuMeb/Ckiwyoej50jqI//ER1XswIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/
MA4GA1UdDwEB/wQEAwIBxjAdBgNVHQ4EFgQUfsk69D2mzcAFjDX0GV53o3gySMMw
DQYJKoZIhvcNAQELBQADggEBAH08sPexRXFxzuIVWD1aUoarYq8FwNBP+xusgZcg
DmRKr0FpEyUjBxgVIsmd44WSX/TWdXokdd7aLPVnjwQbq2mhYtXAn4aIRn3QBNaj
TvFQovVy+LCSRwZjvlpr/KJnXlVMrqLIxP++I6FqLO5G5zJ+qDF39C7RUkkMpvmU
tiS70/zpt2LSfLUNtnS287P9s4wXEwbrkOOY6oNgKDz7jtNua0ZiPq2uGdqrkyZ2
VPgirbNnuoC1uZmuy0Mvih4+8xrvJWHb9QO7JOH3cXA+ZiZ945V+viMEnV0YkQB6
FL11l3fE9xzkPv357Z3e7QULnC8vDRgFAossuh8WBhNjjmo=
-----END CERTIFICATE-----`;
/**
* Once we have captured traffic (once it's being sent to our proxy port) the next step is
* to ensure any clients using TLS (HTTPS) trust our CA certificate, to allow us to intercept
* encrypted connections successfully.
*
* This script does so by attaching to the internals of Conscrypt (the Android SDK's standard
* TLS implementation) and pre-adding our certificate to the 'already trusted' cache, so that
* future connections trust it implicitly. This ensures that all normal uses of Android APIs
* for HTTPS & TLS will allow interception.
*
* This does not handle all standalone certificate pinning techniques - where the application
* actively rejects certificates that are trusted by default on the system. That's dealt with
* in the separate certificate unpinning script.
*/
Java.perform(() => {
// First, we build a JVM representation of our certificate:
@@ -55,5 +49,5 @@ Java.perform(() => {
// pinning too! It auto-trusts us in any implementation that uses TrustManagerImpl (Conscrypt) as
// the underlying cert checking component.
console.log('Inject system certificate trust');
console.log('System certificate trust injected');
});
+25
View File
@@ -0,0 +1,25 @@
// Local testing certificate for now
const CERT_PEM = `-----BEGIN CERTIFICATE-----
MIIDTzCCAjegAwIBAgIRClDpdJeylUmDvNyq5qq+plcwDQYJKoZIhvcNAQELBQAw
QTEYMBYGA1UEAxMPSFRUUCBUb29sa2l0IENBMQswCQYDVQQGEwJYWDEYMBYGA1UE
ChMPSFRUUCBUb29sa2l0IENBMB4XDTIyMTIyNTE5MDQ1MFoXDTIzMTIyNjE5MDQ1
MFowQTEYMBYGA1UEAxMPSFRUUCBUb29sa2l0IENBMQswCQYDVQQGEwJYWDEYMBYG
A1UEChMPSFRUUCBUb29sa2l0IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAz4pwm0pLDvf8qVmAiOi2cvu8xDgboetoLWBoONOY2wvoEFRylLUGaieP
UG5Yuofcj798uYPEqPLoF2ugnw8J/lhYhkMqTEbuqoyZT7DooBiqtSbm4b++T/Zt
F6YnpkYeWIkv88UJaRvLG8OHytVbiC71JQ/DFCEjzNzATCKT7UFqyF4ZsT3cnGJe
3x1iiSzWxJsnDkNZmiQ+IDYSM/dx7RJYwrXO5oWbAHC7otdC66O9eB1uBYq9I8gU
4FcVKHbWAH1BYbsoF/pQJLz2mAXD7E92/Vvho7FgTKYOUq0b58LF9UHt+gDRUGUC
L4HtuMeb/Ckiwyoej50jqI//ER1XswIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/
MA4GA1UdDwEB/wQEAwIBxjAdBgNVHQ4EFgQUfsk69D2mzcAFjDX0GV53o3gySMMw
DQYJKoZIhvcNAQELBQADggEBAH08sPexRXFxzuIVWD1aUoarYq8FwNBP+xusgZcg
DmRKr0FpEyUjBxgVIsmd44WSX/TWdXokdd7aLPVnjwQbq2mhYtXAn4aIRn3QBNaj
TvFQovVy+LCSRwZjvlpr/KJnXlVMrqLIxP++I6FqLO5G5zJ+qDF39C7RUkkMpvmU
tiS70/zpt2LSfLUNtnS287P9s4wXEwbrkOOY6oNgKDz7jtNua0ZiPq2uGdqrkyZ2
VPgirbNnuoC1uZmuy0Mvih4+8xrvJWHb9QO7JOH3cXA+ZiZ945V+viMEnV0YkQB6
FL11l3fE9xzkPv357Z3e7QULnC8vDRgFAossuh8WBhNjjmo=
-----END CERTIFICATE-----`;
// Default emulator address for now:
const PROXY_HOST = '127.0.0.1';
const PROXY_PORT = 8000;
-3
View File
@@ -12,9 +12,6 @@
* to do proxy config alongside this, primarily to capture traffic that might be sent on any non-standard ports.
*/
const PROXY_PORT = 8000;
const PROXY_HOST = '127.0.0.1';
// Ports which we recognize, and forcibly redirect to capture, if not captured already.
const RECOGNIZED_PORTS = [
80,