软件安全实验——pre12(UAF漏洞预习)

Posted 大灬白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了软件安全实验——pre12(UAF漏洞预习)相关的知识,希望对你有一定的参考价值。

1、名词解释:double free,UAF (Use After Free),RELRO(Relocation Read Only),Dangling pointer,Control Flow Guard

  Double Free其实就是一种在free时利用伪造chunk并且欺骗操作系统,达到修改内存的目的。
  Double Free其实就是同一个指针free两次。虽然一般把它叫做double free。其实只要是free一个指向堆内存的指针都有可能产生可以利用的漏洞
  double free的原理其实和堆溢出的原理差不多,都是通过unlink这个双向链表删除的宏来利用的。只是double free需要由自己来伪造整个chunk并且欺骗操作系统。

  UAF:应用程序调用free()释放内存时,如果内存块小于256kb,dlmalloc并不马上将内存块释放回内存,而是将内存块标记为空闲状态。这么做的原因有两个:一是内存块不一定能马上释放会内核(比如内存块不是位于堆顶端),二是供应用程序下次申请内存使用(这是主要原因)。当dlmalloc中空闲内存量达到一定值时dlmalloc才将空闲内存释放会内核。如果应用程序申请的内存大于256kb,dlmalloc调用mmap()向内核申请一块内存,返回返还给应用程序使用。如果应用程序释放的内存大于256kb,dlmalloc马上调用munmap()释放内存。dlmalloc不会缓存大于256kb的内存块,因为这样的内存块太大了,最好不要长期占用这么大的内存资源。
  简单讲就是第一次申请的内存空间在释放过后没有进行内存回收,导致下次申请内存的时候再次使用该内存块,使得以前的内存指针可以访问修改过的内存。

  RELRO(RELocation Read-Only,只读重定位)让加载器将重定位表中加载时解析的符号标记为只读,这减少了GOT覆写攻击的面积。RELRO可以分为Partial RELRO(部分RELRO)和Full RELRO(完整RELRO)。开启Partial RELRO的话GOT表是可写的;开启FULL RELRO的话GOT表是只读的。从Fedora 23开始所有软件包都已启用了Full RELRO。开启-Wl,-z,relro选项即可开启Partial RELRO;开启-Wl,-z,relro,-z,now选项即可开启Full RELRO。

  Dangling pointer:指针指向非法的内存地址,那么这个指针就是悬挂指针,也叫野指针。意为无法正常使用的指针。
  一个指针所指的内存被释放后,这个指针就被悬空了。访问悬空指针,结果随机。可能导致程序功能不正常,也可能导致程序崩溃。如果受到影响的是其它功能,问题通常很难定位。

  Control Flow Guard(CFG)是一种高度优化的平台安全功能,旨在解决内存损坏漏洞。通过严格限制应用程序可以执行代码的位置,使得利用缓冲区溢出等漏洞执行任意代码变得更加困难。CFG扩展了以前的漏洞利用缓解技术,如/ GS,DEP和ASLR。
  CFG的编译和运行时支持的有效组合实现了控制流完整性,这严格限制了间接调用指令可以执行的位置。
编译器执行以下操作:
为编译的代码添加轻量级安全检查。
标识应用程序中作为间接调用的有效目标的函数集。
Windows内核提供的运行时支持:
有效维护标识有效间接调用目标的状态。
实现验证间接调用目标是否有效的逻辑。

2、阅读下面这三篇文章:

UAF学习–原理及利用
https://www.cnblogs.com/alert123/p/4918041.html

  在指针释放后再申请相同大小的内存,系统会将释放的地址进行分配,以提高系统运行速度,因此可以修改到被释放的内存数据,如果被释放的指针继续被使用,则会造成UAF漏洞。

  通过UAF漏洞,可能可以造成一些任意内存的修改,结合代码特点,可能会造成任意内存的读取或者,严重的能够造成任意命令的执行,获得shell。 取决于被释放的指针是怎么使用的

Linux内核提权漏洞的分析和利用(CVE-2016-0728)
http://www.freebuf.com/vuls/93799.html

通过UseAfterFree实现命令执行
https://bbs.pediy.com/thread-221537.htm

  modify_msg函数从用户读取数据,然后拷贝到对应的指针中,但此时使用的是一个已经释放的msg结构指针。当输入content时,会取content的长度作为大小分配内存,当分配内存大小等于msg结构大小(x86上是40字节,会将刚才释放的内存分配给content指针。此外由于msg结构指针刚好是40个字节,再给msg分配堆内存是,由于需要8字节对齐,而40个字节+8字节[prev_size+size],刚好8字节对齐,另外由于40字节,在堆中属于fastbin管理,不会发生合并,free后再分配时,就会返回相同的堆块)。
  接着会将用户输入的内容(content)拷贝到content指针中,即我们构造的恶意内容,覆盖了原来的Message中的char* author、char* title等地址内容。
  在循环代码中,modify_msg完之后可以继续进入modify_msg,此时msg中相关地址,如author、title和content地址已经变成free函数在got表中的位置,也就是我们输入的内容可以覆盖GOT表!我们把free函数的GOT表地址覆盖成system函数地址,下次在执行free函数时,就会执行system函数,从而达到命令执行。

以上是关于软件安全实验——pre12(UAF漏洞预习)的主要内容,如果未能解决你的问题,请参考以下文章

软件安全实验——pre6(整数溢出堆溢出栈溢出漏洞预习)

软件安全实验——pre7(JIT sprayheap spraySEH绕过DEP漏洞预习)

软件安全实验——pre11(XSS跨站脚本攻击预习)

软件安全实验——pre8(SQL注入预习)

软件安全实验——pre4(格式化字符串提权预习)

软件安全实验——pre9(堆栈保护机制return-to-libc预习)