freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

unlink的一些补充
2021-09-15 19:46:58

上次已经比较详细的讲解了unlink宏,但是这只是在代码层面,下面我会讲一下unlink宏的一些逻辑或者是一些思想

#define unlink(AV, P, BK, FD) {                                            
    FD = P->fd;                                   
    BK = P->bk;                                   
    if (__builtin_expect (FD->bk != P || BK->fd != P, 0))             
      malloc_printerr (check_action, "corrupted double-linked list", P, AV);  
    else {                                    
        FD->bk = BK;                                  
        BK->fd = FD;                                  
        if (!in_smallbin_range (P->size)                      
            && __builtin_expect (P->fd_nextsize != NULL, 0)) {            
        if (__builtin_expect (P->fd_nextsize->bk_nextsize != P, 0)        
        || __builtin_expect (P->bk_nextsize->fd_nextsize != P, 0))    
          malloc_printerr (check_action,                      
                   "corrupted double-linked list (not small)",    
                   P, AV);                        
            if (FD->fd_nextsize == NULL) {                    
                if (P->fd_nextsize == P)                      
                  FD->fd_nextsize = FD->bk_nextsize = FD;             
                else {                                
                    FD->fd_nextsize = P->fd_nextsize;                 
                    FD->bk_nextsize = P->bk_nextsize;                 
                    P->fd_nextsize->bk_nextsize = FD;                 
                    P->bk_nextsize->fd_nextsize = FD;                 
                  }                               
              } else {                                
                P->fd_nextsize->bk_nextsize = P->bk_nextsize;             
                P->bk_nextsize->fd_nextsize = P->fd_nextsize;             
              }                                   
          }                                   
      }                                       
}

第一个检查

if (__builtin_expect (FD->bk != P || BK->fd != P, 0))
这一个语句是比较重要的,这个语句就是为了判断你前面的后面是不是你自己。在堆溢出中,会对一些数据进行覆盖(这个后面会讲),而这个函数在某一层面会阻止覆盖,但是也并不是万能的,因为攻击者还可以构造fake chunk

fd_nextsize和bk_nextsize指针

这两个指针并不是largebin中所有的chunk都会用到,只有尾指针才会用到。这里在某乎找到了一张图,一目了然image.png
看这张图就很容易看出来,fd指针指向高地址chunk,bk指针指向低地址chunk,而fd_nextsize指针指向相邻bin的低地址,bk_nextsize指向相邻largebin的高地址,很明显unlink宏里面脱链时也判断了largechunk的位置,并且对尾chunk也专门进行了脱链处理

本文参考自glibc:浅谈unlink堆的largebin attack利用,感谢前辈大佬

# linux # 堆
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者