An OOB(out-of-bounds read) issue was found in function verify_file of verifier.cpp, allows attackers to execute arbitrary code in recovery verifier.

  • CVE ID: CVE-2017-0475;
  • Android ID: A-31914369;
  • Severity: critical;
  • Updated Google devices: All;
  • Updated AOSP versions: 4.4.4, 5.0.2, 5.1.1, 6.0, 6.0.1, 7.0, 7.1.1.

Description

https://android.googlesource.com/platform/bootable/recovery/+/37d7d67ca216972cba9259aa5866220d6abfaf14/verifier.cpp#145

1
size_t signature_start = footer[0] + (footer[1] << 8);

There is a missing boundary check where signature_start should be within the EOCD comment field.

https://android.googlesource.com/platform/bootable/recovery/+/37d7d67ca216972cba9259aa5866220d6abfaf14/verifier.cpp#234

1
2
3
4
5
6
7
8
9
10
11
12
uint8_t* signature = eocd + eocd_size - signature_start;
size_t signature_size = signature_start - FOOTER_SIZE;
LOGI("signature (offset: 0x%zx, length: %zu): %s\n",
length - signature_start, signature_size,
print_hex(signature, signature_size).c_str());
if (!read_pkcs7(signature, signature_size, &sig_der, &sig_der_length)) {
LOGE("Could not find signature DER block\n");
return VERIFY_FAILURE;
}
...
static bool read_pkcs7(uint8_t* pkcs7_der, size_t pkcs7_der_len, uint8_t** sig_der, size_t* sig_der_length)
...

pkcs7_der will point to a position beyound the bounds of the valid ZIP buffer due to the invaild signature_start, which may be exploitable.

Attack vector

You can click here to get the poc.

The easily way to trigger this vulnerability is as follows.

  1. Reboot your Android device to recovery mode;
  2. Select ‘Apply update from ADB’;
  3. Run adb sideload CVE-2017-0475.zip.

Patch

Add a boundary check for signature_start

https://android.googlesource.com/platform/bootable/recovery/+/2c6c23f651abb3d215134dfba463eb72a5e9f8eb%5E%21/#F0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
diff --git a/verifier.cpp b/verifier.cpp
index 16cc7cf..2d1b0e7 100644
--- a/verifier.cpp
+++ b/verifier.cpp
@@ -146,6 +146,12 @@
LOGI("comment is %zu bytes; signature %zu bytes from end\n",
comment_size, signature_start);
+ if (signature_start > comment_size) {
+ LOGE("signature start: %zu is larger than comment size: %zu\n", signature_start,
+ comment_size);
+ return VERIFY_FAILURE;
+ }
+
if (signature_start <= FOOTER_SIZE) {
LOGE("Signature start is in the footer");
return VERIFY_FAILURE;

Acknowledgement

This vulnerability was credited to Zinuo Han from Chengdu Security Response Center of Qihoo 360 Technology Co. Ltd.

Timeline

2016-10-02: ele7enxxh reported the vulnerability to Google;
2016-11-17: Google rated it as a critical vulnerability;
2017-01-31: Google assigned CVE-2017-0475 for this vulnerability;
2017-03-07: Google released the patch and disclosed the details of CVE-2017-0475 on Android Security Bulletin-March 2017.