diff --git a/nogotofail/clients/android/.gitignore b/nogotofail/clients/android/.gitignore index 67495841..e7b0284d 100644 --- a/nogotofail/clients/android/.gitignore +++ b/nogotofail/clients/android/.gitignore @@ -8,6 +8,7 @@ WORKSPACE # Generated files bin/ gen/ +*.apk # Gradle files .gradle/ diff --git a/nogotofail/clients/android/app/build.gradle b/nogotofail/clients/android/app/build.gradle index ebe635bf..9c419540 100644 --- a/nogotofail/clients/android/app/build.gradle +++ b/nogotofail/clients/android/app/build.gradle @@ -16,4 +16,8 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' } } -} + + dependencies { + compile 'com.google.android.gms:play-services:8.1.0' + } +} \ No newline at end of file diff --git a/nogotofail/clients/android/app/src/main/AndroidManifest.xml b/nogotofail/clients/android/app/src/main/AndroidManifest.xml index 0f10c174..f5a5e28e 100644 --- a/nogotofail/clients/android/app/src/main/AndroidManifest.xml +++ b/nogotofail/clients/android/app/src/main/AndroidManifest.xml @@ -32,6 +32,15 @@ + + + + + + + + + getPersonalItems(Context context) { + Set clientPersonalItems = new HashSet(); + + String android_id = getAndroidId(context); + Info advertising_info = getAdvertisingId(context); + String device_id = getDeviceId(context); + String mac_address = getMACAddress(context); + + if (android_id != null) { + clientPersonalItems.add("'android_id':'" + android_id + "'"); + } + if (advertising_info != null) { + clientPersonalItems.add("'google_advertising_id':'" + advertising_info.getId() + "'"); + } + if (device_id != null) { + clientPersonalItems.add("'device_id':'" + device_id + "'"); + } + if (mac_address != null) { + clientPersonalItems.add("'mac_address':'" + mac_address + "'"); + } + return clientPersonalItems; + } + + /** + * Gets the device's current location. + * + * @returns device location or {@code null} if not available. + */ + public static Set getDeviceLocation(Context context) { + Set clientDeviceLocation = new HashSet(); + + Location device_location; + try { + LocationManager location_manager = + (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + + Criteria criteria = new Criteria(); + criteria.setAccuracy(Criteria.ACCURACY_FINE); + String location_provider = location_manager.getBestProvider(criteria, false); + device_location = location_manager.getLastKnownLocation(location_provider); + } + catch (Exception e) { + device_location = null; + } + if (device_location != null) { + String latitude = String.valueOf(device_location.getLatitude()); + String longitude = String.valueOf(device_location.getLongitude()); + + clientDeviceLocation.add("'latitude':'" + latitude + "', " + + "'longitude':'" + longitude + "'"); + } + return clientDeviceLocation; + } + + /* + * Gets the device's Android ID. + * + * @returns the device's Android ID or {@code null} if not available. + */ + private static String getAndroidId(Context context) { + return Secure.getString(context.getContentResolver(), Secure.ANDROID_ID); + } + + /* + * Gets the user's Advertising ID. + * + * @returns the Advertising ID or {@code null} if not available. + */ + private static Info getAdvertisingId(Context context) { + Info advertising_info; + try { + advertising_info = AdvertisingIdClient.getAdvertisingIdInfo(context); + /** + * TODO: Include check to alert when device user has enabled "Limit Ad Tracking" + * for their Google account. This will allow testers to verify apps sending the + * user's "Android ID" to advertisers when they shouldn't. + */ + //final boolean ad_tracking_limited = advertising_info.isLimitAdTrackingEnabled(); + } + catch (GooglePlayServicesRepairableException | GooglePlayServicesNotAvailableException | + IOException e) { + /** Encountered a recoverable error connecting to Google Play services OR + * Google Play services is not available entirely OR + * a general IO exception. + */ + advertising_info = null; + } + return advertising_info; + } + + /* + * Gets the device's Device ID. + * + * @returns the Device ID or {@code null} if not available. + */ + private static String getDeviceId(Context context) { + //Retrieve a reference to an instance of TelephonyManager + TelephonyManager telephonyManager = + (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); + // Fetch the device's unique ID if it exists. + // Note. This varies depending on network e.g. IMEI for GSM, MEID/ESN for CDMA. + String device_id = telephonyManager.getDeviceId(); + if (device_id == null){ + return null; + } + else { + return device_id; + } + } + + /* + * Gets the device's MAC Address. + * + * @returns the MAC Address or {@code null} if not available. + */ + private static String getMACAddress (Context context) { + WifiManager wifi_manager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE); + WifiInfo wifi_info = wifi_manager.getConnectionInfo(); + + // Fetch the device's WiFi MAC address. + String mac_address = wifi_info.getMacAddress(); + if (mac_address == null) { + return null; + } + else { + return mac_address; + } + } + + /* + * Gets the device's location i.e. longitude and latitude. + * + * @returns the location or {@code null} if not available. + */ + /* + private static Location getDeviceLocation (Context context) { + Location last_known_location; + try { + LocationManager location_manager = + (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + + Criteria criteria = new Criteria(); + criteria.setAccuracy(Criteria.ACCURACY_FINE); + String location_provider = location_manager.getBestProvider(criteria, false); + last_known_location = location_manager.getLastKnownLocation(location_provider); + } + catch (Exception e) { + last_known_location = null; + } + return last_known_location; + } + */ } diff --git a/nogotofail/clients/android/app/src/main/java/net/nogotofail/RouterConnectionHandler.java b/nogotofail/clients/android/app/src/main/java/net/nogotofail/RouterConnectionHandler.java index a17a5d0c..a88450d1 100644 --- a/nogotofail/clients/android/app/src/main/java/net/nogotofail/RouterConnectionHandler.java +++ b/nogotofail/clients/android/app/src/main/java/net/nogotofail/RouterConnectionHandler.java @@ -99,6 +99,9 @@ interface CommandHandler { private static final String HEADER_SUPPORTED_DATA_ATTACKS = "Supported-Data-Attacks"; private static final String HEADER_SUPPORTED_DATA_ATTACKS_LOWER_CASE = HEADER_SUPPORTED_DATA_ATTACKS.toLowerCase(Locale.US); + // Client PII header strings + private static final String HEADER_PII_ITEMS = "PII-Items"; + private static final String HEADER_PII_LOCATION = "PII-Location"; /** * Timeout (milliseconds) for a read operation waiting for a command from the server. The server @@ -170,6 +173,18 @@ public void handleConnection(Socket socket) throws IOException { writeHandshakeRequestHeader( out, HEADER_ENABLED_DATA_ATTACKS, TextUtils.join(",", requestedEnabledDataAttackIds)); } + Set requestedPersonalItems = + AttacksPreferenceFragment.getPersonalItems(mContext); + if (requestedPersonalItems != null) { + writeHandshakeRequestHeader( + out, HEADER_PII_ITEMS, "{" + TextUtils.join(",", requestedPersonalItems) + "}"); + } + Set requestedPersonalLocation = + AttacksPreferenceFragment.getDeviceLocation(mContext); + if (requestedPersonalLocation != null) { + writeHandshakeRequestHeader( + out, HEADER_PII_LOCATION, "{" + TextUtils.join(",", requestedPersonalLocation) + "}"); + } out.write("\r\n"); out.flush(); diff --git a/nogotofail/clients/android/app/src/main/res/values/strings.xml b/nogotofail/clients/android/app/src/main/res/values/strings.xml index 11057cf8..d538bc65 100644 --- a/nogotofail/clients/android/app/src/main/res/values/strings.xml +++ b/nogotofail/clients/android/app/src/main/res/values/strings.xml @@ -95,6 +95,9 @@ Downgrade of STARTTLS-protected XMPP to cleartext + + Cleartext PII detected in HTTP content + Notifications Notifications Notify about detected vulnerabilities @@ -160,6 +163,9 @@ XMPP STARTTLS strip Downgrade of STARTTLS-protected XMPP to cleartext + Cleartext PII in HTTP content + Cleartext PII appears in HTTP content + Advanced MiTM controller