unlink

unlink|原理

1、简介:俗称脱链,就是将链表头处的free堆块unsorted bin中脱离出来,然后和物理地址相邻的新free的堆块合并成大堆块(向前合并或者向后合并),再放入到unsorted bin中。

2、危害原理:通过伪造free状态的fake_ chunk, 伪造fd指针和bk指针,通过绕过unlink的检测实现unlink,un'link就 会往p所在的位置写入p-0x18,从而实现任意地址写的漏洞。

3、漏洞产生原因: Offbynull、offbyone、 堆溢出,修改了堆块的使用标志位

unlink的源码如下:

#!c
1413    /* Take a chunk off a bin list */
1414    #define unlink(AV, P, BK, FD) {                                            
1415        FD = P->fd;                                                                      
1416        BK = P->bk;                                                                      
1417        if (__builtin_expect (FD->bk != P || BK->fd != P, 0))                      
1418          malloc_printerr (check_action, "corrupted double-linked list", P, AV);  
1419        else {                                                                      
1420            FD->bk = BK;                                                              
1421            BK->fd = FD;                                                              
1422            if (!in_smallbin_range (P->size)                                      
1423                && __builtin_expect (P->fd_nextsize != NULL, 0)) {                      
1424                if (__builtin_expect (P->fd_nextsize->bk_nextsize != P, 0)              
1425                    || __builtin_expect (P->bk_nextsize->fd_nextsize != P, 0))    
1426                  malloc_printerr (check_action,                                      
1427                                   "corrupted double-linked list (not small)",    
1428                                   P, AV);                                              
1429                if (FD->fd_nextsize == NULL) {                                      
1430                    if (P->fd_nextsize == P)                                      
1431                      FD->fd_nextsize = FD->bk_nextsize = FD;                      
1432                    else {                                                              
1433                        FD->fd_nextsize = P->fd_nextsize;                              
1434                        FD->bk_nextsize = P->bk_nextsize;                              
1435                        P->fd_nextsize->bk_nextsize = FD;                              
1436                        P->bk_nextsize->fd_nextsize = FD;                              
1437                     }                                                              
1438                 } else {                                                              
1439                    P->fd_nextsize->bk_nextsize = P->bk_nextsize;                      
1440                    P->bk_nextsize->fd_nextsize = P->fd_nextsize;                      
1441                 }                                                                      
1442             }                                                                      
1443         }                                                                              
1444   }
1445    
1446    /*

其中的检查机制

 if (__builtin_expect (FD->bk != P || BK->fd != P, 0))                      
       malloc_printerr (check_action, "corrupted double-linked list", P, AV);

在unlink之前会检查一下当前结点的前一个结点的后一个节点和当前结点的后一个节点的前一个节点是不是同一个结点,要想成功unlink,必须绕过这个检测,一种思路是将chunk->fd设置为(&chunk_addr - 0x18),因为:

chunk->fd->bk == *(chunk->fd + 0x18) == *(&chunk_addr - 0x18 + 0x18) == chunk_addr

这样就满足了检测条件,同理需要将chunk->bk设置为(&chunk_addr-0x10)。检测之后进行unlink操作

unlink|绕过&利用

1、伪造如下: chunk = 0x0602280 (P是将要合并到的堆地址,P存在于chunk中,相当于*chunk=P ) P_ fd = chunk-0x18 = 0x602268 P_ bk = chunk-0x10 = 0x602270 2、绕过技巧: define unlink(P, BK, FD) { FD= P->fd; \FD = 0x602268 BK= P->bk; \BK = 0x602270 if(_ builtin_ expect (FD->bk != P|I BK->fd != P, 0)) \FD->bk = *(0x602268+0x18) | *(0x602280)= P \BK->fd = (0x602270+0x10) =(0x602280)= P,绕过! malloc_ printerr (check_ _action, "corrupted double-linked list", P, AV); . FD->bk= BK; \ *(0x602268+0x18) | *(0x602280) = 0x602270 BK->fd = FD; \ *(0x602270+0x10) | *(0x602280) = 0x602268

最终效果就是往chunk里面写入了chunk-0x18的值!



posted @ 2022-03-07 21:50  vi0let  阅读(32)  评论(0编辑  收藏  举报