| Reporter | Title | Published | Views | Family All 9 |
|---|---|---|---|---|
| Android Security Bulletin—December 2016Stay organized with collectionsSave and categorize content based on your preferences. | 5 Dec 201600:00 | – | androidsecurity | |
| The vulnerability of the Android operating system, allowing a hacker to execute arbitrary code | 26 Jan 201700:00 | – | bdu_fstec | |
| CVE-2016-6772 | 20 Dec 201600:00 | – | circl | |
| Google Android Wi-Fi Elevation of Privilege Vulnerability | 13 Dec 201600:00 | – | cnvd | |
| CVE-2016-6772 | 12 Jan 201715:00 | – | cve | |
| CVE-2016-6772 | 12 Jan 201715:00 | – | cvelist | |
| EUVD-2016-7675 | 7 Oct 202500:30 | – | euvd | |
| CVE-2016-6772 | 12 Jan 201715:59 | – | nvd | |
| Privilege escalation | 12 Jan 201715:59 | – | prion |
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(¶ms, 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