zoukankan      html  css  js  c++  java
  • HeapSpray初窥(2014.12)

    注:环境是xp+ie8

    1.HeapSpray简介

    Windows的堆因为动态分配和释放的特点,其看起来是不连续(没有规律的),但是仍可以找到一定的规律:大量的连续分配会更倾向使用连续的地址,减少了碎片化。这为利用找到了机会。

    HeapSpray就是在内存中分配大量的空间,申请的这些内存都是由相同的NOPs+shellcode所构成。如果存在任意地址写的漏洞,就可以利用该HeapSpray:改变程序的流程,使EIP指向事先分配好的NOPs+shellcode的内存块。这样shellcode就可以得到执行了。

    HeapSpray利用的步骤大概如下:

    1.Spray the heap

    2.Trigger the bug/vulnerability

    3.control EIP and make EIP point directly into the heap

    当然还要绕过一些安全机制如DEP,这和缓冲区溢出的绕过思路感觉一样。

    2.BSTR string object结构

    Windows在存储javascript字符串采用的是BSTR string,其结构包含一个用来描述string所占字节数的头+Unicode编码的string+两字节的NUL

    并且字符串的string.lengthbytes存在这样的换算关系:

    bytes=length*2+6;

    length=(bytes-6)/2;

    如下面这句javascript代码,其在内存创建了一段字符串" FuzzySecurity"其中unescape的功能是不让javascript再对FuzzySecurityascci码进行编码。

        

    创建的字符串在内存中:

    按照上面的换算公式:

    bytes=7*2+6=20

    length=(20-6)/2=7

    值得注意的是,此时BSTR string head=0xe,而Shellcode.length=7=head/2。这是因为javascript是按Unicode编码来计算字符串的长度的,所以个数减半,javascript在操作字符串的时候也是按照Unicode编码来的,这点在后面布置Shellcode时有用。

    3.一个例子

    CVE-2013-0025这个IE上的UAF漏洞为例子,编写exp,使用HeapSpray,并绕过DEP,最后弹出对话框。

    3.1分析崩溃

    POC如下:

    运行这个POC(不开启usthpa),相关的崩溃信息:

    可见,若能控制ecx指向内存的值(mov eax,dword ptr[ecx]),也就控制了EIP的值了(call edx)

    3.2占位    (好像是这样叫的吧。。。)

    这一步的目的是为了控制EIP。

    html如下:

    相比上面的POC,只是增加了红框中的一小段javascript代码。具体为什么要这样,暂时还不知道。

    然后再次崩溃:

    可以看到此时eax的值已经被改变了,从0变成0x0c0c0c0c,这样执行call edx的时候就变成了:call [0x0c0c0c7c]EIP改变成功,下一步就是布置shellcode到新EIP位置了。

    3.3布置Block

    先把框架弄好,再来填具体的东西。

    所分配的Block内存布局的期望是这个样子的:

    看起来有点奇怪:为何不直接将EIP指向shellcode开始的地方?这是有道理的,因为需要过DEP保护,需要先执行一点东西再去执行真正的shellcode(弹出对话框)。

    接下来就来实现这个期望吧。

    首先需要确定的是padding的大小,在windbg中利用!heap命令,可以找到0x0c0c0c0c所在堆的起始地址:

    计算偏移:0x0c0c0c0c-0x0c080018=0x40bf4

    0x40bf4对0x1000进行求余运算,得到0xbf4。(0x1000为我们分配的每一个Block的大小)。

    这样得到的是所在的字节数,javascript代码所操作的是字符串的长度,这里需要按照上面提到的公式转换一下:

    0xbf4/2-6=0x5f4

    接下来的shellcode就先随便填一下,只是在+0x70的位置填上一个不一样的值,来确定是否在0x0c0c0c7c的位置能够写上值,为了方便查找还是填上" FuzzySecurity"。

    最后这0x1000 大小的Block剩下空间就全部给NOPs了。

    这三部分对应的javascript代码分别如下:

    要经过大量的堆分配,似乎才可以保证堆"连续",并且保证0x0c0c0c0c是"属于"我们的。所以接下来会分配150MB的堆,这些堆又会分成很多1MB的chunk,每个chunk都是具有很多个上面所构造的这种0x1000大小的Block。对应代码:

    结果就像下面这样:

    3.4编写shellcode

    a.绕过DEP

    所使用的方法是构造ROP链来调用VirtualProtect()改写目标地址的读写权限。使用的是下面这段利用msvcr71.dll来构造的ROP链:

    引用地址https://www.corelan.be/index.php/security/corelan-ropdb/#msvcr71dll_8211_v71030524

     

    b.执行真正的shellcode吧

    现在已经可以执行shellcode这段空间的代码了,那么再跳回到0x0c0c0c7c下一个地址去执行弹出对话框的代码就好了,至于弹出对话框的代码,用metersploit生成一份就好了。

    所以完整的如下:

    代码会按照红àà绿à蓝执行。

    最后就弹出对话框了~~

  • 相关阅读:
    如何用代码来修改目录的权限
    php广告显示设置存放记录的目录代码
    本函数用来改变目前 php 执行的目录到新的 directory 目录中
    for循环的时候是按照数字递增会造成一些元素被遗漏
    php常用的对字符串进行加密的算法
    关于如何用php 获取当前脚本的url
    将正确的 HTTP 头转发给后端服务器的一些问题
    应用服务器上部署自己的 blog 和 wiki 组件。
    PHP统计字符串里单词查询关键字
    (在线工具)JSON字符串转换成Java实体类(POJO)
  • 原文地址:https://www.cnblogs.com/flycat-2016/p/5428886.html
Copyright © 2011-2022 走看看