GitBook: [master] one page modified

This commit is contained in:
CPol 2021-04-21 15:06:12 +00:00 committed by gitbook-bot
parent 6ba898c8bd
commit f735b700ee
No known key found for this signature in database
GPG Key ID: 07D2180C7B12D0FF
1 changed files with 214 additions and 201 deletions

View File

@ -108,13 +108,219 @@ If developers, write in Java and the code is compiled to DEX bytecode, to revers
**Smali is the human readable version of Dalvik bytecode**. Technically, Smali and baksmali are the name of the tools \(assembler and disassembler, respectively\), but in Android, we often use the term “Smali” to refer to instructions. If youve done reverse engineering or computer architecture on compiled C/C++ code. **SMALI is like the assembly language: between the higher level source code and the bytecode**.
## Intents
Intents are the primary means by which Android apps communicate between their components or with other apps. These message objects can also carry data between apps or component, similar to how GET/POST requests are used in HTTP communications.
### Application Entry Points <a id="application-entry-points"></a>
So an Intent is basically a **message that is passed between components**. Intents **can be directed** to specific components or apps, **or can be sent without a specific recipient**.
To be simple Intent can be used:
One of the most important points of reverse engineering is knowing where to begin your analysis and entry points for code execution is an important part of that.
* To start an Activity, typically opening a user interface for an app
* As broadcasts to inform the system and apps of changes
* To start, stop, and communicate with a background service
* To access data via ContentProviders
* As callbacks to handle events
#### Content Provider <a id="services"></a>
Improper implementation could result in data leakage, restricted functions being called and program flow being manipulated.
[**Learn more about intents reading here.**](what-are-intents.md)\*\*\*\*
### Intent-Filter
An Intent Filter specify the **types of Intent that an activity, service, or Broadcast Receiver can respond to**. 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. Intent Filters are typically **defined via the AndroidManifest.xml file**. For **Broadcast Receiver** it is also possible to define them in **coding**. An Intent Filter is defined by its category, action and data filters. It can also contain additional metadata.
In Android, an activity/service/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** the component, thereby restricting access to the component.
### Implicit Intents
Intents are programatically created using an Intent constructor:
```java
Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
```
The **Action** of the previously declared intent is **ACTION\_SEND** and the **Extra** is a mailto **Uri** \(the Extra if the extra information the intent is expecting\).
This intent should be declared inside the manifest as in the following example:
```markup
<activity android:name="ShareActivity">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
```
An intent-filter needs to match the **action**, **data** and **category** to receive a message.
The "Intent resolution" process determine which app should receive each message. This process considers the **priority attribute**, which can be set in the i**ntent-filter declaration**, and t**he one with the higher priority will be selected**. This priority can be set between -1000 and 1000 and applications can use the `SYSTEM_HIGH_PRIORITY` value. If a **conflict** arises, a "choser" Window appears so the **user can decide**.
### Explicit Intents
An explicit intent specifies the class name it's targeting:
```java
Intent downloadIntent = new (this, DownloadService.class):
```
In other applications in order to access to the previously declared intent you can use:
```java
Intent intent = new Intent();
intent.setClassName("com.other.app", "com.other.app.ServiceName");
context.startService(intent);
```
### Pending Intents
These allow other applications to **take actions on behalf of your application**, using your app's identity and permissions. Constructing a Pending Intent it should be **specified an intent and the action to perform**. If the **declared intent isn't Explicit** \(doesn't declare which intent can call it\) a **malicious application could perform the declared action** on behalf of the victim app. Moreover, **if an action ins't specified**, the malicious app will be able to do **any action on behalf the victim**.
### Broadcast Intents
Unlike the previous intents, which are only received by one app, broadcast intents **can be received by multiple apps**. However, from API version 14, it's **possible to specify the app that should receive** the message using Intent.set Package.
Alternatively it's also possible to **specify a permission when sending the broadcast**. The receiver app will need to have that permission.
There are **two types** of Broadcasts: **Normal** \(asynchronous\) and **Ordered** \(synchronous\). The **order** is base on the **configured priority within the receiver** element. **Each app can process, relay or drop the Broadcast.**
It's possible to **send** a **broadcast** using the function **`sendBroadcast(intent, receiverPermission)`** from the `Context` class.
You could also use the function **`sendBroadcast`** from the **`LocalBroadCastManager`** ensures the **message never leaves the app**. Using this you won't even need to export a receiver component.
### Sticky Broadcasts
This kind of Broadcasts **can be accessed long after they were sent**.
These were deprecated in API level 21 and it's recommended to **not use them**.
**They allow any application to sniff the data, but also to modify it.**
If you find functions containing the word "sticky" like **`sendStickyBroadcast`** or **`sendStickyBroadcastAsUser`**, **check the impact and try to remove them**.
## Deep links / URL schemes
**Deep links allow to trigger an Intent via URL**. An application can declare an **URL schema** inside and activity so every time the Android device try to **access an address using that schema** the applications activity will be called:
![](../../.gitbook/assets/image%20%28141%29.png)
In this case the scheme in `myapp://` \(note also the **`category BROWSABLE`**\)
If inside the `intent-filter`you find something like this:
![](../../.gitbook/assets/image%20%28150%29.png)
Then, it's expecting something like `http://www.example.com/gizmos`
If you find something like this:
![](../../.gitbook/assets/image%20%28242%29.png)
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:
```markup
<a href="example://gizmos/https://google.com">click here</a>
<a href="example://gizmos/javascript://%250dalert(1)">click here</a>
```
In order to find the **code that will be executed in the App**, go to the activity called by the deeplink and search the function **`onNewIntent`**.
![](../../.gitbook/assets/image%20%28436%29%20%281%29%20%281%29%20%281%29.png)
Learn how to [call deep links without using HTML pages](./#exploiting-schemes-deep-links).
## AIDL - Android Interface Definition Language
The **Android Interface Definition Language** \(AIDL\) allows you to define the programming interface that both the client and service agree upon in order to **communicate with each other using interprocess communication** \(IPC\). On Android, **one process cannot normally access the memory of another process**. So to talk, they need to decompose their objects into primitives that the **operating system** can understand, and marshall the objects across that boundary for you. The code to do that marshalling is tedious to write, so Android handles it for you with AIDL.\).
Services using AIDL are referred to as **Bound Services**. In the Service's class you will find the **`onBind`** method. This is **where the interaction begins** so it's initial part of the code to review looking for potential vulnerabilities.
A bound service is the server in a client-server interface. **It allows components \(such as activities\) to bind to the service, send requests, receive responses, and perform interprocess communication** \(IPC\). A bound service typically lives only while it serves another application component and does not run in the background indefinitely.
### Messenger
A Messenger is another type of IPC mechanism. Since the **Messenger is also a "Bound Service"**, the data passed from the client app is also processed through the `onBind` method. So, the code review should start on this method and you should look for the invocation of sensitive functionality or unsafe handling of data.
### Binder
It's weird to find a Binder class directly invoked as it's much easier to use AIDL \(which abstracts the Binder class\). However, it's good to know that **Binder is a kernel-level driver which moves data from one process's memory to another's** \([https://www.youtube.com/watch?v=O-UHvFjxwZ8](https://www.youtube.com/watch?v=O-UHvFjxwZ8)\).
## Components
These include: **Activities, Services, Broadcast Receivers and Providers.**
### Launcher Activity and other activities
An **Android activity** is one screen of the **Android** app's user interface. In that way an **Android activity** is very similar to windows in a desktop application. An **Android** app may contain one or more activities, meaning one or more screens.
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 applications manifest. The launcher activity will have the following MAIN and LAUNCHER intents listed.
Keep in mind that not every application will have a launcher activity, especially apps without a UI. Examples of applications without a UI \(and thus a launcher activity\) are pre-installed applications that perform services in the background, such as voicemail.
```markup
<activity android:name=".LauncherActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
```
Activities can be exported allowing other processes on the device to launch the activity. By default, they aren't exported but you can export them setting:
```markup
<service android:name=".ExampleExportedService" android:exported="true"/>
```
Note that the ability to **bypass activity protections isn't always a vulnerability**, you need to check to which data you have obtained access.
Also, **some activities returns data to a caller**. In these scenarios you need to search for the **`setResult`** method and check the data that is passed into the Intent parameter. **If it's sensitive data you may have an information leakage vulnerability** and it's exploitable with apps capable of communicating with the Activity.
### Application Subclass
Android applications can define a **subclass** of [Application](https://developer.android.com/reference/android/app/Application). Applications can, but do not have to define a custom subclass of Application. If an Android app defines an Application subclass, t**his class is instantiated prior to any other class in the application**.
If the **`attachBaseContext`** method is defined in the Application subclass, it is called first, before the **`onCreate`** method.
### Services
[Services](https://developer.android.com/guide/components/services) **run in the background without a UI.** They are used to perform **long-running processes, even if the user starts using a different application**.
There is a myriad of ways that they can be started and thus are an entry point for applications. The default way that a service can be started as an entry point to an application is through **Intents**.
When the **`startService`** method is called to start a Service, the **`onStart`** method in the Service is executed. It will run indefinitely until the **`stopService`** method is called. If the service is only needed as long as the client is connected, the client should "bind" to it using the **`bindService`** method.
For a **bound service** \(see previous section\), the data will be passed to the **`onBind`** method.
For example, a service might play music in the background while the user is in a different application, or it might fetch data over the network without blocking user interaction with an activity.
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:
```markup
<service android:name=".ExampleExportedService" android:exported="true"/>
```
### Broadcast Receivers
Broadcasts can be thought of a messaging system and **broadcast receivers are the listeners**. If an application has registered a receiver for a specific broadcast, the code in that receiver is executed when the system sends the broadcast. Note that in this case **several apps can receive the same message**.
There are **2 ways** that an app can **register a receiver**: in the **apps Manifest or dynamically registered** in the apps code using the **`registerReceiver`** API call. In the manifest you can limit the broadcasts you accept through the u**se of permissions within the receiver element**. When **dynamically** defined you can **pass the permission to the `registerReceiver` method**.
In both cases, to register the receiver, the **intent filters for the receiver are set**. These intent filters are the broadcasts that should trigger the receiver.
When the specific broadcasts are sent that the receiver is registered for are sent, **`onReceive`** in the BroadcastReceiver class is **executed**.
An application may register a receiver for the low battery message for example, and change its behaviour based on that information.
Broadcast can be **asynchronous** \(every receiver receives it\) or **synchronous** \(the broadcast is received in an ordered manner based on the priority set to receive it\).
{% hint style="danger" %}
**Note that any application can set itself as top priority to receive a Broadcast.**
{% endhint %}
To **examine** the **code** implemented into a Broadcast Receiver you need to search for the **`onReceive`** method of the class of the receiver.
Note that **Ordered Broadcasts can drop the Intent received or even modify it** using one of the setter methods. Therefore, the **receivers should validate the data**.
### Content Provider
Content Providers are the way **apps share structured data**, such as relational databases. Therefore, it's very important to use **permissions** and set the appropriate protection level to protect them.
Content Providers can use the **`readPermission`** and **`writePermission`** attributes to specify which permissions an app must have. **These permissions take precedence over the permission attribute**.
@ -165,208 +371,15 @@ Sharing something like **`path="."`** could be **dangerous** even if the provide
You could **access** an **image** inside that folder with `content://com.example.myapp.fileprovider/myimages/default_image.jpg`asd
[More information about FileProviders here](https://developer.android.com/training/secure-file-sharing/setup-sharing).
#### AIDL <a id="services"></a>
#### <a id="services"></a>
**AIDL** \(Android Interface Definition Language\) describes the API offered by a Service to external applications. **AIDL enables IPC** \(InterProcess Communication\).
####
Services using AIDL are referred to as **Bound Services**. In the Service's class you will find the `onBind` method. This is **where the interaction begins** so it's initial part of the code to review looking for potential vulnerabilities.
####
#### Messenger
####
A Messenger is another type of IPC mechanism. Since the Messenger us also a "Bound Service", the data passed from the client app is also processed through the `onBind` method. So, the code review should start on this method and you should look for the invocation of sensitive functionality or unsafe handling of data.
#### Binder
It's weird to find a Binder class directly invoked as it's much easier to use AIDL \(which abstracts the Binder class\). However, it's good to know that Binder is a kernel-level driver which moves data from one process's memory to another's \([https://www.youtube.com/watch?v=O-UHvFjxwZ8](https://www.youtube.com/watch?v=O-UHvFjxwZ8)\).
#### Components
These include: Activities, Services, Broadcast Receivers and Providers.
#### Launcher Activity and other activities <a id="launcher-activity"></a>
An **Android activity** is one screen of the **Android** app's user interface. In that way an **Android activity** is very similar to windows in a desktop application. An **Android** app may contain one or more activities, meaning one or more screens.
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 applications manifest. The launcher activity will have the following MAIN and LAUNCHER intents listed.
Keep in mind that not every application will have a launcher activity, especially apps without a UI. Examples of applications without a UI \(and thus a launcher activity\) are pre-installed applications that perform services in the background, such as voicemail.
```markup
<activity android:name=".LauncherActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
```
Activities can be exported allowing other processes on the device to launch the activity. By default, they aren't exported but you can export them setting:
```markup
<service android:name=".ExampleExportedService" android:exported="true"/>
```
Note that the ability to bypass activity protections isn't always a vulnerability, you need to check to which data you have obtained access.
Also, some activities returns data to a caller. In these scenarios you need to search for the setResult method and check the data that is passed into the Intent parameter. IF it's sensitive data you may have an information leakage vulnerability and it's exploitable with apps capable of communicating with the Activity.
#### Services
[Services](https://developer.android.com/guide/components/services) run in the background without a UI. They are used to perform long-running processes, even if the user starts using a different application.
There is a myriad of ways that they can be started and thus are an entry point for applications. The default way that a service can be started as an entry point to an application is through [Intents](https://developer.android.com/guide/components/intents-filters).
When the `startService` method is called to start a Service, the `onStart` method in the Service is executed. It will run indefinitely until the stopService method is called. If the service is only needed as long as the client is connected, the client should "bind" to it using the bindService method.
For a "bound" service, the data will be passed to the onBind method.
For example, a service might play music in the background while the user is in a different application, or it might fetch data over the network without blocking user interaction with an activity.
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:
```markup
<service android:name=".ExampleExportedService" android:exported="true"/>
```
#### Application Subclass <a id="application-subclass"></a>
Android applications can define a subclass of [Application](https://developer.android.com/reference/android/app/Application). Applications can, but do not have to define a custom subclass of Application. If an Android app defines a Application subclass, this class is instantiated prior to any other class in the application.
If the `attachBaseContext` method is defined in the Application subclass, it is called first, before the `onCreate` method.
#### Intents
Intent is basically a message that is passed between components \(such as Activities, Services, Broadcast Receivers, and Content Providers\). Intents can be directed to specific components or apps, or can be sent without a specific recipient.
To be simple Intent can be used:
* To start an Activity, typically opening a user interface for an app
* As broadcasts to inform the system and apps of changes
* To start, stop, and communicate with a background service
* To access data via ContentProviders
* As callbacks to handle events
Improper implementation could result in data leakage, restricted functions being called and program flow being manipulated.
[**Learn more about intents reading here.**](what-are-intents.md)\*\*\*\*
#### Intent Filter
An IntentFilters 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 an 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.
#### Implicit Intents
Intents are programatically created using an Intent constructor:
```java
Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
```
The **Action** of the previously declared intent is **ACTION\_SEND** and the **Extra** is a mailto **Uri** \(the Extra if the extra information the intent is expecting\).
This intent should be declared inside the manifest as in the following example:
```markup
<activity android:name="ShareActivity">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
```
An intent-filter needs to match the **action**, **data** and **category** to receive a message.
The "Intent resolution" process determine which app should receive each message. This process considers the priority attribute, which can be set in the intent-filter declaration, and the one with the higher priority will be selected. This priority can be set between -1000 and 1000 and applications can use the `SYSTEM_HIGH_PRIORITY` value. If a conflict arises, a "choser" Window appears so the user can decide.
#### Explicit Intents
An explicit intent specifies the class name it's targeting:
```java
Intent downloadIntent = new (this, DownloadService.class):
```
In other applications in order to access to the previously declared intent you can use:
```java
Intent intent = new Intent();
intent.setClassName("com.other.app", "com.other.app.ServiceName");
context.startService(intent);
```
#### Pending Intents
These allow other applications to **take actions on behalf of your application**, using your app's identity and permissions. Constructing a Pending Intent it should be **specified an intent and the action to perform**. If the **declared intent isn't Explicit** \(doesn't declare which intent can call it\) a **malicious application could perform the declared action** on behalf of the victim app. Moreover, **if an action ins't specified**, the malicious app will be able to do **any action on behalf the victim**.
#### Intent Broadcast Receivers <a id="broadcast-receivers"></a>
Broadcasts can be thought of a messaging system and [broadcast receivers](https://developer.android.com/guide/components/broadcasts#receiving-broadcasts) are the listeners. If an application has registered a receiver for a specific broadcast, the code in that receiver is executed when the system sends the broadcast. Note that in this case **several apps can receive the same message**.
From API version 14, it's **possible to specify the app that should receive** the message using Intent.set Package.
There are **two types** of Broadcasts: **Normal** \(asynchronous\) and **Ordered** \(synchronous\). The order is base on the configured priority within the receiver element. Each app can process, relay or drop the Broadcast.
It's possible to **send** a **broadcast** using the function **`sendBroadcast(intent, receiverPermission)`** from the `Context` class.
You could also use the function `sendBroadcast` from the **`LocalBroadCastManager`** ensures the **message never leaves the app**. Using this you won't even need to export a receiver component.
There are 2 ways that an app can register a receiver: in the apps Manifest or dynamically registered in the apps code using the `registerReceiver()` API call.
In both cases, to register the receiver, the intent filters for the receiver are set. These intent filters are the broadcasts that should trigger the receiver.
When the specific broadcasts are sent that the receiver is registered for are sent, `onReceive` in the BroadcastReceiver class is executed.
An application may register a receiver for the low battery message for example, and change its behaviour based on that information.
{% hint style="danger" %}
Note that any application can set itself as top priority to receive a Broadcast.
{% endhint %}
Broadcast Receivers can be statically defined in the `AdroidManifest.xml` file or dynamically using the `registerReceiver` method. In the manifest you can limit the broadcasts you accept through the use of permissions within the receiver element, When dynamically defined you can pass the permission to the registerReceiver method.
To examine the code implemented into a Broadcast Receiver you need to search for the onReceive method of the class of the receiver.
Note that Ordered Broadcasts can drop the Intent received or even modify it using one of the setter methods. Therefore, the receivers should validate the data.
#### Sticky Broadcasts
This kind of Broadcasts **can be accessed long after they were sent**.
These were deprecated in API level 21 and it's recommended to **not use them**.
**They allow any application to sniff the data, but also to modify it.**
If you find functions containing the word "sticky" like **`sendStickyBroadcast`** or **`sendStickyBroadcastAsUser`**, **check the impact and try to remove them**.
#### URL schemes / Deep links
**Deep links allow to trigger an Intent via URL**. An application can declare an **URL schema** inside and activity so every time the Android device try to **access an address using that schema** the applications activity will be called:
![](../../.gitbook/assets/image%20%28141%29.png)
In this case the scheme in `myapp://` \(note also the category BROWSABLE\)
If inside the `intent-filter`you find something like this:
![](../../.gitbook/assets/image%20%28150%29.png)
Then, it's expecting something like `http://www.example.com/gizmos`
If you find something like this:
![](../../.gitbook/assets/image%20%28242%29.png)
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:
```markup
<a href="example://gizmos/https://google.com">click here</a>
<a href="example://gizmos/javascript://%250dalert(1)">click here</a>
```
In order to find the **code that will be executed in the App**, go to the activity called by the deeplink and search the function **`onNewIntent`**.
![](../../.gitbook/assets/image%20%28436%29%20%281%29%20%281%29%20%281%29.png)
Learn how to [call deep links without using HTML pages below](./#exploiting-schemes-deep-links).
###
### WebViews