欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

浏览器漏洞:从数组越界到任意地址读写

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


 
引言
在现代的操作系统中,针对内存破坏方面的漏洞,提供了一系列的阻碍措施,类似DEP、CFG以及EMET。浏览器Exploit中,通过UAF/Double Free 乃至 堆溢出都能实现对内存的一定程度读写,但是碍于内存不可执行,浏览器利用中常常需要精确堆喷射结合ROP,前提是获取二进制文件(ELF/COFF)在内存中load的确切地址(地址泄漏)。文本暂时不讨论堆利用本身,会分别讨论两个浏览器漏洞,利用漏洞实现了OOB之后,如何在开启ASLR的情况下完成地址泄漏,帮助读者完成Exploit的最后一公里。
Linux下检查是否开始ASLR
ASLR 技术在 2005 年的 kernel 2.6.12 中被引入到 Linux 系统,Linux 平台上的 ASLR 分为三级,由内核参数 randomize_va_space 进行等级控制。它们对应的效果如下:
0:没有随机化。即关闭 ASLR。
1:保留的随机化。共享库、栈、mmap() 以及 VDSO 将被随机化。
2:完全的随机化。在 1 的基础上,通过 brk() 分配的内存空间也将被随机化。
$ cat /proc/sys/kernel/randomize_va_space
2
需要注意的是Linux下的ASLR默认不对代码段以及数据段(data段和bss段)进行随机化,于是gcc在编译时候加-pie参数,开启PIE机制的程序会对代码段和数据段也进行随机化。不过由于PIE是编译选项,PIE是否真正的开启是基于系统的ASLR是否开启。
Windows下检查是否开启ASLR
Windows在vista之后是默认开启ASLR的,并且Windows的ASLR同样会对代码段和数据段进行随机化,简单来说Windows的ASLR基本等于Linux下的ASLR加PIE。
绕过ASLR
利用未启用ASLR的模块绕过这部分的研究价值不高,和没有开ASLR的难度差别不大,所以这个方案就暂时不做演示。如果要寻找哪些模块没有开启ASLR,可以使用mona插件可以的mod命令查看。
常见的例子,如java6的msvcr71.dll编译时时默认不支持ASLR的,所以很多exploit都使用这个模块构造ROP链来实现攻击。
泄露基地址绕过ASLR是最经典的绕过技术,也是CTF中最常见的绕过技术,这个技术在2010年左右兴起,用于对抗当时已经有较大市场份额的WIN7。这也是本文会着重分析的技术,重点会在漏洞利用。例如下文案例,IE浏览器利用中通过虚函数表获取mshtml.dll的基地址构造ROP链。
yuange的天人模式袁哥在97年就发布的DVE数据虚拟执行技术,一项技术几乎能绕过DEP+ASLR+CFG+页堆保护等多项防护技术,并且在2014年在贴吧公布了技术细节。本文作者对这个技术知之甚少,依然在探究中,希望有朝一日能够掌握该技术的原理。
本次案例的两个漏洞,产生的原因并不相同(堆溢出和数组越界),但是在地址泄漏方面的方式是相同的。通过构造如下的结构,来读取虚函数表的地址,以达到任意地址泄漏。当然后者数组越界,可以进一步实现任意地址读写,利用到方式更加多样。
前置知识
BSTR是一种Pascal-Style字符串(明确标示字符串长度)和C-Style字符串(以结尾)的混合物,一般用于COM中,是Unicode字符串,即标示字符串长度,最后还有一个值为字节。BSTR的存储结构
字符串头 —-4字节 存储了包好字节(Byte)的个数
字符串内容 —-以unicode方式存储,每个字符两字节(w_char – 2byte)
结束符 —-结束符null, 2字节
QArrayData是QT中定义的数组结构,头部包含一个24字节的数据结构。结构体定义如下。
struct Q_CORE_EXPORT QArrayData
{
    QtPrivate::RefCount ref;//引用计数
    int size;                //大小
    uint alloc : 31;         //分配的个数
    uint capacityReserved : 1;//适应模式
    qptrdiff offset; // in bytes from beginning of header  定位指针
    void *data()
    {
        Q_ASSERT(size == 0
                || offset 0 || size_t(offset) >= sizeof(QArrayData));
        return reinterpret_castchar *>(this) + offset;
    }
    const void *data() const
    {
        Q_ASSERT(size == 0
                || offset 0 || size_t(offset) >= sizeof(QArrayData));
        return reinterpret_castconst char *>(this) + offset;
    }
    // This refers to array data mutability, not "header data" represented by
    // data members in QArrayData. Shared data (array and header) must still
    // follow COW principles.
    bool isMutable() const
    {
        return alloc != 0;
    }
    enum AllocationOption {                   //5种模式  分配模式  使用shared_null[0]  使用shared_null[1]  可以增长   默认
        CapacityReserved    = 0x1,

[1] [2] [3] [4] [5] [6] [7] [8]  下一页

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