Skip to content

Application Components

Application Components

  • Activity: Point of user interaction with the application, most commonly through a UI screen or window
  • Broadcast Receiver: Listens for and receives messages from
    applications and the Android system
  • Content Provider: Application data storage (SQLite databases)
  • Service: Operates in the background to provide long-running
    application functionality without user interaction

Parameters: Look for putExtra(key, value), get*Extra(key) or getData() to see what parameters are taken from a Android Intent. Look for getQueryParameter for parameters names.

Activities

These Activities must be declared in the Manifest file. These are the UI views that can be shown to the user. The start funciton of the app is a Activity that can be called by any application. This is how a homescreen opens the app when the icon is pressed.

Activity Lifecycle:
- onCreate(): When the Activity Starts this function is called.

  • onStart(): When the Activity Starts this function is called after onCreate(). This is run when the activity is shown to the user.
  • onResume(): This is called when the Activity is foregrounded after onStart(). This is also called when the app is running but switches from another Activity.
  • onPause(): This is run when the Application starts another activity, switches to another application, when receiving a phone call, or the device screen’s turning off.
  • onStop(): This occurs when the a new activity covers the entire screen or when the activity has finished running.
  • onDestroy(): This occurs after the onStop callback.

android:exported
- If set to true this Activity be launched by another application.
- If this has an intent-filter in it then it is exported by default
- If set to false can only be launched by components of the same application or the same user ID. This is the default value.
- Look for getString

Security

Get Activity information from a Application:

dz> run app.activity.info --package com.cisco.webex.meetings
Package: com.cisco.webex.meetings
	com.cisco.webex.meetings.ui.premeeting.welcome.WebExMeeting
		Permission: null
	com.cisco.webex.meetings.ui.integration.AssistantActivity
		Permission: null
	com.cisco.webex.meetings.ui.integration.DeepLinkActivity
		Permission: null
	com.cisco.webex.meetings.ui.integration.IntegrationActivity
		Permission: null
	com.cisco.webex.meetings.ui.integration.IntegrationInternalActivity
		Permission: com.cisco.webex.permission.INTERNAL_BROADCAST
	com.cisco.webex.meetings.ui.integration.IntegrationWrapAccountActivity
		Permission: null
	com.cisco.webex.meetings.ui.premeeting.ShortcutActivity
		Permission: null
	com.microsoft.identity.client.BrowserTabActivity
		Permission: null
	com.smartdevicelink.transport.USBAccessoryAttachmentActivity
		Permission: null

Launch an Activity with Drozer:

dz> run app.activity.start --component com.cisco.webex.meetings com.cisco.webex.meetings.ui.premeeting.welcome.WebExMeeting
dz> run app.activity.start --component com.cisco.webex.meetings com.cisco.webex.meetings.ui.integration.AssistantActivity
dz> run app.activity.start --component com.example.app.client com.example.app.client.ui.SettingsActivity --extra string Uri "file:///sdcard/Download/nm_settings.json"

Start an Activity from the commandline:

am start -n com.example.app.client/.ui.SettingsActivity -a android.intent.action.VIEW -d file:///sdcard/Download/nm_settings.json
am start -n com.example.app.client/.ui.ImportUserCertificateActivity -a android.intent.action.VIEW -d file:///sdcard/Download/crt.p12 --eu Password test --ez Standalone True
adb shell am start -n com.quora.android/com.quora.android.ModalContentActivity -e url 'http://test/test' -e html '<script>alert(QuoraAndroid.getClipboardData());</script>'

Finding an Activity in Code:
- startActivity()
- getExtras()

Launch Activity PoC

public Class MainAcitivity extends AppCampatActivity {
	public static final String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstatnceState);
		setContentView(R.layout.activity_main);
	}

	/** Called when the user taps the Send button */
	public void sendMessage(View view){
		Intent intent = new Intent(this, DisplayMessageActivity.class);
		EditText editText = (EditText) findViewById(R.id.editText);
		String message = editText.getText().toString;
		intent.putExtra(EXTRA_MESSAGE, message);
		startActivity(intent);
	}

}

Fragments

These are partial UI views similar to Activities but don't need to be declared in the Manifest File.

FLAG_SECURE: On an fragment prevents information from being shown on the application switcher.

Broadcast/Intent Receiver

  • Enable applications to receive messages/triggers that are broadcast by the system or by other applications,
    • This can happen when the application is not running.
    • Example getting a text message, incoming call, or a notification
  • Can be created in the Manifest file or by Code.
  • This information is not secret since it can be listened to by other applications on the device

android:exported
- If set to true this Receiver can receive intents from other applications. This is the default value if their are intent filters.
- If set to false can only be launched by components of the same application or the same user ID. This is the default value if their are no intent filters.

Security

List Broadcast Receiver in a Application:

dz> run app.broadcast.info --package com.cisco.webex.meetings
Package: com.cisco.webex.meetings
	com.cisco.webex.meetings.receiver.MeetingStatusUpdater
		Permission: com.cisco.webex.permission.INTERNAL_BROADCAST
	com.cisco.webex.meetings.receiver.LocaleChangeReceiver
		Permission: com.cisco.webex.permission.UI_BROADCAST
	com.cisco.webex.meetings.receiver.SendLogStatusReceiver
		Permission: com.cisco.webex.permission.UI_BROADCAST
	com.cisco.webex.meetings.receiver.MeetingWidgetProvider
		Permission: com.cisco.webex.permission.INTERNAL_BROADCAST
	com.cisco.webex.meetings.SdlReceiver
		Permission: null
	com.cisco.webex.meetings.receiver.AppIndexingUpdateReceiver
		Permission: com.google.android.gms.permission.APPINDEXING
	com.cisco.webex.meetings.receiver.CreateShortcutReceiver
		Permission: com.cisco.webex.permission.UI_BROADCAST
	com.cisco.webex.meetings.receiver.MeetingAutoEndReceiver
		Permission: com.cisco.webex.permission.UI_BROADCAST
	com.google.firebase.iid.FirebaseInstanceIdReceiver
		Permission: com.google.android.c2dm.permission.SEND
	com.google.android.gms.measurement.AppMeasurementInstallReferrerReceiver
		Permission: android.permission.INSTALL_PACKAGES

Sending a Broadcast from the commandline:

adb shell am broadcast -a com.whereismywifeserver.intent.TEST --es sms_body "test from adb"

Sending a Broadcast from Drozer:

dz> run app.broadcast.send --action (broadcast receiver name) --extra (number of arguments)

Code Review

  • Check AndroidManifest for <intent-filter> this limits what the service is subscribed to.
  • Check the onReceive function to see what is pulled from the context and the Intent.

Checking in Code:
- BroadcastReceiver
- onReceive
- IntentFilter
- .addAction
- registerReciever

Services

  • Must be declared in the Manifest file.
  • Is a background task that can be run when not in the foreground.
  • Is started using Intents

Viewing Android Services:

>>> adb shell service list
Found 138 services:
0	nfc: [android.nfc.INfcAdapter]
1	cneservice: [com.quicinc.cne.ICNEManager]
2	ims: [com.android.ims.internal.IImsService]
3	timezone: [android.app.timezone.IRulesManager]
4	otadexopt: [android.content.pm.IOtaDexopt]
5	android.service.gatekeeper.IGateKeeperService: []
6	AtCmdFwd: [com.qualcomm.atfwd.IAtCmdFwd]
7	sip: [android.net.sip.ISipService]
[...]

android:exported
- If set to true this Activity be launched by another application. This is the default value if their are intent filters.
- If set to false can only be launched by components of the same application or the same user ID. This is the default value if their are no intent filters.

android:permission
- specifies if the caller needs a specific permission to launch the service. By default the service is not protected by a permission.

Security

List all services from an application:

dz> run app.service.info --package com.cisco.webex.meetings
Package: com.cisco.webex.meetings
	com.cisco.webex.meetings.SdlRouterService
		Permission: null
	com.cisco.webex.meetings.service.AccountAuthenticatorService
		Permission: com.cisco.webex.permission.INTERNAL_BROADCAST
	com.cisco.webex.meetings.service.AccountSyncAdapterService
		Permission: com.cisco.webex.permission.INTERNAL_BROADCAST
	com.cisco.webex.meetings.service.WBXUrlApiService
		Permission: null
	com.cisco.webex.meetings.service.WBXInfoService
		Permission: null
	com.cisco.webex.meetings.service.WBXService
		Permission: null
	com.cisco.webex.meetings.service.WBXUrlApiSecureService
		Permission: com.cisco.webex.permission.UI_BROADCAST
	com.cisco.webex.watch.adapter.PhoneWearableService
		Permission: null
	com.cisco.webex.notification.WbxFirebaseMessagingService
		Permission: null

Start a Service from Commandline:

adb shell am startservice android.nfc.INfcAdapter

Start a Service from Drozer:


Start Service PoC

Intent intent = new Intent(this, HelloService.class);
startService(intent);

Content Providers

  • Usually connected to a database

Can be viewed from content://com.example.app.provider/table1/1 or content://com.example.app.provider/table2/*

Read from the Provider:

>>> content query --uri content://com.yahoo.mobile.client.android.weather.provider.Weather/locations/
>>> content query --uri content://settings/secure --projection name:value --where "name=\'new_setting\'" --sort "name ASC"
>>> content query --uri content://com.yahoo.mobile.client.android.weather.provider.Weather/locations/ --sort "_id"                                                                                       
>>> content query --uri content://com.yahoo.mobile.client.android.weather.provider.Weather/locations/ --sort '_id/**/limit/**/\(select/**/1/**/from/**/sqlite_master/**/where/**/1=1\)'                   
>>> content query --uri content://com.yahoo.mobile.client.android.weather.provider.Weather/locations/ --sort '_id/**/limit/**/\(select/**/1/**/from/**/sqlite_master/**/where/**/1=2\)'

Write to the Provider:

>>> content insert --uri content://settings/secure --bind name:s:new_setting --bind value:s:new_value

>>> content update --uri content://settings/secure --bind value:s:newer_value --where "name='new_setting'"

>>> content delete --uri content://settings/secure --where "name='new_setting'"

Check to see if there is a Permission to Read and Write the Provider. If not then any application can read and write these values.

Security

Detect SQL injections in content providers:

dz> run scanner.provider.injection -a (package name)
dz> run scanner.provider.traversal -a com.mwr.example.sieve

Checking in Code:
- Grep for ContentProvider
- Grep for onReceive

Note

This is exported by default if the targetSDK is less than 17*

File Provider

A file provider allows other application to access specific files and folders.

To view a file from this Provider try content://com.example.myapp.fileprovider/myimages/default_image.jpg