Skip to content
This repository has been archived by the owner on Apr 4, 2024. It is now read-only.

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Jan Girlich committed Feb 13, 2018
0 parents commit aadc16f
Show file tree
Hide file tree
Showing 167 changed files with 4,894 additions and 0 deletions.
60 changes: 60 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Android Java Deserialization Vulnerability Tester

## About

This project includes Android apps that are intended as a tool to test and create Proof of Concept (PoC) exploits for Java deserialization vulnerabilities in Android. It is based on [ysoserial](https://github.com/frohoff/ysoserial) by frohoff, but targeting the Android platform.

This project was developed by Jan Girlich (@vollkorn) from modzero AG (@mod0).

## Background

Java deserialization vulnerabilities are a long known and [well researched](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet) topic. Essentially, there is a high risk involved when deserializing untrusted, serialized Java objects. This usually leads to code execution in the context of the attacked application while deserializing malicious objects.

On Android this becomes even more problematic because of the way how data exchange between apps is handled. Intents are messages sent between Android apps to enable communication between apps. These intents can carry extra data like strings, integers, or serialized objects. Unfortunately, when any part of intent's extra data is accessed all the extra data is unpacked. This means that any serialized Java object is deserialized as soon as any extra data of an intent is used.

## Vulnerability

Any app, which

1. receives an intent and accesses any of its extra data and
1. has any Java class exploitable through a Java deserialization loaded

is vulnerable against Java deserialization attacks on Android.

In other words, except for using vulnerable dependencies (such as CommonsCollection6) and using regular functionality of Android (getting extras from an exported Intent), the app does not need to have any other security weakness.

It's remarkable how such a security-critical operation is discussed [without](https://stackoverflow.com/questions/2139134/how-to-send-an-object-from-one-android-activity-to-another-using-intents) [discussing](https://stackoverflow.com/questions/4233873/how-do-i-get-extra-data-from-intent-on-android) [security](https://stackoverflow.com/questions/2736389/how-to-pass-an-object-from-one-activity-to-another-on-android), not even in the [official documentation](https://developer.android.com/reference/android/content/Intent.html#getExtras()).

## Contents of this repository

This repository consist of two Android apps:

* The [attacker app](deserialization_sender/), which creates a payload and sends the malicious intent: [deserialization_sender](deserialization_sender/)
* The [vulnerable demo app](deserialization_receiver/), which is vulnerable to the CommonsCollection exploit: [deserialization_receiver](deserialization_receiver/)

For a demonstration, open the vulnerable demo app, switch to the attacker app and use the intent target "ch.modzero.intent_receiver.deserialize.pwn".

## Usage

1. Checkout, open in Android Studio and compile the [attacker app](deserialization_sender/) folder.
1. Install the resulting apk on a phone or emulator where you also install the app you want to test for deserialization vulnerabilities (or the [vulnerable demo app](deserialization_receiver/)).
1. Make sure your potentially vulnerable app is running.
1. Put the name of an intent of the potentially vulnerable app listens to into the input field on the top of the main activity (or "ch.modzero.intent_receiver.deserialize.pwn" for the [vulnerable demo app](deserialization_receiver/)).
1. Hit the send button on the bottom right corner.

The app will send all known payloads via the above entered intent. If any payload is successfully executed, the victim app will send back an intent to the attacker app to signal that it was executed. If such a payload's intent is received, the corresponding checkbox in the main activity of the attacker app gets checked.


## Status

For this app it was attempted to port all known Java deserialization exploits from ysoserial to Android. But due to limitations in the Java reflection API and other APIs missing on Android, it was only possible to port one payload so far. You can compare it with the [list of payloads](https://github.com/frohoff/ysoserial#usage) in ysoserial.

If an app accesses any intent's extra data and includes the vulnerable java library on the right hand side of the table, it is exploitable by the payload named in the left column. The app does not even need to use any functionality of the vulnerable library. Just having the classes loaded in the Java Virtual Machine is enough.

| Name | Vulnerable Java Library |
| ---- | ----------------------- |
| CommonsCollection6 | commons-collections:3.1 |

## Contribution

This app is missing more working payloads to test with. Help in porting more payloads from ysoserial or adding new ones is welcome.
Binary file added apks/deserialization_receiver.apk
Binary file not shown.
Binary file added apks/deserialization_sender.apk
Binary file not shown.
1 change: 1 addition & 0 deletions deserialization_receiver/app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
148 changes: 148 additions & 0 deletions deserialization_receiver/app/app.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android-gradle" name="Android-Gradle">
<configuration>
<option name="GRADLE_PROJECT_PATH" value=":app" />
</configuration>
</facet>
<facet type="android" name="Android">
<configuration>
<option name="SELECTED_BUILD_VARIANT" value="debug" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
<afterSyncTasks>
<task>generateDebugSources</task>
</afterSyncTasks>
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7">
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/test/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/build-info" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/builds" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/check-manifest" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-runtime-classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-verifier" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-resources" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-support" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaPrecompile" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/prebuild" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/reload-dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/shaders" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/split-apk" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/splits-support" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/tmp" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/transforms" />
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
<excludeFolder url="file://$MODULE_DIR$/build/reports" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
</content>
<orderEntry type="jdk" jdkName="Android API 26 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" scope="TEST" name="com.android.support.test:exposed-instrumentation-api-publish-0.5" level="project" />
<orderEntry type="library" scope="TEST" name="junit:junit:4.12@jar" level="project" />
<orderEntry type="library" scope="TEST" name="javax.inject:javax.inject:1@jar" level="project" />
<orderEntry type="library" name="com.android.support:support-core-ui-25.3.1" level="project" />
<orderEntry type="library" scope="TEST" name="com.squareup:javawriter:2.1.1@jar" level="project" />
<orderEntry type="library" name="com.android.support:support-compat-25.3.1" level="project" />
<orderEntry type="library" name="com.android.support.constraint:constraint-layout-solver:1.0.0-alpha7@jar" level="project" />
<orderEntry type="library" name="com.android.support:support-core-utils-25.3.1" level="project" />
<orderEntry type="library" name="com.android.support:support-v4-25.3.1" level="project" />
<orderEntry type="library" name="com.android.support:support-fragment-25.3.1" level="project" />
<orderEntry type="library" name="com.android.support:support-media-compat-25.3.1" level="project" />
<orderEntry type="library" scope="TEST" name="com.google.code.findbugs:jsr305:2.0.1@jar" level="project" />
<orderEntry type="library" scope="TEST" name="org.hamcrest:hamcrest-core:1.3@jar" level="project" />
<orderEntry type="library" scope="TEST" name="com.android.support.test.espresso:espresso-core-2.2.2" level="project" />
<orderEntry type="library" name="com.android.support:animated-vector-drawable-25.3.1" level="project" />
<orderEntry type="library" scope="TEST" name="com.android.support.test:rules-0.5" level="project" />
<orderEntry type="library" name="com.android.support:transition-25.3.1" level="project" />
<orderEntry type="library" name="com.android.support:design-25.3.1" level="project" />
<orderEntry type="library" scope="TEST" name="org.hamcrest:hamcrest-library:1.3@jar" level="project" />
<orderEntry type="library" scope="TEST" name="org.hamcrest:hamcrest-integration:1.3@jar" level="project" />
<orderEntry type="library" scope="TEST" name="com.android.support.test:runner-0.5" level="project" />
<orderEntry type="library" name="com.android.support:appcompat-v7-25.3.1" level="project" />
<orderEntry type="library" name="commons-collections:commons-collections:3.2.1@jar" level="project" />
<orderEntry type="library" scope="TEST" name="com.android.support.test.espresso:espresso-idling-resource-2.2.2" level="project" />
<orderEntry type="library" scope="TEST" name="javax.annotation:javax.annotation-api:1.2@jar" level="project" />
<orderEntry type="library" name="com.android.support:support-vector-drawable-25.3.1" level="project" />
<orderEntry type="library" name="com.android.support:recyclerview-v7-25.3.1" level="project" />
<orderEntry type="library" name="com.android.support:support-annotations:25.3.1@jar" level="project" />
<orderEntry type="library" name="com.android.support.constraint:constraint-layout-1.0.0-alpha7" level="project" />
</component>
</module>
32 changes: 32 additions & 0 deletions deserialization_receiver/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
apply plugin: 'com.android.application'

android {
compileSdkVersion 26
buildToolsVersion "26.0.2"
defaultConfig {
applicationId "ch.modzero.intent_receiver"
minSdkVersion 17
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha7'
compile 'com.android.support:design:25.3.1'
testCompile 'junit:junit:4.12'
compile 'commons-collections:commons-collections:3.2.1'
}
Binary file added deserialization_receiver/app/intent_receiver.apk
Binary file not shown.
25 changes: 25 additions & 0 deletions deserialization_receiver/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /home/work/Android/Sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Loading

0 comments on commit aadc16f

Please sign in to comment.