linux heap unlinking分析

虽然这个技术已经不能在新版本上使用了,但是还是有许多学习价值的。
刚开始学,与大家分享一下,直说自己不是很明白的几个点,然后是参考的文章。

实例代码如下:

/* 
 Heap overflow vulnerable program. 
 */
#include <stdlib.h>
#include <string.h>

int main( int argc, char * argv[] )
{
        char * first, * second;

/*[1]*/ first = malloc( 666 );
/*[2]*/ second = malloc( 12 );
        if(argc!=1)
/*[3]*/         strcpy( first, argv[1] );
/*[4]*/ free( first );
/*[5]*/ free( second );
/*[6]*/ return( 0 );
}

我们要知道堆是从内存低址到内存高址增长的,很明显第三行代码strcpy有堆溢出。
此时如果传入的数据过多,就会覆盖second的堆首、堆身数据。


payload条件如下:
  • prev_size = even number and hence PREV_INUSE bit is unset.
  • size = -4
  • fd = free address – 12
  • bk = shellcode address
这里fd、bk都是指second中要被覆盖的信息。

下边重点解释一下:
怎么判断堆是被占用还是free呢 ,就是看prev_inuse位
怎么确定second堆是处于占用还是free呢 就是查看second的下一个堆的prev_inuse位。
这样通过first-8+size(first)+size(second)+4(pre_size),就可以确定second是否被占用。

此时我们覆盖size为-4,所以上边的计算就是first-8+size(first)
也就是 认为second的下一个chunk就是second本身,这样通过覆盖second的prev_inuse,就可以使second chunk处于free状态。

在free( first );时,因为first chunk和second chunk都处于free状态,发生unlink操作。


fd保存first chunk 下一个chunk的地址,再加上12就是下一个chunk的bk ,unlink操作将其覆写为first chunk的bk
bk保存first chunk上一个chunk的地址,再加上8就是上一个chunk的fd地址,unlink将其覆写为fd的地址

简单点来说就是:
  • fd+12 is overwritten with bk.
  • bk+8 is overwritten with fd.

此时我们将fd设置为free address – 12,bk 设置为shellcode address,所以fd+12正好就是free@got的地址,正好将其覆盖为shellcode的地址,这样以后调用free函数时,我们的shellcode就可以执行了。

  • fd = free address – 12
  • bk = shellcode address

参考资料:
5. http://wooyun.jozxing.cc/static/drops/tips-16610.html
等。

猜你喜欢

转载自blog.csdn.net/qq_35519254/article/details/77532248
今日推荐