ImageVerifierCode 换一换
格式:DOCX , 页数:12 ,大小:190.60KB ,
资源ID:3310447      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/3310447.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(JITBHDCPaperchs.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

JITBHDCPaperchs.docx

1、JITBHDCPaperchsINTERPRETER EXPLOITATION: POINTER INFERENCE AND JIT SPRAYING Dion Blazakis dion翻译:espzj摘要随着远程漏洞的逐渐减少以及边界防护的标准化,针对远程客户端的攻击是攻击者下一个最好的选择。如今的Windows操作系统通过使用DEP和ASLR等技术已经逐渐消除了针对客户端漏洞的利用。本文将介绍两种新颖的技巧来绕过DEP和ASLR。这些技巧利用了在浏览器内通常可访问的高级脚本解释器和虚拟机所暴露出来的攻击面。第一个技巧,pointer inference,用于在使用了ASLR的情况下找出A

2、ctionScript interpreter内shellcode串的内存地址。第二个技巧,JIT spraying,通过利用ActionScript JIT编译器可以预测的行为把shellcode写到可以执行的内存地址来绕过DEP。最后讨论了未来的研究方向和翻译器(用于针对这些技巧)的对抗措施实现。介绍发现和利用远程漏洞的困难性激发攻击者把他们的资源用于发现和利用客户端的漏洞。客户端攻击者的汇聚促使微软实施健壮的对抗技术,使得针对这些漏洞的利用越来越困难。Sotirov and Dowd【1】详细介绍了每个对抗技术以及它们在直到Windows7 RC的各个Windows系统下的默认配置。他们

3、介绍了一些可以用来绕过这些保护的技巧以及微软公司的设计选择是怎样影响绕过这些保护措施的具体细节的。贯穿文章的一件事情就是针对浏览器的攻击利用是多么的成熟攻击者可以使用多个插件(plugins),选择特定的可利用插件,来创建一个可靠的利用情景。经典的web浏览器,因为插件而开了一道缝隙,被设计成不可能有更多可能被利用的地方。它需要一个健壮的解析器来解析和尝试对版本6的提升。随着Web2.0的到来,浏览器必需包含一个高性能的脚本环境来重写这些动态解析的页面。暴露给这些运行时脚本库在继续增加。另外,大多数浏览器都利用了最近的JIT和垃圾搜集技术来加速脚本的执行。所有这些攻击面以及我们还没讨论的插件都

4、是普遍安装了的。RIA(Rich Internet Application,富互联网应用系统)越来越多,Adobe目前牢牢地掌握了Flash市场。安装了web浏览器的主机有99%都安装了Flash Player。Sun公司的JRE(Java Runtime Environment)是另一个普遍安装了的解释器。微软公司的Sliverlight是一个基于运行时.NET和工具的RIA框架。Silverlight仍在试图获得市场份额,在将来可能会是一个竞争者(例如, Netflix On-Demand已经开始使用这个技术)。这些插件都需要一个复杂的解析器并且暴露了更多的可被攻击者利用的攻击面。例如,A

5、dob Flash Player实现的特色包括一个非常大的GUI库,一个JIT 3D shadow language,一个RMI系统,一个基于ECMAScript的JIT虚拟机,对嵌入式pdf的支持以及多个声音和视屏嵌入和流的选项。所有这些特色默认都可以被那些幸运的攻击者所利用。考虑到这一点,投入时间和精力发展特定应用程序的技巧对于利用浏览器生态系统内的漏洞是有帮助的。DEP和ASLR对于漏洞利用人员来说是一个真正的挑战。DEP使得定位shellcode变得困难。(原文:DEP makes locating shellcode difficult。我认为应该改为:ASLR makes loca

6、ting shellcode difficult,ASLR使得定位shellcode变得困难);攻击者必需首先找到具有可执行权限的页面并且要能够在具有写权限时对其进行写操作,同时要能够定位它的地址。有一种选择就是,攻击者可以找到一些代码重新使用正如基于return-oriented programming【3,4】的攻击那样。ASLR通过混淆加载映像的基地址来对抗这个选择。请参看Sotirov和Dowd【1】的文章来详细了解在不同Windows操作系统上ASLR和DEP的具体实现。现在,我们假定ASLR接近完美-也就是攻击者不能猜出加载映像,堆,堆栈的地址。本文把焦点集中于两种绕过这些安全措施

7、的技巧上:pointerer inference和JIT spraying。Pointer inference是通过和目标软件的”正常”(例如,不是通过利用漏洞)交互来恢复内部对象的内存地址的行为。以Adobe Flash Player作为例子。我将展示如何通过一个脚本来判定一个位于Flash Player的ActionScript 解释器内部的字符串对象的地址。JIT spraying类似于heap spraying;攻击者将分配许多可执行的页面,这些页面包含了攻击者能够影响的数据。我将展示如何构造一个ActionScript脚本,当被Actionscript 引擎即时编译时,构造出一个st

8、age-0的shellcode来加载和执行next stage的shellcode(定位于一个ActionScript字符串)。然后,我将讨论结合使用这两项技术来攻击Windows Vista的可能性。最后,讨论了一些对抗措施和未来的研究方向 。Pointer Inference把控制权从EIP转到exploit在地址空间随机化的情况下变得越来越困难。即使从一个崩溃的POC得到EIP的控制权也很困难。证实一个漏洞存在有时是相当容易的,使用heap spray在一个已知的地址放置攻击者构造的结构就可以轻易实现。但是对漏洞利用者不幸的是,heap spray并不总是非常可靠(而且有时并不总是可行如

9、果攻击者不能分配大的堆对象)。另外,针对heap spray的对抗措施(mitigation)已经出现在学术界【10】而且微软公司在它们的EMET工具【9】中有一个相当简单的消除措施(把heap spray常用的页面映射到进程开始处)。可靠的利用要有在一定的范围内动态地得到运行时对象的堆地址的能力。脚本执行环境是pointer inference的完美目标对象通常存在于堆,并且运行时语言和库提供了多种方法来操作和检查对象。另外,脚本语言是动态类型语言,因此内置的容器对象通常是不同类的-存引用对象和存值对象的结构通常是一样的。我们的目标是找到一种方法,以在解释器或虚拟机内判定脚本对象的内存地址。

10、提取包含有shellcod的JavaScript字符串的地址,并不是这个技巧的唯一用处,但却是一个好的利用的基本模块。目标VM包括(ECMA|Java|Action)Script,Java,Python,Ruby,PHP,以及.NET CLR。浏览器内的Javascript引擎,Adobe Reader内的JavaScript引擎,以及Adobe Flash Player内的ActionScript引擎等在大多数浏览器安装后都可以使用(如果他们按装了Adobe插件并且没有禁用JavaScript)。本文我将显示如何在遍历ActionScrip字典对象时,利用对象的顺序得到在ActionScri

11、pt虚拟机内某个对象的内存地址。我选择在这个POC中使用Flash Player有多个原因:相对于其他的,我逆向它的时间最多,它是跨平台的不管浏览器,对插件来说都是同样的代码基的,最后,但并不是最不重要的是,Adobe已经开放了它们的ActionScript compiler的源代码。为了了解这个技巧的细节,首先我将描述对象在内部是如何被解释器所存储的,然后介绍了解释器是如何实现内置的字典容器的。ActionScript对象的内部表示在讨论揭露ActionScript对象地址的方法之前,先介绍下解释器内部是怎样存储对象的。当执行的脚本创建一个ActionScript对象时,解释器基于对象的类型

12、来进行相应的操作。如果对象是比较小的基本对象,比如整数(integer)或者布尔(boolean)类型,就存储它的值。对于doubles,strings,和class则存它们的引用解释器会分配一个足够大的缓冲区来存储对象并且保存一个指向这个缓冲区的指针。ActionScript是一种动态类型语言。动态类型语言在编译时并不给值赋予类型。动态类型语言并不把类型表示加入语言并在编译时加入类型限制,而是提供运行时函数来检查和比较对象类型。解释器确保所有在操作时的操作数都是合法的。当解释器检测到类型不匹配时(例如,查询一个实例并没有实现的方法时),ActionScript要么会抛出一个异常或者隐式强制转

13、换。这种运行时类型语言要求对象堆不光要存储对象的类型,还要保存对象的值。为了处理这种运行时类型要求,ActionScript解释器使用带标签的指针(tagged pointers)-在内部,这些对象被称作”atom”,来表示内部对象。在使用同样大小的内存单元的情况下,Tagged pointers是用来区分存值对像和存引用对象的常用实现方法。Tagged Pointer用最低的几个比特位存储类型信息,用高位来存储特定类型的值。如图1所示,ActionScript的atom是32bit宽的;它分配3bit来存类型信息,用29bit来存值。图1例子可能会有助于解释是如何工作的。拿下面的Action

14、Script声明来说:var x = 42; / Integer atomvar y = “blackhat”; / String atomvar z = new Dictionary(); / Object atomvar b = true; / Boolean atom变量x是一个值为42的局部变量。解释器会在当前域内创建一个局部变量和值42的映射。正如上面所描述的,这个值在内部将会被表示为一个atom。整数atom能表示-228到228-1的值,是通过创建时把值左移3bit来给类型标签留存储空间的。整数atom的标签是一个6,如果图1所示。用Python表示这个过程如下: def ato

15、mFromInteger(n):return (n 0x%08x % (atomFromInteger(42),)0x00000156String和Object atoms是“引用”atom-它们存储指针,指向解释器堆上面的垃圾回收内存。把y和z转换为atom需要先为它们分配一块内存来保存值,然后用这个内存地址的值来创建atom。下面是一个用Python操作z的例子额外的call是模拟的,不要让它们分散你的注意力。 def atomFromObject(obj):return (obj & 7) | 1 a = actionScriptHeapAlloc(size_of_Dictionary)

16、 Dictionary.initialize(a) 0x%08x % (atomFromObject(a), )0x00c8b301介绍内部如何表示的目的是用于解释值和引用(内存地址,指针)都被解释器用作atom。接下来,我将解释ActionScript字典类是如何实现和使用的。ActionScript字典的实现内置的ActionScript字典类揭示了一个关联的图数据结构。当在ActionScript脚本内部使用时,它提供一个接口,把任何ActionScript对象同任何其他的ActionScript对象关联为key/value关系。类似于Python字典,字典对象可以通过方括号来查询。另外

17、,用户可以通过遍历字典来操作每个key/value对。遍历的顺序并没有通过API的定义来指定,同时是不依赖于实现的细节的。使用例子:var dict = new Dictionary(); dict“Alpha” = 0x41414141;dicttrue = 1.5; var k; for (k in dict) f(dictk);Flash Player的字典类在内部通过hashtable来实现。Hashtable从key atom而来,并且把key和value atom一起存到表中。当遍历字典时,hashtable从最低的hash value遍历到最高的hash value。最后的细节就

18、是hash 函数是如何工作的,它是如何处理碰撞的,以及hash table是如何增长的。Hash table的大小总是2的幂次。这样做有两个原因:hash 函数是一个快速的掩码操作函数,平方探测依赖于2的幂次的表。当一个表中的空单元低于总大小的20%时,hash table就要增长到2的下一个幂次(也就是表的大小要乘以2)。为了把表变大,先要分配一个新表,所有的条目都将要被重新hash并插入到新表中。Hashtable的实现泄露了integer(值) atom和object(引用) atom的顺序-object atom被用于直接同interger atom比较。Hash函数将会把最高的某些位

19、给删除掉,但是一个大的hashtable将会使用剩下的大多bit位。表中的顺序就泄露了引用atom的内存地址。整数筛选因为整数使用它们的值作为在hashtable中的键值(key)(当然,最高的某些bit位将会被屏蔽掉),我们可以通过在遍历hashtable时测量新的对象被发现的位置,来判定某些ActionScript对象的atom值。通过记录新插入的对象之前和之后的整数,我们可以得到新对象的atom的一个范围。因为Object atom只是指针(有3bit的修改),我们可以在hashtable增大时得到指针的bit位。为了避免hash碰撞的问题,我们执行两次测试:一次是所有的偶数,一次是所有

20、的奇数(达到2的某次幂-随着我们发现的bit位数而增大)。在创建完字典后,把victim object插入两个字典。字典中和关键字关联的值并不对此造成任何影响-只与关键字和它们的顺序有关。接下来,通过使用for-in结构查询字典,记录下最后访问的关键字并且在当前关键字是victim object时退出。现在我们有两个整数值(对偶数和奇数字典分别有一个在victim object 之前的最后一个整数)。这两个整数应该相差17。原因在于这是线性探查;当hashtable插入时遇到碰撞,它使用二次探查来找出一个空的单元。第一个尝试位于(hash(victim_atom)+8),但是总是和-2n+8=

21、2(n+4) 或(2n+1)+8=2(n+4)+1碰撞。第二个尝试是(hash(victim_atom)+17),这次尝试总是会成功,-2n+17=2(n+8)+1或者(2n+1)+17=2(n+9)。唯一使得这两个整数相差不是17的情况就是这个探查被包装了。否则,小的整数来自于并不存在碰撞的字典。当两者相差不是17的时候,较大的值来自于不存在碰撞的字典。现在我们有一个整数,当转换为atom时比victim atom小8。最后,可以从整数得到victim atom,x:(x3+8)或者(x+1)3);那只是一小部分;来查看执行过程:/ First, create the Dictionarie

22、svar even = new Dictionary();var odd = new Dictionary(); / Now, fill the Dictionary objects with the integer atomsvar index; for (index = 0; index 8; index += 1) evenindex * 2 = true;oddindex * 2 + 1 = true;在插入interger atom后,堆看起来将会如此:图2接下来,插入引用对象来泄露地址:var victim = “AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

23、AAAAAAAAA”; evenvictim = true;oddvictim = true;图 3:插入victim对象之后的堆在图3中,可以看到victim object是怎样被包围的(表有16个单元,因此17在模16后和1有碰撞)。最后一步就是遍历两个字典来找到最后一个出现在victim object对象之前的整数。var curr, evenPrev, oddPrev; for (curr in even) if (curr = victim) break; evenPrev = curr; for (curr in odd) if (curr = obj) break; oddPre

24、v = curr; 在执行完上面一段代码之后,evenPrev将包含值0(atom:0x00000006),oddPrev将包含值1(atom: 0x0000000E),假定evenPrev和oddPrev相差17(hash表为一个更合理的大小,比如,4百万)。evenPrev小一些,这就意味着我们可用通过把evenPrev(值为0,正如在ActionScript中大家所看到的一样)加1然后左移3位来得到vimtim object的最低几位地址。结果就是0x00000008。和victim object的地址的最低几位匹配。提取出内存地址泄流并不唯一,并且其他用于推测地址信息的变量也不难想象。

25、如果我们限制用数据结构泄露,内部id和hash function(和ActionScript技术相反,.NET和Java并不能通过脚本直接获取hash,参见.NET和Java)。这些函数需要一个独一无二的堆对象并且这些地址也能够被使用。我为这个过程提供了ActionScript样本例子,并且在Adobe Flash Player plug-in (NPSWF32.DLL and Flash10c.ocx) 版本 10.0.32.18 and 10.0.42.34上验证过。JIT SPRAY数据执行保护(DEP)使得执行构造的shellcode相当困难堆栈和默认堆都被标记为不可执行。据我所知,已

26、公开的绕过DEP的最好的方法就是找到一个已加载了的,没有使用ASLR的DLL,然后使用DLL中的代码来构造return-oriented shellcode【3,4】来关闭进程的DEP,或者分配可执行的内存并把next stage shellcode拷贝到已分配的地方。现代的解释器实现了一个即时(Just-In-Time,JIT)编译器来把解析的输入或者字节码转化为机器码以加快执行速度。JIT spray就是迫使JIT引擎把嵌入的shellcode写到可执行页面的过程。Shellcode通过正常的JIT指令输入。例如,一个JavaScript语句如“var x = 0x41414141 + 0

27、x42424242;”可能被编译为在可执行映像中包含2个4字节的常量(例如,“mov eax, 0x41414141; mov ecx, 0x42424242; add eax, ecx”)。从这写常量中间的某个位置开始将会执行一个完全不同的指令序列。本节的剩余部分将介绍一个针对Adobe Flash Player ActionScript bytecode JIT的例子。结尾的结果是一个Python脚本和ActionScript脚本。Python脚本生成ActionScript。ActionScript在加载和字节码引擎开始JIT编译后,将在堆上展示一个可执行的页面。当这个可执行页面被输入一

28、个已知的偏移量(0x6A,对于下面的例子代码来说)后,将执行一个stage-0的shellcode使得剩下的页面可以读写并执行,并且把next stage的shellcode从一个可以在编译前修改的ActionScript String中拷贝过来。关键点就是JIT是可以预测的并且必须拷贝一些常量到可执行的页面。给一串一致的语句,这些常量可以编码小的指令并且能够把控制流转移到下一个常量的位置。Development在Flash Player中调用VirtualProtect的位置下一个断点,我们可以观察从ABC(ActionScript Byte Code)字节码到JIT代码的生成过程。通过实验

29、,我发现一个长XOR表达式(a b c d )将会被编译为一个非常精简的XOR指令集。例如,在JIT编译后 var y = (0x3c54d0d9 0x3c909058 0x3c59f46a 0x3c90c801 0x3c9030d9 0x3c53535b 将转变为:03470069 B8 D9D0543C MOV EAX,3C54D0D9 0347006E 35 5890903C XOR EAX,3C909058 03470073 35 6AF4593C XOR EAX,3C59F46A 03470078 35 01C8903C XOR EAX,3C90C801 0347007D 35 D9

30、30903C XOR EAX,3C9030D9 03470082 35 5B53533C XOR EAX,3C53535B 现在,如果从0x0347006A开始执行:0347006A D9D0 FNOP 0347006C 54 PUSH ESP 0347006D 3C 35 CMP AL,35 0347006F 58 POP EAX 03470070 90 NOP 03470071 90 NOP 03470072 3C 35 CMP AL,35 03470074 6A F4 PUSH -0C 03470076 59 POP ECX 03470077 3C 35 CMP AL,35 034700

31、79 01C8 ADD EAX,ECX 0347007B 90 NOP 0347007E D930 FSTENV DS:EAX 0347007C 3C 35 CMP AL,35 这是一个很流行的GetPC方法-使用浮点状态保存【8】ActionScript允许动态加载(和运行时生成)字节码,使用这个技巧,我们就可以通过重复加载一个给定的字节码文件来在堆上生成构造的JIT代码。这个就是JIT spray;在合理的猜测并且幸运的情况下,攻击者在ASLR和DEP存在的情况下可以执行shellcode。最后一节,我们将看看如何使用。上面给的例子中,注意到控制从一个DWORD转移到下一个只用了一个字节。利用单字节XOR EAX 机器码,cmp al在语义上也是一个NOP,并且不需要JMP指令所需要的两个字节。二者结合在讨论Pointer inference中没有说明的一点就是通过泄露的指针所指向的值。攻击者通过地址泄露能够得到什么呢?攻击者通过泄露的指针能够控制的值是什么呢?对于Object atom来说,指针所指向的C+实例包含了很难被控制的域。对于String atom来说,指针所指向的C+对象包含一个长度域和一个指向字符串缓冲区的指针。这在某些例子下肯定是有用的,但它并不是直接指向string缓冲区的指针。最后,它只是一个指向堆的指针。为了找到和使用这个指针,我们必须理解F

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1