Skip to content

Commit 422c85d

Browse files
committed
Bump mitm addon to 2.0 and fix IPv4/IPv6 decryption collision
Addon changes: - Increase minSdk to 24 - Drop x86 and armeabi-v7a ABI support - Update mitmproxy to 12.2.3 (includes security fixes) - Update Chaquopy to 17 - Target Python 3.13 - Support 16 KB page sizes - Fix IPv6 local port collisions
1 parent 7f08c9d commit 422c85d

19 files changed

Lines changed: 73 additions & 55 deletions

File tree

app/src/main/java/com/emanuelef/remote_capture/CaptureService.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,11 @@ public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
317317
mSettings.capture_interface = mSettings.input_pcap_path;
318318
}
319319

320+
if(mSettings.tls_decryption && !MitmAddon.isSupportedTarget()) {
321+
Log.w(TAG, "TLS decryption is not supported on this target, disabling it");
322+
mSettings.tls_decryption = false;
323+
}
324+
320325
// Retrieve DNS server
321326
String fallbackDnsV4 = Prefs.getDnsServerV4(mPrefs);
322327
dns_server = fallbackDnsV4;

app/src/main/java/com/emanuelef/remote_capture/MitmAddon.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* You should have received a copy of the GNU General Public License
1515
* along with PCAPdroid. If not, see <http://www.gnu.org/licenses/>.
1616
*
17-
* Copyright 2022-24 - Emanuele Faranda
17+
* Copyright 2022-26 - Emanuele Faranda
1818
*/
1919

2020
package com.emanuelef.remote_capture;
@@ -49,8 +49,8 @@
4949
import java.lang.ref.WeakReference;
5050

5151
public class MitmAddon {
52-
public static final long PACKAGE_VERSION_CODE = 21;
53-
public static final String PACKAGE_VERSION_NAME = "1.4";
52+
public static final long PACKAGE_VERSION_CODE = 22;
53+
public static final String PACKAGE_VERSION_NAME = "2.0";
5454
public static final String REPOSITORY = "https://github.com/emanuele-f/PCAPdroid-mitm";
5555
private static final String TAG = "MitmAddon";
5656
private final Context mContext;
@@ -173,6 +173,15 @@ public static String getGithubReleaseUrl(String version) {
173173
version + "/PCAPdroid-mitm_v" + version + "_" + Build.SUPPORTED_ABIS[0] + ".apk";
174174
}
175175

176+
// The mitm addon is only built for Android 7+ and the x86_64/arm64-v8a ABIs
177+
public static boolean isSupportedTarget() {
178+
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
179+
return false;
180+
181+
String abi = Build.SUPPORTED_ABIS[0];
182+
return abi.equals("arm64-v8a") || abi.equals("x86_64");
183+
}
184+
176185
public static void setCAInstallationSkipped(Context ctx, boolean skipped) {
177186
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
178187
prefs.edit()

app/src/main/java/com/emanuelef/remote_capture/MitmReceiver.java

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,11 @@
5555
* The mitm addon sends TCP messages via a socket, containing an header and the plaintext.
5656
*
5757
* The header is an ASCII string in the following format:
58-
* "timestamp:port:msg_type:msg_length\n"
58+
* "timestamp:ipver:ipproto:port:msg_type:msg_length\n"
5959
* - timestamp: milliseconds timestamp for the message
60-
* - port: the TCP local port used by the SOCKS5 client
60+
* - ipver: the IP version (4 or 6) of the connection
61+
* - ipproto: the IP protocol number of the connection (e.g. 6 for TCP)
62+
* - port: the local port used by the SOCKS5 client
6163
* - msg_type: type of message, see parseMsgType for possible values
6264
* - msg_length: the message length in bytes
6365
*
@@ -102,13 +104,15 @@ private enum MsgType {
102104
private static class PendingMessage {
103105
MsgType type;
104106
byte[] msg;
107+
int ipver;
105108
int port;
106109
long pendingSince;
107110
long when;
108111

109-
PendingMessage(MsgType _type, byte[] _msg, int _port, long _now) {
112+
PendingMessage(MsgType _type, byte[] _msg, int _ipver, int _port, long _now) {
110113
type = _type;
111114
msg = _msg;
115+
ipver = _ipver;
112116
port = _port;
113117
pendingSince = SystemClock.elapsedRealtime();
114118
when = _now;
@@ -204,6 +208,8 @@ public void run() {
204208
try(DataInputStream istream = new DataInputStream(new ParcelFileDescriptor.AutoCloseInputStream(mSocketFd))) {
205209
while(mAddon.isConnected()) {
206210
String msg_type;
211+
int ipver;
212+
int ipproto;
207213
int port;
208214
int msg_len;
209215
long tstamp;
@@ -222,13 +228,17 @@ public void run() {
222228
//Log.d(TAG, "[HEADER] " + header);
223229

224230
try {
225-
// timestamp:port:msg_type:msg_length\n
231+
// timestamp:ipver:ipproto:port:msg_type:msg_length\n
226232
String tk_tstamp = tk.nextToken(":");
233+
String tk_ipver = tk.nextToken();
234+
String tk_ipproto = tk.nextToken();
227235
String tk_port = tk.nextToken();
228236
msg_type = tk.nextToken();
229237
String tk_len = tk.nextToken();
230238

231239
tstamp = Long.parseLong(tk_tstamp);
240+
ipver = Integer.parseInt(tk_ipver);
241+
ipproto = Integer.parseInt(tk_ipproto);
232242
port = Integer.parseInt(tk_port);
233243
msg_len = Integer.parseInt(tk_len);
234244
} catch (NoSuchElementException | NumberFormatException e) {
@@ -263,15 +273,16 @@ else if(type == MsgType.LOG) {
263273
} else if(type == MsgType.RUNNING) {
264274
Log.i(TAG, "MITM proxy is running");
265275
proxyStatus.postValue(Status.RUNNING);
266-
} else {
267-
ConnectionDescriptor conn = getConnByLocalPort(port);
276+
} else if(ipproto == 6 /* TCP */) {
277+
// only TCP connections are decrypted, UDP messages are ignored
278+
ConnectionDescriptor conn = getMitmConnByLocalPort(ipver, port);
268279
//Log.d(TAG, "MSG." + type.name() + "[" + msg_len + " B]: port=" + port + ", match=" + (conn != null));
269280

270281
if(conn != null)
271282
handleMessage(conn, type, msg, tstamp);
272283
else
273284
// We may receive a message before seeing the connection in connectionsAdded
274-
addPendingMessage(new PendingMessage(type, msg, port, tstamp));
285+
addPendingMessage(new PendingMessage(type, msg, ipver, port, tstamp));
275286
}
276287
}
277288
} catch (IOException e) {
@@ -349,12 +360,13 @@ private synchronized void addPendingMessage(PendingMessage pending) {
349360
}
350361
}
351362

352-
int idx = mPendingMessages.indexOfKey(pending.port);
363+
int key = getMitmConnKey(pending.ipver, pending.port);
364+
int idx = mPendingMessages.indexOfKey(key);
353365
ArrayList<PendingMessage> pp;
354366

355367
if(idx < 0) {
356368
pp = new ArrayList<>();
357-
mPendingMessages.put(pending.port, pp);
369+
mPendingMessages.put(key, pp);
358370
} else
359371
pp = mPendingMessages.valueAt(idx);
360372

@@ -451,11 +463,13 @@ public void connectionsAdded(int start, ConnectionDescriptor[] conns) {
451463
if(!conn.isMitmDecrypt())
452464
continue;
453465

466+
int key = getMitmConnKey(conn.ipver, conn.local_port);
467+
454468
//Log.d(TAG, "[+] port " + conn.local_port);
455-
mPortToConnId.put(conn.local_port, conn.incr_id);
469+
mPortToConnId.put(key, conn.incr_id);
456470

457471
// Check if the message has already been received
458-
int pending_idx = mPendingMessages.indexOfKey(conn.local_port);
472+
int pending_idx = mPendingMessages.indexOfKey(key);
459473
if(pending_idx >= 0) {
460474
ArrayList<PendingMessage> pp = mPendingMessages.valueAt(pending_idx);
461475
mPendingMessages.removeAt(pending_idx);
@@ -515,17 +529,21 @@ public void onMitmServiceDisconnect() {
515529
CaptureService.stopService();
516530
}
517531

518-
ConnectionDescriptor getConnByLocalPort(int local_port) {
532+
private static int getMitmConnKey(int ipver, int local_port) {
533+
return (ipver << 16) | local_port;
534+
}
535+
536+
ConnectionDescriptor getMitmConnByLocalPort(int ipver, int local_port) {
519537
Integer conn_id;
520538

521539
synchronized(this) {
522-
conn_id = mPortToConnId.get(local_port);
540+
conn_id = mPortToConnId.get(getMitmConnKey(ipver, local_port));
523541
}
524542
if(conn_id == null)
525543
return null;
526544

527545
ConnectionDescriptor conn = mReg.getConnById(conn_id);
528-
if((conn == null) || (conn.local_port != local_port))
546+
if((conn == null) || (conn.ipver != ipver) || (conn.local_port != local_port))
529547
return null;
530548

531549
// success

app/src/main/java/com/emanuelef/remote_capture/activities/MainActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -855,7 +855,7 @@ public void startCapture() {
855855
if(showRemoteServerAlert())
856856
return;
857857

858-
if(Prefs.getTlsDecryptionEnabled(mPrefs)) {
858+
if(Prefs.getTlsDecryptionEnabled(mPrefs) && MitmAddon.isSupportedTarget()) {
859859
if (MitmAddon.needsSetup(this)) {
860860
Intent intent = new Intent(this, MitmSetupWizard.class);
861861
startActivity(intent);

app/src/main/java/com/emanuelef/remote_capture/activities/prefs/SettingsActivity.java

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@
2828
import android.os.Bundle;
2929
import android.os.LocaleList;
3030
import android.provider.Settings;
31-
import android.system.Os;
32-
import android.system.OsConstants;
3331
import android.text.InputType;
3432
import android.util.AttributeSet;
3533
import android.view.View;
@@ -355,30 +353,31 @@ private void setupTrafficInspectionPrefs() {
355353
mAutoBlockPrivateDNS = requirePreference("auto_block_private_dns");
356354

357355
mTlsDecryption = requirePreference(Prefs.PREF_TLS_DECRYPTION_KEY);
358-
mTlsDecryption.setOnPreferenceChangeListener((preference, newValue) -> {
359-
boolean enabled = (boolean) newValue;
360-
Context ctx = requireContext();
356+
if(!MitmAddon.isSupportedTarget()) {
357+
// The mitm addon dropped support for armv7/x86 and Android < 7
358+
mTlsDecryption.setChecked(false);
359+
mTlsDecryption.setEnabled(false);
360+
mTlsDecryption.setSummary(R.string.tls_decryption_unsupported_target);
361+
} else
362+
mTlsDecryption.setOnPreferenceChangeListener((preference, newValue) -> {
363+
boolean enabled = (boolean) newValue;
364+
Context ctx = requireContext();
361365

362-
if (enabled && (Os.sysconf(OsConstants._SC_PAGE_SIZE) == 16384)) {
363-
Utils.showToastLong(ctx, R.string.tls_decryption_not_supported_16KB);
364-
return false;
365-
}
366+
if(!checkDecrpytionWithRoot(rootCaptureEnabled(), (boolean) newValue))
367+
return false;
366368

367-
if(!checkDecrpytionWithRoot(rootCaptureEnabled(), (boolean) newValue))
368-
return false;
369-
370-
if(enabled && MitmAddon.needsSetup(ctx)) {
371-
mHasStartedMitmWizard = true;
372-
Intent intent = new Intent(ctx, MitmSetupWizard.class);
373-
startActivity(intent);
374-
return false;
375-
}
369+
if(enabled && MitmAddon.needsSetup(ctx)) {
370+
mHasStartedMitmWizard = true;
371+
Intent intent = new Intent(ctx, MitmSetupWizard.class);
372+
startActivity(intent);
373+
return false;
374+
}
376375

377-
mMitmWizard.setVisible((boolean) newValue);
378-
mMitmproxyOpts.setVisible((boolean) newValue);
379-
socks5ProxyHideShow((boolean) newValue, rootCaptureEnabled());
380-
return true;
381-
});
376+
mMitmWizard.setVisible((boolean) newValue);
377+
mMitmproxyOpts.setVisible((boolean) newValue);
378+
socks5ProxyHideShow((boolean) newValue, rootCaptureEnabled());
379+
return true;
380+
});
382381

383382
mPcapngEnabled = requirePreference("pcapng_format");
384383

app/src/main/res/values-ar/strings.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,6 @@
523523
<string name="show_api_key">أظهِر مفتاح API</string>
524524
<string name="api_key">مفتاح API</string>
525525
<string name="api_key_discard_confirm">هل تريد حقًا التخلص من مفتاح الـ API الحالي وتوليد مفتاح جديد؟</string>
526-
<string name="tls_decryption_not_supported_16KB">فك تعمية TLS غير مدعوم حاليًا على الأجهزة ذات الذاكرة 16 كيلوبايت</string>
527526
<string name="filename_prefix">بادئة اسم الملف</string>
528527
<string name="filename_prefix_description">عيّن البادئة للملفات التي يصدرها PCAPdroid، مثل ملفات PCAP</string>
529528
<string name="select">حدِّد</string>

app/src/main/res/values-az/strings.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,6 @@
513513
<string name="errno_ehostunreach">Barındırıcıya marşrut yoxdur</string>
514514
<string name="errno_ehostunreach_msg">Sistem hədəf barındırıcıya marşrutu tapmadı</string>
515515
<string name="tls_conn_info">TLS/HTTPS trafiki şifrəlidir.Bu trafiki incələmək üçün,deşifrləməyə ehtiyacın var.Yoxla PCAPdroid <a href="%1$s">istifadəçi təlimatını</a> ətraflı üçün</string>
516-
<string name="tls_decryption_not_supported_16KB">TLS deşifrələməsi hazırda 16 KB cihazlarda dəstəklənmir</string>
517516
<string name="filename_prefix">Fayl adı prefiksi</string>
518517
<string name="filename_prefix_description">PCAPdroid tərəfindən ixrac edilən fayllar üçün prefiks təyin edin, məs. PCAP faylları</string>
519518
<string name="no_requests">Sorğu yoxdur</string>

app/src/main/res/values-de/strings.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,6 @@
513513
<string name="errno_ehostunreach_msg">Das System kann keine Route zum Ziel-Host finden</string>
514514
<string name="dns_conn_info">DNS übersetzt einen Domainnamen in eine IP-Adresse. Die tatsächlichen Daten werden typischerweise über nachfolgende HTTPS/TLS-Verbindungen ausgetauscht</string>
515515
<string name="tls_conn_info">TLS/HTTPS-Verkehr ist verschlüsselt. Um diesen Traffic zu überprüfen, müssen Sie ihn entschlüsseln. Überprüfen Sie die PCAPdroid <a href="%1$s">Benutzeranleitung</a> für Details</string>
516-
<string name="tls_decryption_not_supported_16KB">TLS-Entschlüsselung wird auf 16-KB-Geräten derzeit nicht unterstützt</string>
517516
<string name="dump_extensions_summary">Erweitern Sie das Paket-Dump-Format mit zusätzlichen Metadaten, wie die App, die ein bestimmtes Paket gesendet / empfangen</string>
518517
<string name="unsupported_pcap_file">Ununterstütztes Erfassungsdateiformat</string>
519518
<string name="mitm_addon_update_available">Ein neues Update für das mitm AddOn ist verfügbar. Aktualisiere, um die aktuellsten Fehlerbehebungen zu installieren</string>

app/src/main/res/values-es/strings.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,6 @@
519519
<string name="errno_ehostunreach_msg">El sistema no puede encontrar una ruta hacia el host de destino</string>
520520
<string name="dns_conn_info">DNS traduce un nombre de dominio a una dirección IP. Los datos reales se intercambian normalmente a través de conexiones HTTPS/TLS posteriores</string>
521521
<string name="tls_conn_info">El tráfico TLS/HTTPS está cifrado. Para inspeccionar este tráfico, necesita descifrarlo. Consulte la <a href="%1$s">guía de usuario</a> de PCAPdroid para más detalles</string>
522-
<string name="tls_decryption_not_supported_16KB">El descifrado TLS no es compatible actualmente en dispositivos de 16 KB</string>
523522
<string name="filename_prefix">Prefijo de nombre de archivo</string>
524523
<string name="filename_prefix_description">Establece el prefijo para los archivos exportados por PCAPdroid, p. ej. archivos PCAP</string>
525524
<string name="no_requests">Sin solicitudes</string>

app/src/main/res/values-in/strings.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,6 @@
507507
<string name="errno_ehostunreach">Tidak ada rute ke host</string>
508508
<string name="errno_ehostunreach_msg">Sistem tidak dapat menemukan rute ke host tujuan</string>
509509
<string name="tls_conn_info">lalu lintas TLS/HTTPS dienkripsi. Untuk memeriksa lalu lintas ini, Anda perlu mendekripsinya. Cek <a href="%1$s">panduan pengguna</a> PCAPdroid untuk detailnya</string>
510-
<string name="tls_decryption_not_supported_16KB">Dekripsi TLS saat ini tidak didukung pada perangkat 16 KB</string>
511510
<string name="filename_prefix">Awalan nama file</string>
512511
<string name="filename_prefix_description">Atur awalan untuk file yang diekspor oleh PCAPdroid, mis. file PCAP</string>
513512
<string name="no_requests">Tidak ada permintaan</string>

0 commit comments

Comments
 (0)