Exploit matérialisé
CVE-2016-6772
MEDIUM1 exploit(s) public(s) pour cette CVE, 1 matérialisé(s) avec leur code.
À des fins de recherche défensive uniquement. Ne testez que sur des systèmes que vous possédez ou pour lesquels vous détenez une autorisation écrite. L'accès non autorisé est illégal.
ExploitDB
dos android Vérifié
Source
Google Android - WifiNative::setHotlist Stack Overflow
Par Google Security Research
Comment tester cet exploit
Déni de service : envoie une entrée malformée pour crasher le service. À tester en VM isolée, l'effet est destructif.
Code txt
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 (pthread_getspecific@got.plt) --> 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://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/40945.zip