1 /**
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.security.cts;
18 
19 import com.android.tradefed.device.ITestDevice;
20 
21 /*
22  * Adding Tests:
23  * We are testing a series of exploits that all take advantage of binder in the
24  * same way, using a malformed parcel to get system permission, with the only
25  * difference being the details of how we create the malformed parcel. In order
26  * to take advantage of these similarities (among other reasons) we share code
27  * between these exploits with an app that only requires two things to run a new
28  * version of this exploit: a class implementing IGenerateMalformedParcel and an
29  * intent telling the app which version of the exploit to run.
30  *
31  * When you recieve a new LaunchAnyWhere exploit it will likely be in the form
32  * of an app that can perform a number of actions such as creating a new pin
33  * or installing an app without recieving the appropriate permissions. However,
34  * the only file we care about form the app will be GenMalformedParcel.java.
35  * Find that file and follow these steps to add a new LaunchAnyWhere test:
36  *
37  * 1. Copy GenMalformedParcel.java into the LaunchAnyWhere app at
38  *    cts/hostsidetests/security/test-apps/launchanywhere/src... Rename the file
39  *    and class after the CVE that you are addressing. Modify the class
40  *    signature and method signature so that it implements
41  *    IGenerateMalformedParcel (namely, add the `implements` clause and change
42  *    the function to public Parcel generate(Intent intent)).
43  *
44  * 2. Next, add a hostside test to the appropriate file in this directory.
45  *    In the test all you have to do is call
46  *    LaunchSomeWhere.launchSomeWhere("CVE_20XX_XXXXX", getDevice());
47  *
48  * 3. Verify your test and submit, assuming all went well. If not then check
49  *    for differences between the files in the submitted apk and the code in
50  *    tests/tests/security/src/android/security/cts/launchanywhere.
51  *
52  * Exploit Overview:
53  * All LaunchAnyWhere exploits take advantage of classes that write more data
54  * than they read. They follow the same process to send an intent with system
55  * permissions. The process is described below (you do not need to understand
56  * this in order to create tests, but we learned this while debugging some
57  * things and don't want the information to be lost):
58  *
59  * 1. Add an account with the account type 'com.launchanywhere' When an account
60  *    is added the AccountManager delegates the task of authenticating the
61  *    account to an instance of AbstractAccountAuthenticator. Our malicious
62  *    authenticator finds
63  *    android.accounts.IAccountAuthenticatorResponse.Stub.Proxy and replaces
64  *    it's mRemote field with our anonymous IBinder before returning a
65  *    default-constructed bundle. We save the old value and delegate to it
66  *    after altering the arguments when appropriate (MitM).
67  *
68  * 2. When we finish, our IBinder's transact is called. At this point we create
69  *    a reboot intent and send it to the appropriate class to generate the
70  *    malformed parcel. This grants the intent system permissions.
71  *
72  * 3. The phone reboots, proving a successful exploit.
73  */
74 class LaunchSomeWhere {
launchSomeWhere(String cve, ITestDevice device)75     public static void launchSomeWhere(String cve, ITestDevice device)
76         throws Exception {
77 
78         String command = "am start";
79 
80         String[] args = {
81             "--es", "cve", cve,
82             "-n", "com.android.security.cts.launchanywhere/.StartExploit"
83         };
84 
85         for (String s : args) {
86           command += " " + s;
87         }
88 
89         AdbUtils.runCommandLine(command, device);
90         if (device.waitForDeviceNotAvailable(9_000))
91             device.waitForDeviceAvailable();
92     }
93 }