Android DropBox SDK Vulnerability (CVE-2014-8889) Analysis
0x00 Preface
This article is a translation of the detailed analysis of DropBox SDK vulnerabilities by the ibm iss security team.
Today, personal data is stored on the cloud, so that services such as photo backup and general storage can be accessed by users and apps that represent users. In many aspects, the interoperability between apps and services, including access control functions, is always challenging. To address the challenges posed by access control, authorization protocols such as OAuth1 and 2 are gradually proposed, they can securely grant the app the permission to access personal data in a specific service without disclosing the user's personal creden. To facilitate development, these services generally provide a framework or SDK for the app to enable the app to communicate with the service. For app developers, the SDK is attractive because it abstracts internal details and provides developers with simple client APIs. From the security point of view, the SDK provides an attractive attack surface, because once a vulnerability is available, it can affect a large number of apps that use the SDK.
This article introduces a serious vulnerability (CVE-2014-8889) in Android Dropbox SDK 1.5.4-1.6.1, which exposes Dropbox SDK-based apps to severe local and remote attacks. As proof of concept (POC), we have developed remote attack programs for popular apps including Microsoft Office Mobile and 1 password. We reported the vulnerability to Dropbox responsibly, and Dropbox also provided a fixed SDK (version 1.6.2) in a timely manner ). It is strongly recommended that developers download the SDK and update its app.
0x01 background
The Dropbox SDK is a library for developers to download and use for their products. It uses a simple set of APIs to easily use the Dropbox service, such as downloading or uploading files.
AppBrain statistics show the popularity of the Dropbox SDK in Android [1]. 0.31% of all apps use the Dropbox SDK. In the first 500 of Google Play apps, 1.41% used the Dropbox SDK. Interestingly, according to the installation quantity statistics, Dropbox SDK is used for 1.32% of the total quantity and 500 of the first 3.93% of the application installation quantity.
Although the Dropbox SDK is not a highly popular basic software library, some very popular Android apps still use the Dropbox SDK to hold sensitive data, including [Microsoft Office Mobile] (https: // https://play.google.com/store/apps/details? Id = com. microsoft. office. officehub), and an AgileBits 1 Password with 100,000 downloads.
This vulnerability affects all Android apps using the Dropbox SDK 1.5.4-1.6.1. We analyzed 41 apps using the Android Dropbox SDK (they use version 1.5.4-1.6.1), and 31 of them (76%) were successfully attacked ). It should be noted that other apps still have vulnerabilities and can be exploited by simple attacks with the same consequences, but these apps have not been upgraded to version 1.5.4 to fix the vulnerabilities.1.
The structure of this article is as follows. Chapter 2 introduces the background of cross-application communication (IAC) in Android, and Chapter 3 introduces how IAC is locally exploited by malicious code and Remote drive-by attack, chapter 4 describes how the Dropbox SDK uses OAuth to grant permissions to Android apps. Chapter 5 provides an in-depth analysis of the Android Dropbox SDK vulnerability in OAuth code, chapter 6 describes the actual attacks that we call DROPPEDIN to exploit this vulnerability. Chapter 7 describes the cases that reflect the real threats. Finally, Chapter 8 describes how to fix the vulnerability.
0x02 Cross-Application Communication (IAC) in Android)
Android applications are executed in the sandbox environment. The Sandbox ensures the confidentiality and integrity of application data. If you do not configure proper permissions, an application cannot access sensitive information of other applications. For example, the sensitive information in the Android Stock browser, such as cookies, caches, and history, will not be accessed by third-party apps. The Sandbox mechanism relies on a variety of technologies, including application-based Linux user-id allocation. Therefore, by default, resources (such as files) of an application are not accessed by other applications. Although the sandbox mechanism is conducive to security, some interoperability is also sacrificed for apps that sometimes need to communicate with each other. Return to the example of the Stock browser. When a user accesses the Google Play URL through a browser, the Google Play app may need to be opened. To support this type of interoperability, android provides a high-level cross-application communication (IAC) mechanism. Generally, it encapsulates information about loads and target application components and is called a special message of Intent. Intent can be explicitly specified. In this case, the target application component must be explicitly specified or implicitly specified. In this case, the target application does not need to be explicitly specified, the Android system depends on the URI scheme, action, or category in the Intent parameter.
0x03 cross-application communication attacks
If attackers can control Intent loads and directly start application components, the attack surface will be extended, especially for application components in the Export (exported) state. These exported components are vulnerable to local attacks by malicious applications. The Android COMPONENT Activity responsible for UI screens can also be remotely attacked by drive-by. For details, see [2, 3].
In local attacks, as shown in Figure 3.1, a malicious application starts an exported target application by using a malicious Intent (including malicious data), which only requires simple API calls, such as Context. startActivity (intent)
Figure 3.1 local attacks against malicious applications
In the remote drive-by attack shown in Figure 3.2, users are spoofed to browse malicious websites. Web pages of malicious websites enable browsers to send malicious Intent and start the target activity.2
Figure 3.2 Remote Drive-by Attack
0x04 OAuth and Dropbox
To authorize the app to use a specified Dropbox account, the Dropbox SDK uses the OAuth protocol. This process starts when the app registers with the Dropbox website for out-of-band registration, then, the app can receive the app key and app secret from Dropbox and hardcode them into the code.
Then the app will export the AuthActivity used by Dropbox In the Android Manifest file, as shown below.
<activity android:name="com.dropbox.client2.android.AuthActivity" ...> <intent-filter> <data android:scheme="db-<APP_KEY >" /> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.BROWSABLE" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
Figure 4.1 describes the parties to the Dropbox OAuth protocol and the communication process. This process starts when the app carries the necessary data (that is, the app key and app secret) call the static method start {oau2} Authentication in the Dropbox SDK AndroidAuthSession. This method uses an Intent to start the AuthActivity, and then the AuthActivity generates a nonce random number, start the browser or Dropbox app (if installed) through an Intent, authenticate the user and authorize the app. This process uses the previously generated nonce. The browser or Dropbox app will use the implicit Intent pointing to the unique URI scheme (db-) of the app to return access token, secret, And nonce carrying additional data (such as uid. This will cause the OnNewIntent method of AuthAcitivity to be called. This method will check whether the input nonce is consistent with the output nonce. If they are consistent, it accepts the token and stores it in its static result variable. The token will be saved in the Dropbox session for the next Dropbox SDK call.
Figure 4.1 Dropbox OAuth
This process has two major threats. First, the returned OAuth access token may be stolen, which allows attackers to access authorized Dropbox resources. Malicious apps can use a registered Intent filter to perform such attacks on fake apps. However, because the Dropbox SDK can check whether other applications have registered the same Intent filter, the risk of this threat has been mitigated. Second, attackers can inject their own access tokens, which will cause the app to connect to the attacker's account and upload sensitive data to the attacker without authorization, or download the data to further launch other attacks. Due to the existence of the nonce parameter (introduced in version 1.5.4), the risk of this threat has been mitigated. However, there is still a vulnerability in the specific implementation. Attackers can take the initiative to expose the nonce parameter of the Dropbox SDK to the server controlled by the attacker, which will be described in the next chapter.
0x05 Vulnerability Analysis
One of the vulnerabilities we found was identified as CVE-2014-8889, allowing attackers to inject an arbitrary access token into the AuthActivity of the Dropbox SDK, completely bypassing nonce protection.
AuthAcitivity accepts several different Intent extra parameters as an exported and browasable activity (required as described in Chapter 4). It can carry any Intent extra parameter (see chapter 3) therefore, you must be careful when using these Intent extra parameters.
However, an Intent extra parameter named INTERNAL_WEB_HOST can be controlled by attackers, resulting in destructive effects. When the browser is used to authenticate users and authorize apps (when the Dropbox app is not installed), this parameter ultimately controls the address accessed by the user's browser, such as appendix, the startWebAuth method is called by the OnResume callback method of the AuthActivity (called after the Intent starts the Activity. Therefore, if an attacker can generate an Intent for the activity and direct INTERNAL_WEB_HOST extra to the server controlled by the attacker, the nonce will be sent to the attacker's server during authentication!
0x06 DROPPEDIN attacks
We have implemented both local and remote drive-by attacks. Both of these attacks require that the attacked device cannot install the Dropbox app, and require the attacker to obtain the access token (ACCESS_TOKEN_KEY, ACCESS_TOKEN_SECRET) in an out-of-band manner in advance ), and uid related to the account and the attacked app. This step is easy because attackers can simply download the attacked app to their own device, authorize their Dropbox account to use it, and record the returned access token pair. 6.1 remote attacks are carried out in four steps. Local attacks are similar, but malicious applications must be installed on the attacked devices.
Figure 6.1 Droppedin attack
6.1 natural web browsing
Attackers can access malicious websites that are completely controlled by attackers, or exploit vulnerabilities (such as XSS) to implant malicious code.
6.2 active Nonce Leakage
Malicious Code carries special Intent parameters that enable the user's browser to launch the attacked app and enable subsequent OAuth processes to be performed between the server controlled by the attacker, rather than the normal https://www.dropbox.com. This step allows attackers to obtain nonce. You can achieve this through simple HTTP redirection to the following code: Intent: # Intent; scheme = db-<APP_KEY>; S. EXTRA_INTERNAL_WEB_HOST =; S. EXTRA_INTERNAL_APP_KEY = foo; S. EXTRA_INTERNAL_APP_SECRET = bar; end
As of writing this article, most popular browsers support the implicit Intent of the above Intent URI scheme mechanism.
6.3 Auth Access Token Injection
The above Intent will eventually allow the browser to access https: // attacker: 443/1/connect (and include nonce in the get parameter), which requires the attacker to have his own SSL certificate, but this is also very easy. After obtaining the nonce, attackers can use another HTTP to redirect to the following code and inject their own pre-generated access tokens to the app.
db-<APP_KEY>://1/connect?oauth_token_secret=<ACCESS_TOKEN_SECRET> &oauth_token=<ACCESS_TOKEN_KEY> &uid=<UID> &state=<NONCE>
If the access token is successfully injected, it is saved in AuthActivity. result.
6.4 The App uses OAuth Access Token
So far, the result of the static member variable of AuthActivity contains the token of the attacker. The rest is how the attacked app uses the data, depending on the developer.
It is not ruled out that there are other cases, but in general, the client (app) code will initiate the authentication process when one of the onCreate methods of the Activity or when the user clicks some buttons. Next, check whether the authentication is successful and use the token in its onResume Method for Dropbox sessions.
The key to successful attacks is that the onCreate and onResume methods are called in sequence (see [4, 6]). This indicates that, once an attacker injects his access token before the activity of the app is displayed, the access token will be used before the user inputs his/her creden. For details, refer to the Case Study in Chapter 7th.
0x07 Case Study 7.1 Mircrosoft Office Mobile: inject and add new connections
Microsoft Office Mobile app allows users to upload their documents to the cloud and supports multiple Dropbox accounts.
In this case, the following steps are normally performed in the following order:
1. the user adds the Dropbox account, which will start the activity responsible for Dropbox authentication. 2. The onCreate method of the activity calls the startOAuth2Authentication method in the SDK AndroidAuthSession. 3. Call the onResume method of acitivity to check whether the authentication is successful through the authenticationSuccessful method of AndroidAuthSession. The latter returns a negative value. 4. the user logs on to Dropbox authentication through a browser and authorizes the app to use its own account. 5. The onResume method of the activity is called again. At this time, authenticationSuccessful returns a positive value. The token copies the AuthActivity to the session object for the app to use. Destroy Activity. 6. The account is added to the app by calling activity. finish.
This process can be attacked as follows. Before the first step, attackers inject their tokens through the vulnerability. The user then adds a new Dropbox account. Normally, the user will be directed to the Dropbox official website. However, the third step can occur in the background without the user's consent, the authentication method is called successfully. The attacker's token is copied to the session object, and the activity is destroyed, even in step 5. Therefore, even if the user inputs his/her own authentication creden。, the attacker's token is used to make the attack happen seamlessly.
7.2 1 Password: injected before the first connection 1 Password app is a Password management app (such as KeyPass). You can use the Dropbox SDK to synchronize your vault (keystore) to Dropbox. This app supports synchronizing a local keystore to Dropbox using a Dropbox account. Uploading a keystore to an attacker's account can have a catastrophic impact-attackers can perform offline cracking. If a weak master password is used (this is still a common problem []), attackers can successfully crack the attack within the feasible time. In addition, attackers can perform phishing attacks to obtain the primary protection password.
Similar to Section 7.1, the following steps occur in sequence when a user decides to synchronize data:
1. Click "Synchronize to Dropbox" to start the activity responsible for Dropbox authentication. 2. The onCreate method of the activity checks whether it is connected through AndroidAuthSession. isLinked. If no, the startAuthentication method of AndroidAuthSession is called.
3. Call the onResume method of the activity and call AndroidAuthSession. isLinked () again (). If false is returned, the AnroidAuthSession. authenticationSucessful () method is used to check whether the authentication is successful. The latter returns a negative value.
4. the user logs on to Dropbox authentication through a browser and authorizes the app to use its own account.
5. The onResume method of the activity is called, and AndroidAuthSession. isLinked () returns false again. However, the authenticationSuccessful () method returns a positive value. The app then calls finishAuthentication to copy the token to the session object (this will cause the isLinked method to return true), so the app uses the token.
6. The synchronization process starts.
This process can be attacked as follows. Before the first step, attackers can exploit the vulnerability to inject their tokens. The user then synchronizes his account. Normally, he will be directed to the Dropbox official website. However, if step 3 can occur in the background without the user's consent, the authentication method will be called successfully, the attacker's token is copied to the session object, causing the isLinked method in step 5 to return true. Therefore, even if the user inputs his/her own authentication creden。, the attacker's token is used to make the attack happen seamlessly.
7.3 DBRoulette: inject and connect again The DBRoulette app and Dropbox SDK are packaged together as an example application. It is an app with basic functions. It authenticates users and randomly loads a photo from the user's Dropbox photo folder. In the main activity DBRoulette, The onResume method simply overwrites the pre-stored authentication credente, which means that even if the Dropbox account has been connected to DBRoulette, the attacker's account can still be used. In addition, the code that DBRoulette calls the Dropbox SDK authentication method is located in an exported activity. Attackers can start this activity to launch a fully automated attack. Figure 7.1 describes a successful attack. The attacker's account's finger photos appear in DBRoulette, instead of the victim's own photos.
Figure 7.1 attacked DBRoulette
0x08 repair Android Dropbox SDK 1.6.2 has been released, including fixing the vulnerability. The AuthActivity method of the Dropbox SDK does not accept the extra parameter of the Intent, which makes it impossible for attackers to obtain the nonce through the server address that the Dropbox SDK communicates. It is strongly recommended that developers update their Dropbox SDK to the latest version. To prevent apps that do not update the SDK from being exploited by this vulnerability, end users can install the Dropbox app to invalidate the attack.
0x09 disclosure time 2014.12.1-report the vulnerability to the vendor. 2014.12.1-the vendor confirms and starts to compile the patch. 2014.12.5-patch availability (Android Dropbox SDK 1.6.2) 2015.3.11-public disclosure.
0x10 thanks Dropbox's response to security threats was impressive. we reported this issue to Dropbox, and we received a response in just 6 minutes. The vulnerability was confirmed within 24 hours, and the patch was available four days later. Thanks to the Dropbox team, this is the fastest patch we have ever seen, and they are undoubtedly responsible for user security.
References 1. AppBrain. Dropbox API-Android library statistics. http://www.appbrain.com/stats/libraries/ details/dropbox_api/dropbox-api.
2. Takeshi Terada. Attacking Android browsers via intent scheme URLs. 2014. http://www.mbsd.jp/Whitepaper/IntentScheme.pdf.
3. Roee Hay & David Kaplan. Remote exploitation of the cordova framework. 2014. http: // www. slideapps.net/ibmsecurity/remote-exploitation-of-the-cordova-framework.
4. Android. Activity. http://developer.android.com/reference/android/app/Activity.html.
5. Trustwave. 2014 business password analysis, 2014. https://gsr.trustwave.com/topics/ business-password-analysis/2014-business-password-analysis /.
Appendix A: vulnerability-specific Dropbox SDK code
protected void onCreate(Bundle savedInstanceState) { ... Intent intent = getIntent(); ... webHost = intent.getStringExtra(EXTRA\_INTERNAL\_WEB\_HOST); if (null == webHost) { webHost = DEFAULT\_WEB_HOST; } ... } protected void onResume() { ... String state = createStateNonce(); ... if (hasDropboxApp(officialIntent)) { startActivity(officialIntent); } else { startWebAuth(state); } ... authStateNonce = state; } private void startWebAuth(String state) { String path = "/connect"; Locale locale = Locale.getDefault(); String[] params = { "locale", locale.getLanguage()+"_"+locale.getCountry(), "k", appKey, "s", getConsumerSig(), "api", apiType, "state", state}; String url = RESTUtility.buildURL(webHost, DropboxAPI.VERSION, path, params); Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); startActivity(intent); }
From the context, this vulnerability does not refer to the CVE-2014-8889 analyzed in this article.
For more information about this attack technique, see Intent scheme URL attack.
From the content in this Article, the term "Link" indicates that the app establishes a relationship with a Dropbox account, that is, the app uses this account to access the Dropbox service.