blob: 3a61311a0a2f27fd1a109e17fdc7ff9e3969526d [file] [log] [blame]
/**
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.security.cts;
import com.android.tradefed.device.ITestDevice;
/*
* Adding Tests:
* We are testing a series of exploits that all take advantage of binder in the
* same way, using a malformed parcel to get system permission, with the only
* difference being the details of how we create the malformed parcel. In order
* to take advantage of these similarities (among other reasons) we share code
* between these exploits with an app that only requires two things to run a new
* version of this exploit: a class implementing IGenerateMalformedParcel and an
* intent telling the app which version of the exploit to run.
*
* When you recieve a new LaunchAnyWhere exploit it will likely be in the form
* of an app that can perform a number of actions such as creating a new pin
* or installing an app without recieving the appropriate permissions. However,
* the only file we care about form the app will be GenMalformedParcel.java.
* Find that file and follow these steps to add a new LaunchAnyWhere test:
*
* 1. Copy GenMalformedParcel.java into the LaunchAnyWhere app at
* cts/hostsidetests/security/test-apps/launchanywhere/src... Rename the file
* and class after the CVE that you are addressing. Modify the class
* signature and method signature so that it implements
* IGenerateMalformedParcel (namely, add the `implements` clause and change
* the function to public Parcel generate(Intent intent)).
*
* 2. Next, add a hostside test to the appropriate file in this directory.
* In the test all you have to do is call
* LaunchSomeWhere.launchSomeWhere("CVE_20XX_XXXXX", getDevice());
*
* 3. Verify your test and submit, assuming all went well. If not then check
* for differences between the files in the submitted apk and the code in
* tests/tests/security/src/android/security/cts/launchanywhere.
*
* Exploit Overview:
* All LaunchAnyWhere exploits take advantage of classes that write more data
* than they read. They follow the same process to send an intent with system
* permissions. The process is described below (you do not need to understand
* this in order to create tests, but we learned this while debugging some
* things and don't want the information to be lost):
*
* 1. Add an account with the account type 'com.launchanywhere' When an account
* is added the AccountManager delegates the task of authenticating the
* account to an instance of AbstractAccountAuthenticator. Our malicious
* authenticator finds
* android.accounts.IAccountAuthenticatorResponse.Stub.Proxy and replaces
* it's mRemote field with our anonymous IBinder before returning a
* default-constructed bundle. We save the old value and delegate to it
* after altering the arguments when appropriate (MitM).
*
* 2. When we finish, our IBinder's transact is called. At this point we create
* a reboot intent and send it to the appropriate class to generate the
* malformed parcel. This grants the intent system permissions.
*
* 3. The phone reboots, proving a successful exploit.
*/
class LaunchSomeWhere {
public static void launchSomeWhere(String cve, ITestDevice device)
throws Exception {
String command = "am start";
String[] args = {
"--es", "cve", cve,
"-n", "com.android.security.cts.launchanywhere/.StartExploit"
};
for (String s : args) {
command += " " + s;
}
AdbUtils.runCommandLine(command, device);
if (device.waitForDeviceNotAvailable(9_000))
device.waitForDeviceAvailable();
}
}