• unlink


    这个知识点以前就看过了,但之前一直不是很懂,今天再来看的时候,把以前一些盲区扫了

    参考资料:

    https://ctf-wiki.github.io/ctf-wiki/pwn/linux/glibc-heap/unlink-zh/

    从0到1 ctfer书籍

    pwnki师傅的博客

    这三篇其实讲的也差不多,但是在不同角度上某些东西显的比较清楚

    原理

    所谓的UNlink其实就是链表的一个remove操作,先来看看linux的源码

    // 由于 P 已经在双向链表中,所以有两个地方记录其大小,所以检查一下其大小是否一致(size检查)
    if (__builtin_expect (chunksize(P) != prev_size (next_chunk(P)), 0))      
          malloc_printerr ("corrupted size vs. prev_size");               
    // 检查 fd 和 bk 指针(双向链表完整性检查)
    if (__builtin_expect (FD->bk != P || BK->fd != P, 0))                      
      malloc_printerr (check_action, "corrupted double-linked list", P, AV);  
    
      // largebin 中 next_size 双向链表完整性检查 
                  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);
    // fd bk
    if (__builtin_expect (FD->bk != P || BK->fd != P, 0))                      
      malloc_printerr (check_action, "corrupted double-linked list", P, AV);  

    在这种情况下,如果想利用unlink,那么必须要满足以下条件

    此时

    • FD->bk = target addr - 12 + 12=target_addr
    • BK->fd = expect value + 8

    那么我们上面所利用的修改 GOT 表项的方法就可能不可用了。但是我们可以通过伪造的方式绕过这个机制。

    首先我们通过覆盖,将 nextchunk 的 FD 指针指向了 fakeFD,将 nextchunk 的 BK 指针指向了 fakeBK 。那么为了通过验证,我们需要

    • fakeFD -> bk == P <=> *(fakeFD + 12) == P
    • fakeBK -> fd == P <=> *(fakeBK + 8) == P

    当满足上述两式时,可以进入 Unlink 的环节,进行如下操作:

    • fakeFD -> bk = fakeBK <=> *(fakeFD + 12) = fakeBK
    • fakeBK -> fd = fakeFD <=> *(fakeBK + 8) = fakeFD

    如果让 fakeFD + 12 和 fakeBK + 8 指向同一个指向 P 的指针,那么:

    • *P = P - 8
    • *P = P - 12

    即通过此方式,P 的指针指向了比自己低 12 的地址处。此方法虽然不可以实现任意地址写,但是可以修改指向 chunk 的指针,这样的修改是可以达到一定的效果的。

    此外,其实如果我们设置 next chunk 的 fd 和 bk 均为 nextchunk 的地址也是可以绕过上面的检测的。但是这样的话,并不能达到修改指针内容的效果。

    利用思路

    条件 

    UAF ,可修改 free 状态下 smallbin 或是 unsorted bin 的 fd 和 bk 指针

    已知位置存在一个指针指向可进行 UAF 的 chunk

    效果 

    使得已指向 UAF chunk 的指针 ptr 变为 ptr - 0x18

    思路 

    设指向可 UAF chunk 的指针的地址为 ptr

    修改 fd 为 ptr - 0x18

    修改 bk 为 ptr - 0x10

    触发 unlink

    ptr 处的指针会变为 ptr - 0x18。

    疑问解答

    1、-0x18和-0x10是什么意思?这里的-0x18和-0x10一直是我上次的疑问,后面发现这目的就是为的绕开检查,并且直接对uaf chunk 指针直接进行修改内容

    2、为什么ptr会指向ptr-0x18?答:ptr变为ptr-0x18的原因是FD=ptr-0x18 ptr=FD->bk  并且  BK=ptr-0x10    ptr=BK->fd,由于unlink是remove操作,所以BK->fd=FD=ptr-0x18

    相关例题可以在 ctf wiki上看

  • 相关阅读:
    [转]swift 学习资源 大集合
    [转]Swift 编程语言入门教程
    luogu 3375 KMP模板题
    我终于明白了的马拉车算法———感谢我们学校的大佬
    A*B problem(FFT)
    又是毕业季1&&又是毕业季2
    邻接表——最简单易懂的写法——向非我非非我大佬低头
    马拉车——Manacher一篇看上去很靠谱的理解(代码显然易懂)
    邻接表存储
    一直想写的关于tarjan算法的理解——向struct edge大佬低头
  • 原文地址:https://www.cnblogs.com/pppyyyzzz/p/13762102.html
Copyright © 2020-2023  润新知