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