Lucene search
K

Google Android - WifiNative::setHotlist Stack Overflow Vulnerability

🗓️ 20 Dec 2016 00:00:00Reported by Google Security ResearchType 
zdt
 zdt
🔗 0day.today👁 59 Views

Google Android WifiNative::setHotlist Stack Overflow Vulnerability found in the code in frameworks/opt/net/wifi/service/jni/com_android_server_wifi_WifiNative.cp

Related
Code
ReporterTitlePublishedViews
Family
Android Security Bulletins
Android Security Bulletin—December 2016Stay organized with collectionsSave and categorize content based on your preferences.
5 Dec 201600:00
androidsecurity
BDU FSTEC
The vulnerability of the Android operating system, allowing a hacker to execute arbitrary code
26 Jan 201700:00
bdu_fstec
Circl
CVE-2016-6772
20 Dec 201600:00
circl
CNVD
Google Android Wi-Fi Elevation of Privilege Vulnerability
13 Dec 201600:00
cnvd
CVE
CVE-2016-6772
12 Jan 201715:00
cve
Cvelist
CVE-2016-6772
12 Jan 201715:00
cvelist
EUVD
EUVD-2016-7675
7 Oct 202500:30
euvd
NVD
CVE-2016-6772
12 Jan 201715:59
nvd
OSV
CVE-2016-6772
12 Jan 201715:59
osv
Prion
Privilege escalation
12 Jan 201715:59
prion
Rows per page
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=958
 
The following code in frameworks/opt/net/wifi/service/jni/com_android_server_wifi_WifiNative.cpp doesn't validate the parameter params.num_bssid, and then copies that number of elements into a stack-allocated wifi_bssid_hotlist_params structure. I don't think this can be reached from an untrusted_app context; but it can be reached from a context with system_api_service access; so a compromised platform app or one of several lower privileged system services (bluetooth, nfc etc.).
 
static jboolean android_net_wifi_setHotlist(
        JNIEnv *env, jclass cls, jint iface, jint id, jobject ap)  {
 
    JNIHelper helper(env);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
    ALOGD("setting hotlist on interface[%d] = %p", iface, handle);
 
    wifi_bssid_hotlist_params params;
    memset(&params, 0, sizeof(params));
 
    params.lost_ap_sample_size = helper.getIntField(ap, "apLostThreshold");
 
    JNIObject<jobjectArray> array = helper.getArrayField(
            ap, "bssidInfos", "[Landroid/net/wifi/WifiScanner$BssidInfo;");
    params.num_bssid = helper.getArrayLength(array);
 
    if (params.num_bssid == 0) {
        ALOGE("setHotlist array length was 0");
        return false;
    }
 
    for (int i = 0; i < params.num_bssid; i++) { // <--- no validation on num_bssid
        JNIObject<jobject> objAp = helper.getObjectArrayElement(array, i);
 
        JNIObject<jstring> macAddrString = helper.getStringField(objAp, "bssid");
        if (macAddrString == NULL) {
            ALOGE("Error getting bssid field");
            return false;
        }
 
        ScopedUtfChars chars(env, macAddrString);
        const char *bssid = chars.c_str();
        if (bssid == NULL) {
            ALOGE("Error getting bssid");
            return false;
        }
        parseMacAddress(bssid, params.ap[i].bssid); // <--- params.ap has 128 elements.
 
        mac_addr addr;
        memcpy(addr, params.ap[i].bssid, sizeof(mac_addr));
 
        char bssidOut[32];
        snprintf(bssidOut, sizeof(bssidOut), "%0x:%0x:%0x:%0x:%0x:%0x", addr[0],
                 addr[1], addr[2], addr[3], addr[4], addr[5]);
 
        ALOGD("Added bssid %s", bssidOut);
 
        params.ap[i].low = helper.getIntField(objAp, "low");
        params.ap[i].high = helper.getIntField(objAp, "high");
    }
 
See attached for a POC which causes a crash before the function with the corrupted stack frame returns and checks the stack cookie.
 
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
[---------------------------------------------------------------------REGISTERS----------------------------------------------------------------------]
*X0   0x80000000 <-- 0x0
*X1   0x0
*X2   0x707882c3e0 <-- u'c0:1d:b3:3f:01:...'
*X3   0x3
*X4   0x709bf05fc0 <-- stp    x28, x27, [sp, #-0x60]!
*X5   0x709c1f07b0 (art::gJniNativeInterface) <-- 0x0
*X6   0x709bf27034 <-- cbz    x2, #0x709bf27040 /* u'b' */
*X7   0x284801ff284800ff
*X8   0xc01d0142c01d0229
*X9   0x1
*X10  0xc01d0142c01d0141
*X11  0x7082dff4e8 <-- 0x41013fb31dc0
 X12  0x0
*X13  0x0
*X14  0x0
*X15  0x33511e057221be
*X16  0x709f0035a0 ([email protected]) --> 0x709efaad5c (pthread_getspecific) <-- movz   w8, #0x8000, lsl #16
*X17  0x709efaad5c (pthread_getspecific) <-- movz   w8, #0x8000, lsl #16
*X18  0x0
*X19  0x707882c3e0 <-- u'c0:1d:b3:3f:01:...'
*X20  0x7082dfe0a0 --> 0x70833c1470 --> 0x7083381c0c (android::JNIObject<_jobject*>::~JNIObject()) <-- adrp   x2, #0x70833c2000
*X21  0x7082dfe0b8 --> 0x70833c1490 --> 0x7083381c70 (android::JNIObject<_jstring*>::~JNIObject()) <-- adrp   x2, #0x70833c2000
*X22  0x7082dfe078 <-- 0x0
*X23  0xb1da807287fa8cf
*X24  0x709f00e86c (je_tsd_tsd) <-- 0xa880000000
*X25  0x7082dfe8d8 <-- u'c0:1d:b3:3f:1:4...'
*X26  0x200011
*X27  0x7082dfe0d0 <-- 0x100000000001
*X28  0x707882c3e0 <-- u'c0:1d:b3:3f:01:...'
*SP   0x70815310f0 <-- 0x0
*PC   0x709efaada8 (pthread_getspecific+76) <-- ldr    x10, [x10, #0xe0]
[------------------------------------------------------------------------CODE------------------------------------------------------------------------]
 => 0x709efaada8L <pthread_getspecific+76>    ldr    x10, [x10, #0xe0]
    0x709efaadacL <pthread_getspecific+80>    cmp    x10, x9
    0x709efaadb0L <pthread_getspecific+84>    b.ne   #pthread_getspecific+56       <0x709efaad94>
...
    0x709efaad94L <pthread_getspecific+56>    mov    x0, xzr
    0x709efaad98L <pthread_getspecific+60>    str    xzr, [x8]
    0x709efaad9cL <pthread_getspecific+64>    ret    
 
    0x709efaada0L <pthread_getspecific+68>    add    x10, x10, x8, lsl #4
    0x709efaada4L <pthread_getspecific+72>    add    x8, x10, #0xe8
 => 0x709efaada8L <pthread_getspecific+76>    ldr    x10, [x10, #0xe0]
    0x709efaadacL <pthread_getspecific+80>    cmp    x10, x9
    0x709efaadb0L <pthread_getspecific+84>    b.ne   #pthread_getspecific+56       <0x709efaad94>
[------------------------------------------------------------------------CODE------------------------------------------------------------------------]
155 in bionic/libc/bionic/pthread_key.cpp
[-----------------------------------------------------------------------STACK------------------------------------------------------------------------]
00:0000| sp  0x70815310f0 <-- 0x0
...
04:0020|     0x7081531110 --> 0x3f800000 <-- 0x0
05:0028|     0x7081531118 <-- 0x0
...
[---------------------------------------------------------------------BACKTRACE----------------------------------------------------------------------]
>  f 0       709efaada8 pthread_getspecific+76
   f 1       709efd2394 je_free+68
   f 2       709efd2394 je_free+68
   f 3       709efd2394 je_free+68
   f 4       709efd2394 je_free+68
   f 5       7083387d10
   f 6       7083387d10
   f 7       7083387d10
Program received signal SIGSEGV (fault address 0x1d0142c01d0221)
pwndbg> bt
#0  pthread_getspecific (key=<optimized out>) at bionic/libc/bionic/pthread_key.cpp:160
#1  0x000000709efd2394 in je_tsd_wrapper_get () at external/jemalloc/include/jemalloc/internal/tsd.h:609
#2  je_tsd_get () at external/jemalloc/include/jemalloc/internal/tsd.h:609
#3  je_tsd_fetch () at external/jemalloc/include/jemalloc/internal/tsd.h:614
#4  je_free (ptr=0x707882c3e0) at external/jemalloc/src/jemalloc.c:1932
#5  0x0000007083387d10 in _JNIEnv::ReleaseStringUTFChars (utf=0x707882c3e0 "c0:1d:b3:3f:01:"..., string=0x200011, this=0x7091fd2b00) at libnativehelper/include/nativehelper/jni.h:851
#6  ScopedUtfChars::~ScopedUtfChars (this=<synthetic pointer>, __in_chrg=<optimized out>) at libnativehelper/include/nativehelper/ScopedUtfChars.h:45
#7  android::android_net_wifi_setHotlist (env=0x7091fd2b00, cls=<optimized out>, iface=<optimized out>, id=0x690a3633, ap=<optimized out>) at frameworks/opt/net/wifi/service/jni/com_android_server_wifi_WifiNative.cpp:799
#8  0x000000709b1a084c in ?? ()
 
Fixed in https://source.android.com/security/bulletin/2016-12-01.html
 
 
Proof of Concept:
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/40945.zip

#  0day.today [2018-01-11]  #

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

20 Dec 2016 00:00Current
8.3High risk
Vulners AI Score8.3
EPSS0.02797
59