unlink

作者: intmian | 来源:发表于2018-05-09 20:00 被阅读7次

堆 pwn


glibc中间维护的bins其实是用来存放malloc时从heap中割下来的堆,为了避免在heap中割下了太多的连续的free chunk,系统会将free chunk自动合并到top chunk中去(top chunk指系统heap中最高位未分配的那个chunk)或者合并成为更大的一个chunk。


条件:相邻的两块chunk 一块为top chunk 一块为free chunk 或者两块两块 free chunk。所以我们要做的是先连续割两块chunk,保证他们是连续的,以保证他们会unlink。

在溢出时之所以要覆写p位,就是为了能够触发unlink


流程:
如果上一块是free chunk
  合并上一块chunk并对上一块做unlink
如果下一块是
  top:合并到top
  一般chunk:
    是free chunk:合并下一块chunk,并对下一块做unlin。最终加入unsortedbin
    正在使用中:加入unsortedbin


最终结果,所有的同样大小的free chunk递归合并


假定有三块连续的smallchunk
第一块第二块freed,第三块issued。
***********************************
prevsize = 0
size = 0x80
fd = &smallbin
bk = &smallbin
***********************************
prevsize = 0
size = 0x80
***********************************
prevsize = 0
size = 0x81(p位+1代表上一块已经使用已经使用)
***********************************

free(p)(第二块),就会导致一二两块合并,从而触发unlink
系统检验p+size 与p-prevsize得到了上下两个块的头

p+0x10为FD,p+0x18为BK

unlink(P,FD,BK)
{
    P = p
    FD = P -> BK
    BK = P -> FD
    FD -> BK = BK
    BK -> FD = FD
}

相当于将这个块从bin中脱链。然后系统会将上一个块更改size之类的,然后链到unsortedbin上。


预期利用方式,将程序劫持到shellcode中

shellcode是一段用于利用软件漏洞而执行的代码,以其经常让攻击者获得shell而得名。 shellcode常常使用机器语言编写。

利用unlink导致返回了weichunk中指向的地址。最后触发任意写,将必须触发的函数在got表中值改到shellcode,或者更改函数指针变量的值导致触发system()。


利用思路:
首先很直观地想到通过堆溢出q堆盖掉后面的FD和BK,将fd改为gou entry -12,将bk 改为 shellcode 的地址,将size低位改为1。在free(q)时会发生如下过程:

free(q)
FD = P->fd = got entry -12
BK = P->bk =sc(shellcode) addr
FD->bk=BK(got hijacking)
got entry -12 +12 = sc addr
BK->fd=FD
sc addr+8=got entry -12

在此过程后,会会进行一次任意写将FD+0x10的地方写入shellcode
然而在现实情况中,现代的glibc会有着针对chunk的检查以及其他保护机制,使得该方法无法使用。
因此我们的利用方式是
***********************************
prevsize = 0
size = 0x80

***********************************
prevsize = 0
size = 0x91
< r指向此处>
***********************************
prevsize = 0
size = 0x80(p位+1代表上一块已经使用已经使用)
< q指向此处>
***********************************
通过对于第二个chunk进行堆溢出将第二个块整体盖掉然后在其中伪造一个chunk并且改写第三个堆块的prev_size
最后变为
***********************************
prevsize = 0
size = 0x80

***********************************
prevsize = 0
size = 0x91
fake prev_size = 0x90< r指向此处>
fake size = 0x80
fake fd = &r-0x18
fake bk = &r-0x10
***********************************
prevsize = 0x80
size = 0x80(p位+1代表上一块已经使用已经使用)
< q指向此处>
***********************************
这样子在可以绕过两个检查,成功将r并入了chunk中从而进行任意写。
具体流程:
free(q)
找到q与r都是freed
找到了最下面的q,通过q-0x10找到的prev_size。q-0x10-prev_size找到r。对于r执行unlink
跳过了check:
r->fd->bk == r = *(&r-0x18+0x18) ==r
f->bk->fd == r = *(&r-0x18+0x18) ==r

FD->bk = BK =》(&r-0x18+0x18)=&r-0x10
BK->fd = FD =》
(&r-0x10+0x10)=&r-0x18

相关文章

  • 文件目录操作其他(基于itop4412)

    1 删除文件目录链接 解除链接unlink• man 2 unlink• 解除链接函数• int unlink(c...

  • unlink attack --how2heap unlink

    unlink 简介 unlink用于将 chunk 从所在的空闲链表中取出来。基本过程如下: 执行unlink时的...

  • unlink:

    堆入门---unlink的理解和各种题型总结 unlink主要是通过unlink来实现向任意地址写入,这题主要是想...

  • php删除文件

    php删除文件可以使用unlink函数 具体用法如下 unlink($filename);

  • unlink

    堆 pwn glibc中间维护的bins其实是用来存放malloc时从heap中割下来的堆,为了避免在heap中割...

  • Node.js fs模块-unlink、mkdir()、rmdi

    一. unlink()方法-->删除文件 1. fs.unlink('要删除文件的路径',回调函数) 2. 同步版...

  • C语言基础-unlink函数的使用

    一、头文件 二、函数原型 三、函数介绍 unlink()函数功能即为删除文件。执行unlink()函数会删除所给参...

  • Linux中的Unlink命令(删除文件)

    在本文中,我们将向您展示如何使用“unlink”命令删除GNU/Linux系统中的文件。 使用unlink删除文件...

  • pwnable.kr之unlink

    这道题考查基础的堆溢出unlink利用, 其中实现的unlink函数是对早期ptmalloc的模拟. 程序给了堆栈...

  • PWN unlink

    最近做了一些堆的题,发现对unlink还是不太熟悉,所以回来做下笔记 unlink的目的:把一个双向链表中的空闲块...

网友评论

    本文标题:unlink

    本文链接:https://www.haomeiwen.com/subject/jovorftx.html