diff --git a/app/src/main/java/com/emanuelef/remote_capture/activities/CaptureCtrl.java b/app/src/main/java/com/emanuelef/remote_capture/activities/CaptureCtrl.java
index 8d7a1a0f..cc1c5751 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/activities/CaptureCtrl.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/activities/CaptureCtrl.java
@@ -22,6 +22,7 @@ package com.emanuelef.remote_capture.activities;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
@@ -199,6 +200,27 @@ public class CaptureCtrl extends AppCompatActivity {
finish();
}
+ // Check if the capture is requesting to send traffic to a remote server.
+ // For security reasons, this is only allowed if such server is already configured by
+ // the user in the app prefs.
+ // see also MainActivity.showRemoteServerAlert
+ private String checkRemoteServerNotAllowed(CaptureSettings settings) {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+
+ if((settings.dump_mode == Prefs.DumpMode.UDP_EXPORTER) &&
+ !Utils.isLocalNetworkAddress(settings.collector_address) &&
+ !Prefs.getCollectorIp(prefs).equals(settings.collector_address))
+ return settings.collector_address;
+
+ if(settings.socks5_enabled &&
+ !Utils.isLocalNetworkAddress(settings.socks5_proxy_address) &&
+ !Prefs.getSocks5ProxyAddress(prefs).equals(settings.socks5_proxy_address))
+ return settings.socks5_proxy_address;
+
+ // ok
+ return null;
+ }
+
private void processRequest(Intent req_intent, @NonNull String action) {
Intent res = new Intent();
Utils.showToast(this, R.string.ctrl_consent_allowed);
@@ -209,13 +231,11 @@ public class CaptureCtrl extends AppCompatActivity {
Log.d(TAG, "Starting capture, caller=" + mStarterApp);
CaptureSettings settings = new CaptureSettings(req_intent);
- if((settings.dump_mode == Prefs.DumpMode.UDP_EXPORTER) && (!Utils.isLocalNetworkAddress(settings.collector_address))) {
- if(!Prefs.getCollectorIp(PreferenceManager.getDefaultSharedPreferences(this)).equals(settings.collector_address)) {
- Log.w(TAG, "For security reasons, exporting to the remote UDP collector \"" + settings.collector_address + "\" is disabled");
- abort();
- return;
- } else
- Log.i(TAG, "Allowing export to remote collector as it matches user pref");
+ String disallowedServer = checkRemoteServerNotAllowed(settings);
+ if(disallowedServer != null) {
+ Utils.showToastLong(this, R.string.remote_server_warning, disallowedServer);
+ abort();
+ return;
}
// will call the mCapHelper listener
diff --git a/app/src/main/java/com/emanuelef/remote_capture/activities/MainActivity.java b/app/src/main/java/com/emanuelef/remote_capture/activities/MainActivity.java
index aefbc7b7..c7e20fcc 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/activities/MainActivity.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/activities/MainActivity.java
@@ -674,6 +674,9 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
}
public void startCapture() {
+ if(showRemoteServerAlert())
+ return;
+
if(Prefs.getTlsDecryptionEnabled(mPrefs) && MitmAddon.needsSetup(this)) {
Intent intent = new Intent(this, MitmSetupWizard.class);
startActivity(intent);
@@ -700,7 +703,28 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
CaptureService.stopService();
}
- public void openFileSelector() {
+ // see also CaptureCtrl.checkRemoteServerNotAllowed
+ private boolean showRemoteServerAlert() {
+ if(mPrefs.getBoolean(Prefs.PREF_REMOTE_COLLECTOR_ACK, false))
+ return false; // already acknowledged
+
+ if(((Prefs.getDumpMode(mPrefs) == Prefs.DumpMode.UDP_EXPORTER) && !Utils.isLocalNetworkAddress(Prefs.getCollectorIp(mPrefs))) ||
+ (Prefs.getSocks5Enabled(mPrefs) && !Utils.isLocalNetworkAddress(Prefs.getSocks5ProxyAddress(mPrefs)))) {
+ Log.i(TAG, "Showing possible scan notice");
+
+ AlertDialog dialog = new AlertDialog.Builder(this)
+ .setTitle(R.string.scam_alert)
+ .setMessage(R.string.remote_collector_notice)
+ .setPositiveButton(R.string.ok, (d, whichButton) -> mPrefs.edit().putBoolean(Prefs.PREF_REMOTE_COLLECTOR_ACK, true).apply())
+ .show();
+ dialog.setCanceledOnTouchOutside(false);
+ return true;
+ }
+
+ return false;
+ }
+
+ private void openFileSelector() {
boolean noFileDialog = false;
String fname = Utils.getUniquePcapFileName(this);
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
diff --git a/app/src/main/java/com/emanuelef/remote_capture/model/Prefs.java b/app/src/main/java/com/emanuelef/remote_capture/model/Prefs.java
index 3b4a10b2..0d104e6b 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/model/Prefs.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/model/Prefs.java
@@ -77,6 +77,7 @@ public class Prefs {
public static final String PREF_VPN_EXCEPTIONS = "vpn_exceptions";
public static final String PREF_BLOCK_NEW_APPS = "block_new_apps";
public static final String PREF_PAYLOAD_NOTICE_ACK = "payload_notice";
+ public static final String PREF_REMOTE_COLLECTOR_ACK = "remote_collector_notice";
public enum DumpMode {
NONE,
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 50e91526..eacbd4d1 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -386,4 +386,6 @@
This view may contain sensitive information, like your passwords and access tokens.\n\nNever give out this information to anyone, it may be a scam attempt
Cancel
Show data
+ You have configured PCAPdroid to send traffic to a remote server. The server will be able to access your sensitive information.\n\nIf someone asked you to do this, it is probably a scam attempt
+ For security reasons, sending traffic to the remote server \"%1$s\" is not allowed"