五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

二進制安全之堆溢出(系列)——堆基礎 & 結(jié)構(gòu)(四)

2020-03-26 16:50 作者:匯智知了堂  | 我要投稿

二進制安全之堆溢出(系列)——“堆基礎&結(jié)構(gòu)”第四節(jié)上回咱們聊到碎塊合并問題本次咱們從ulink講起

unlink

  • unlink用來將一個雙向鏈表bin鏈中的一個元素取出來,即斷鏈過程

  • 引發(fā)unlink的幾種方式

malloc

  • 從恰好大小合適的largebin中獲取chunk會unlink

  • fastbin和smallbin沒有使用unlink

  • 依次遍歷unsorted bin時也沒有使用unlink

  • 合并和切割的時候都會unlink

free

  • 后向合并,合并物理相鄰低地址空閑chunk的時候會unlink

  • 前向后并,合并物理相鄰高地址空閑chunk的時候會unlink(除了top chunk)

relloc

consolidate

  • unlink源碼分析

? ? /* Take a chunk off a bin list 用于將某一個空閑 chunk從其所處的bin中脫鏈*/

? ? #define unlink(AV, P, BK, FD) {? //P 即為待脫鏈的空閑 chunk? ? ? ? ? ? ? ? ? ? ? ? \

? ? if (__builtin_expect (chunksize(P) != prev_size (next_chunk(P)), 0))

? ? /*檢查一下其大小是否一致(size檢查)

? ? 故在做overlap的時候,偽造的堆塊的size需要和presize一致

? ? */

? ? malloc_printerr ("corrupted size vs. prev_size");? ? ? ? ? ? ? ?\

? ? FD = P->fd;? ? ? ? ?//FD為? ?P的前一個空閑chunk

? ? BK = P->bk;? ? ? ? ?//BK為p的后一個空閑chunk

? ? if (__builtin_expect (FD->bk != P || BK->fd != P, 0))

? ? /*承上檢查,檢查當前的p是否與兩邊相連

? ? */

? ? malloc_printerr ("corrupted double-linked list");

? ? else {? ? ? //設置相鄰 chunk 的 fd 或 bk 指針

? ? FD->bk = BK;

? ? BK->fd = FD;

? ? /*

? ? 可以在這里修改p的fd和bk

? ? p->fd = target? //修改fd

? ? p->bk = target? ? //修改bk

? ? 因此

? ? FD = target

? ? BK = target

? ? FD->bk = *(target + 0x18)? ?//prev_size + size +fd = 0x18

? ? BK->fd = *(target + 0x10)

? ? 上面的改法無法繞過FD->bk != P || BK->fd != P的檢查

? ? //TODO follow

? ? FD = target - 0x18? ? ? ? ? ? ? ?//自己控制堆塊修改值即可

? ? BK = target - 0x10

? ? FD->bk = *(target - 0x18 + 0x18) = BK = target - 0x10 = p

? ? BK->fd = *(target - 0x10 + 0x10) = FD = target - 0x18 = p

? ? 這樣就可以繞過當前的校驗

? ? payload = 0x18 *'a' + target_addr

? ? 構(gòu)造payload,替換target為got或任意地址

? ? */

? ? /*對于smallbin而言,以上脫鏈完成

? ? 下面處理largebin的脫鏈,多了fd/bk_nextsize的unlink過程

? ? */

? ? if (!in_smallbin_range (chunksize_nomask (P))

? ? && __builtin_expect (P->fd_nextsize != NULL, 0)) {

? ? //說明P是相應bins的第一個chunk,否則fd_nextsize和bk_nextsize沒有意義

? ? if (__builtin_expect (P->fd_nextsize->bk_nextsize != P, 0)

? ? || __builtin_expect (P->bk_nextsize->fd_nextsize != P, 0))? ? \

? ? malloc_printerr ("corrupted double-linked list (not small)");

? ? if (FD->fd_nextsize == NULL) { //p斷鏈之后,FD成為當前bins的第一個chunk

? ? if (P->fd_nextsize == P)? ? //只有唯一的chunk時

? ? 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成為下一組bins的第一個chunk

? ? P->fd_nextsize->bk_nextsize = P->bk_nextsize;

? ? P->bk_nextsize->fd_nextsize = P->fd_nextsize;

? ? }

? ? }

? ? }

? ? }

  • 泄露libc的地址

P位于雙向鏈表頭部,bk泄露P位于雙向鏈表尾部,fd泄露雙向鏈表中只包含一個空閑chunk時,P位于雙向鏈表中,fd和bk均可泄露tips:這里的頭部指的是bin的fd指向的chunk,即雙向鏈表中最新加入的chunk,反之亦然
  • 實例分析

斷鏈的目標:p ,p之后需要有一個已經(jīng)free的堆塊覆蓋p->fd = target - 0x18 p->bk = target - 0x10,注意此時的fd和bk都是地址的值


?target 為堆中的任意堆塊的地址的值,前提是可以通過heap_base + offset 獲得地址現(xiàn)在假設target為note2,note2的地址為heap_base+0x60,則target需要填heap_base+0x60

當free p的時候,就會和之后的空閑堆塊發(fā)生合并,從而引發(fā)unlink此時按順序斷鏈 *(p->fd->bk)= bk,*(p->bk->fd) = fd,即最終實現(xiàn)*(target)=target-0x18

?p->fd->bk的內(nèi)容為bk的值,故`*(p->fd->bk)= bk`p->bk->fd的內(nèi)容為bk的值,故`*(p->bk->fd)= fd`最終結(jié)果為第二條語句的執(zhí)行結(jié)果這時前面的target為指針,上述結(jié)果相當于target指向了target-0x18的地址空間

此時我們向target里面寫入0x18 * 'a',就相當于指針target+0x18指向了target起始的地址緊接著寫入malloc_hook的地址,然后再edit target,寫入system的地址,就相當于target+0x18+0x8指向了target+0x8的地址空間此時就相當于*(malloc_hook) = system ,再次malloc的時候就會調(diào)用system了。

調(diào)試

源代碼一

? #include<stdio.h>

? ? #include<malloc.h>

? ? #include<unistd.h>

? ? #include<string.h>

? ? int main(){

? ? int size = 0x70;

? ? void *p = malloc(size);

? ? void *q = malloc(size);

? ? void *junk = malloc(size);

? ? sleep(0);

? ? free(q);

? ? sleep(0);

? ? printf("%p\n",q);

? ? int *r = malloc(0x60);

? ? printf("%p\n",r);

? ? sleep(0);

? ? return 0;

堆塊分配后的heap與內(nèi)存布局


?0x602000 FASTBIN {? ===>chunk1

? ? prev_size = 0,

? ? size = 129,

? ? fd = 0x0,

? ? bk = 0x0,

? ? fd_nextsize = 0x0,

? ? bk_nextsize = 0x0

? ? }

? ? 0x602080 FASTBIN {? ===>chunk2

? ? prev_size = 0,

? ? size = 129,

? ? fd = 0x0,

? ? bk = 0x0,

? ? fd_nextsize = 0x0,

? ? bk_nextsize = 0x0

? ? }

? ? 0x602100 FASTBIN {? ===>chunk3

? ? prev_size = 0,

? ? size = 129,

? ? fd = 0x0,

? ? bk = 0x0,

? ? fd_nextsize = 0x0,

? ? bk_nextsize = 0x0

? ? }

? ? 0x602180 PREV_INUSE {

? ? prev_size = 0,

? ? size = 134785,? ? ? ? ? ? ===>top_chunk

? ? fd = 0x0,

? ? bk = 0x0,

? ? fd_nextsize = 0x0,

? ? bk_nextsize = 0x0

? ? }

? ? }


---------------------------------------------------------------------------------------------------------------------------

?0x602000:? ? ? ?0x0000000000000000? ? ? 0x0000000000000081 <=== chunk1

? ? 0x602010:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602020:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602030:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602040:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602050:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602060:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602070:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602080:? ? ? ?0x0000000000000000? ? ? 0x0000000000000081 <=== chunk2

? ? 0x602090:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6020a0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6020b0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6020c0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6020d0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6020e0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6020f0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602100:? ? ? ?0x0000000000000000? ? ? 0x0000000000000081? <=== chunk3

? ? 0x602110:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602120:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602130:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602140:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602150:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602160:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602170:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602180:? ? ? ?0x0000000000000000? ? ? 0x0000000000020e81? <=== top chunk

? ? 0x602190:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6021a0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6021b0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6021c0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6021d0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

free(q)之后的heap與內(nèi)存布局

?0x602000 FASTBIN {

? ? ? prev_size = 0,

? ? ? size = 129,

? ? ? fd = 0x0,

? ? ? bk = 0x0,

? ? ? fd_nextsize = 0x0,

? ? ? bk_nextsize = 0x0

? ? }

? ? 0x602080 FASTBIN {

? ? ? prev_size = 0,

? ? ? size = 129,

? ? ? fd = 0x7ffff7dd1be8 <main_arena+200>,

? ? ? bk = 0x7ffff7dd1be8 <main_arena+200>,

? ? ? fd_nextsize = 0x0,

? ? ? bk_nextsize = 0x0

? ? }

? ? 0x602100 FASTBIN {

? ? ? prev_size = 128,

? ? ? size = 129,

? ? ? fd = 0x0,

? ? ? bk = 0x0,

? ? ? fd_nextsize = 0x0,

? ? ? bk_nextsize = 0x0

? ? }

? ? 0x602180 PREV_INUSE {

? ? ? prev_size = 0,

? ? ? size = 1041,

? ? ? fd = 0x3039303230367830,

? ? ? bk = 0xa,

? ? ? fd_nextsize = 0x0,

? ? ? bk_nextsize = 0x0

? ? }

? ? 0x602590 PREV_INUSE {

? ? ? prev_size = 0,

? ? ? size = 133745,

? ? ? fd = 0x0,

? ? ? bk = 0x0,

? ? ? fd_nextsize = 0x0,

? ? ? bk_nextsize = 0x0

? ? }

---------------------------------------------------------------------------------------------------------------------------

?0x602000:? ? ? ?0x0000000000000000? ? ? 0x0000000000000081

? ? 0x602010:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602020:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602030:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602040:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602050:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602060:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602070:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602080:? ? ? ?0x0000000000000000? ? ? 0x0000000000000081? ==>chunk未發(fā)生變化

? ? 0x602090:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6020a0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6020b0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6020c0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6020d0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6020e0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6020f0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602100:? ? ? ?0x0000000000000000? ? ? 0x0000000000000081

? ? 0x602110:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602120:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602130:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602140:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602150:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602160:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602170:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602180:? ? ? ?0x0000000000000000? ? ? 0x0000000000020e81

? ? //此時free掉的chunk_size為81的原因 :free掉了,但沒有把指針置空,第二個堆塊變成空閑堆塊,由bins鏈管理,chunk_size依然為0x80


此時的bins鏈

fastbins

? ? 0x20: 0x0

? ? 0x30: 0x0

? ? 0x40: 0x0

? ? 0x50: 0x0

? ? 0x60: 0x0

? ? 0x70: 0x0

? ? 0x80: 0x602080 ?— 0x0? ? ? ? ? ?==》被釋放的chunk進入了fastbin鏈

? ? unsortedbin

? ? all: 0x0

? ? smallbins

? ? empty

? ? largebins

? ? empty

分配新的0x60的chunk后的heap和內(nèi)存布局

0x602000 FASTBIN {

? ? ? prev_size = 0,

? ? ? size = 129,

? ? ? fd = 0x0,

? ? ? bk = 0x0,

? ? ? fd_nextsize = 0x0,

? ? ? bk_nextsize = 0x0

? ? }

? ? 0x602080 FASTBIN {? ? ===>chunk2被切割出0x70的空間,剩下的0x10自動和top_chunk合并

? ? ? prev_size = 0,

? ? ? size = 129,

? ? ? fd = 0x7ffff7dd1be8 <main_arena+200>,

? ? ? bk = 0x7ffff7dd1be8 <main_arena+200>,

? ? ? fd_nextsize = 0x0,

? ? ? bk_nextsize = 0x0

? ? }

? ? 0x602100 {

? ? ? prev_size = 128,? ? ? //說明上一個chunk被free掉了,大小為0x80

? ? ? size = 128,

? ? ? fd = 0x0,

? ? ? bk = 0x0,

? ? ? fd_nextsize = 0x0,

? ? ? bk_nextsize = 0x0

? ? }

? ? 0x602180 PREV_INUSE {? ?//printf的緩沖區(qū)堆塊 ,從top_chunk中分配,多個printf分配一個chunk

? ? ? prev_size = 0,

? ? ? size = 1041,

? ? ? fd = 0x3039303230367830,? ? ??

? ? ? bk = 0xa,

? ? ? fd_nextsize = 0x0,

? ? ? bk_nextsize = 0x0

? ? }

? ? 0x602590 PREV_INUSE {

? ? ? prev_size = 0,

? ? ? size = 133745,

? ? ? fd = 0x0,

? ? ? bk = 0x0,

? ? ? fd_nextsize = 0x0,

? ? ? bk_nextsize = 0x0

? ? }

---------------------------------------------------------------------------------------------------------------------------


0x602000:? ? ? ?0x0000000000000000? ? ? 0x0000000000000081

? ? 0x602010:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602020:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602030:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602040:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602050:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602060:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602070:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602080:? ? ? ?0x0000000000000000? ? ? 0x0000000000000081? ==>重新組裝的chunk2

? ? 0x602090:? ? ? ?0x00007ffff7dd1be8? ? ? 0x00007ffff7dd1be8? ==>fd和bk指向main_arena的地址

? ? 0x6020a0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6020b0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6020c0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6020d0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6020e0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6020f0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602100:? ? ? ?0x0000000000000080? ? ? 0x0000000000000081

? ? 0x602110:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602120:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602130:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602140:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602150:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602160:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602170:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x602180:? ? ? ?0x0000000000000000? ? ? 0x0000000000000411

? ? 0x602190:? ? ? ?0x3039303230367830? ? ? 0x000000000000000a

? ? 0x6021a0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6021b0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6021c0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

? ? 0x6021d0:? ? ? ?0x0000000000000000? ? ? 0x0000000000000000

此時的bins鏈

fastbins

? ? 0x20: 0x0

? ? 0x30: 0x0

? ? 0x40: 0x0

? ? 0x50: 0x0

? ? 0x60: 0x0

? ? 0x70: 0x0

? ? 0x80: 0x0

? ? unsortedbin

? ? all: 0x0

? ? smallbins

? ? 0x80: 0x602080 —? 0x7ffff7dd1be8 (main_arena+200) ?— 0x602080

? ? largebins

? ? empty

源代碼二

#include<stdio.h>

#include<malloc.h>

#include<unistd.h>

#include<string.h>

int main(int argc,char *argv[])

{

? ? ?int size = 0x100;

? ? ?void *p = malloc(size);

? ? ?void *junk = malloc(size);? ? ?//創(chuàng)建以junk防止釋放p,q時q的prev_inuse為0而合并

? ? ?void *q = malloc(size);

? ? ?void *r = malloc(size);? ? ? ? ? //防止q和top_chunk合并,在沒有printf的前提下

? ? ?sleep(0);

? ? ?printf("p:0x%x\n",p);

? ? ?printf("q:0x%x\n",q);

? ? ?printf("r:0x%x\n",r);

? ? ?sleep(0);

? ? ?strcpy(p,"aaaaaaaaaaaaaaaaa");

? ? ?strcpy(q,"bbbbbbbbbbbbbbbbb");

? ? ?strcpy(r,"ccccccccccccccccc");

? ? ?sleep(0);

? ? ?free(p);

? ? ?free(q);

? ? ?sleep(0);

? ?return 0;

}

在不創(chuàng)建junc和r的情況下,p,q以及p,q,top_chunk會發(fā)生合并

#include<stdio.h>

#include<malloc.h>

#include<unistd.h>

#include<string.h>

int main(int argc,char *argv[])

{

? ? ?int size = 0x100;

? ? ?void *p = malloc(size);

? ? ?void *q = malloc(size);

? ? ?sleep(0);

? ? ?strcpy(p,"aaaaaaaaaaaaaaaaa");

? ? ?strcpy(q,"bbbbbbbbbbbbbbbbb");

? ? ?free(p);

? ? ?free(q);

? ? ?sleep(0);

? ?return 0;

}

---------------------------------------------------------------------------------------------------------------------------

0x602000 PREV_INUSE {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?===>p、q合并

? prev_size = 0,?

? size = 545,?

? fd = 0x7ffff7dd1b78 <main_arena+88>,? ===>fd指向main_arena

? bk = 0x7ffff7dd1b78 <main_arena+88>,? ===>bk指向main_arena

? // 因為當前只有一個main_arena只管理一個合并之后的堆塊了

? fd_nextsize = 0x61,?

? bk_nextsize = 0x0

}

0x602220 {

? prev_size = 544,?

? size = 1040,?

? fd = 0x3132303678303a71,? ? ? ? ? ? ? ? ? ? ? ? ? ===>print

? bk = 0xa3032,?

? fd_nextsize = 0x0,?

? bk_nextsize = 0x0

}

0x602630 PREV_INUSE {

? prev_size = 0,?

? size = 133585,?

? fd = 0x0,?

? bk = 0x0,?

? fd_nextsize = 0x0,?

? bk_nextsize = 0x0

}?

此時的bins鏈

fastbins

0x20: 0x0

0x30: 0x0

0x40: 0x0

0x50: 0x0

0x60: 0x0

0x70: 0x0

0x80: 0x0

unsortedbin

all: 0x602000 —? 0x7ffff7dd1b78 (main_arena+88) ?— 0x602000 ==>只有一個合并之后的堆塊

smallbins

empty

largebins

empty

(main_arena+88)的原因

main_arena的結(jié)構(gòu)體前項變量:

__libc_lock_define (, mutex);? ? ? ?//定義了一個0x4字節(jié)的lock

int flags;? ? ? ? ? ? ? ? ? ? ? //0x4

int have_fastchunks;? ? ? ? ? ? ? ? //0x4

mfastbinptr fastbinsY[NFASTBINS]; //fastbin鏈的管理頭,總共10個, 每個0x10字節(jié)

mchunkptr top;? ? ? //0x4 到此為止總共0x96字節(jié)

注:glibc2.27為0x96

vmmap查看到(main_arena+88)出現(xiàn)在libc的地址范圍

0x7ffff7dd1000 0x7ffff7dd3000 rw-p 2000 1c4000 /lib/x86_64-linux-gnu/libc-2.23.so

相同版本的libc,main_arena的偏移固定

main_arena的地址存放在0x602000中

pwndbg> x/20gz 0x602000

0x602000:? ?0x0000000000000000? 0x0000000000000221

0x602010:? ?0x00007ffff7dd1b78? 0x00007ffff7dd1b78

利用方法

overlap --> 打印當前堆塊的內(nèi)容 --> 獲取main_arena的地址 --> 通過固定的偏移計算出libc的地址

當size大于0x400的時候,free之后的堆塊首先會進入unsorted bin,觸發(fā)整理后才會進入large bin

free掉0x400以上的堆塊后,再malloc一個堆塊,才會觸發(fā)整理,進入到large bin如在源碼二的最后加上malloc(0x2000),并把size改為0x1000

#include<stdio.h>

?#include<malloc.h>

?#include<unistd.h>

?#include<string.h>

?int main(int argc,char *argv[])

{

? ? ? int size = 0x1000;

? ? ? void *p = malloc(size);

? ? ? void *junk = malloc(size);

? ? ? void *q = malloc(size);

? ? ? void *r = malloc(size);

? ? ? sleep(0);

? ? ? printf("p:0x%x\n",p);

? ? ? printf("q:0x%x\n",q);

? ? ? printf("r:0x%x\n",r);

? ? ? strcpy(p,"aaaaaaaaaaaaaaaaa");

? ? ? strcpy(q,"bbbbbbbbbbbbbbbbb");

? ? ? strcpy(r,"ccccccccccccccccc");

? ? ? free(p);

? ? ? free(q);

? ? ? sleep(0);

? ? ? malloc(0x2000);

? ? ? sleep(0);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ?return 0;

? ? ? ? }?

此時fd_nextsize和bk_nextsize有效

0x602000 PREV_INUSE {

? prev_size = 0,?

? size = 4113,?

? fd = 0x604020,?

? bk = 0x7ffff7dd2198 <main_arena+1656>,?

? fd_nextsize = 0x602000,?

? bk_nextsize = 0x602000

}

未malloc(2000)當前的bins鏈

fastbins

0x20: 0x0

0x30: 0x0

0x40: 0x0

0x50: 0x0

0x60: 0x0

0x70: 0x0

0x80: 0x0

unsortedbin

all: 0x604020 —? 0x602000 —? 0x7ffff7dd1b78 (main_arena+88) ?— 0x604020 /* ' @`' */

smallbins

empty

largebins

empty

malloc(0x2000)的bins鏈

fastbins

0x20: 0x0

0x30: 0x0

0x40: 0x0

0x50: 0x0

0x60: 0x0

0x70: 0x0

0x80: 0x0

unsortedbin

all: 0x0

smallbins

empty

largebins

0x1000: 0x602000 —? 0x604020 —? 0x7ffff7dd2198 (main_arena+1656) ?— 0x602000

對于新malloc的堆塊大小,有這幾種情況

0-0x999

0x1000-0x1008

0x1009以上

當size小于0x80的時候,free后會進入到fastbin

fastbins

0x20: 0x0

0x30: 0x0

0x40: 0x0

0x50: 0x0

0x60: 0x0

0x70: 0x6020e0 —? 0x602000 ?— 0x0? ?//p , q都進入fastbin

0x80: 0x0

unsortedbin

all: 0x0

smallbins

empty

largebins

empty

當malloc(0x60)的新chunk時,會首先從后free的0x6020e0中分配空間,分配之后,0x6020e0退出fastbin

0x70: 0x602000 ?— 0x0

源代碼三

#include<stdio.h>

#include<stdlib.h>

#include<malloc.h>

#include<unistd.h>

#include<string.h>

#include<sys/types.h>

#include<pthread.h>

void* threadFunc(void* arg)

{

? int size = 0x200;

? sleep(0);

? void *q = malloc(size);

? printf("%p\n",q);

? sleep(0);

? free(q);

? sleep(0);

}

int main(int argc,char *argv[])

{

? ? int size = 0x100;

? void *p = malloc(size);

? free(p);

? pthread_t t1;

? void *s;

? int ret;

? ret = pthread_create(&t1,NULL,threadFunc,NULL);

? ? ret = pthread_join(t1,&s);

? return 0;

}

子線程的堆空間

pwndbg> c

Continuing.

0x7ffff00008c0? ? ? ? ==>第一個堆塊

pwndbg>vmmap

?0x602000? ? ? ? ? ?0x623000 rw-p? ? 21000 0? ? ? [heap]

? ? 0x7ffff0000000? ? ?0x7ffff0021000 rw-p? ? 21000 0?

? ? 0x7ffff0021000? ? ?0x7ffff4000000 ---p? 3fdf000 0? ? ?

? ?0x7ffff6fef000? ? ?0x7ffff6ff0000 ---p? ? ?1000 0?

查看內(nèi)存布局

pwndbg> x/20gz 0x7ffff00008c0 -0x10

0x7ffff00008b0:? 0x0000000000000000? 0x0000000000000215? ?NO_MAIN_ARENA & PREV_INUSE = 5

0x7ffff00008c0:? 0x0000000000000000? 0x0000000000000000

0x7ffff00008d0:? 0x0000000000000000? 0x0000000000000000

0x7ffff00008e0:? 0x0000000000000000? 0x0000000000000000

偏移查看arena結(jié)構(gòu)

pwndbg> x/100gz 0x7ffff00008c0 -0x10 + 0x200

0x7ffff0000ab0:? 0x0000000000000000? 0x0000000000000000

0x7ffff0000ac0:? 0x0000000000000000? 0x0000000000000415? ? ==>第二個堆塊,分配了0x410的空間

0x7ffff0000ad0:? 0x3066666666377830? 0x000a306338303030? ? ?==>printf的堆塊

0x7ffff0000ae0:? 0x0000000000000000? 0x0000000000000000

pwndbg> x/s 0x7ffff0000ad0

0x7ffff0000ad0:? "0x7ffff00008c0\n"

pwndbg> x/20gz 0x7ffff00008c0 -0x10 + 0x200 + 0x420

0x7ffff0000ed0:? 0x0000000000000000? 0x0000000000020131? ? ?==>子線程的top_chunk

0x7ffff0000ee0:? 0x0000000000000000? 0x0000000000000000

free掉q之后NO_MAIN_ARENA置0

pwndbg> x/20gz 0x7ffff00008c0 -0x10?

0x7ffff00008b0: 0x0000000000000000? 0x0000000000000211

0x7ffff00008c0: 0x00007ffff0000078? 0x00007ffff0000078? ? ? ==> 類似于主線程的main_arena + 88

pwndbg> x/20gz 0x00007ffff0000078

0x7ffff0000078: 0x00007ffff0000ed0? 0x0000000000000000? ? ==> 子線程的top_chunk

0x7ffff0000088: 0x00007ffff00008b0? 0x00007ffff00008b0? ? ==> 子線程的第一個堆塊

0x7ffff0000098: 0x00007ffff0000088? 0x00007ffff0000088?

0x7ffff00000a8: 0x00007ffff0000098? 0x00007ffff0000098? ??

0x7ffff00000b8: 0x00007ffff00000a8? 0x00007ffff00000a8

0x7ffff00000c8: 0x00007ffff00000b8? 0x00007ffff00000b8

0x7ffff00000d8: 0x00007ffff00000c8? 0x00007ffff00000c8

0x7ffff00000e8: 0x00007ffff00000d8? 0x00007ffff00000d8

0x7ffff00000f8: 0x00007ffff00000e8? 0x00007ffff00000e8

0x7ffff0000108: 0x00007ffff00000f8? 0x00007ffff00000f8

//此這里可以leak main_arena的結(jié)構(gòu)

實驗總結(jié)

main_arena為主線程的arena

在第一次調(diào)用malloc之后,會用brk調(diào)用生成堆,并生成top_chunk之后分配的堆,都會從top_chunk上切割當top_chunk不夠用時,會再次通過brk系統(tǒng)調(diào)用申請內(nèi)存副線程的arena通過mmap獲得,并也會生成top_chunk

好了,到這兒,二進制安全之堆溢出(系列)——堆基礎 & 結(jié)構(gòu)就更完了??!








二進制安全之堆溢出(系列)——堆基礎 & 結(jié)構(gòu)(四)的評論 (共 條)

分享到微博請遵守國家法律
苏尼特右旗| 榆林市| 永修县| 花莲县| 大余县| 达拉特旗| 开原市| 湖州市| 福鼎市| 资阳市| 新巴尔虎右旗| 布尔津县| 奉化市| 布拖县| 焉耆| 康保县| 宜丰县| 金昌市| 高清| 普陀区| 汉川市| 金昌市| 台安县| 宜昌市| 南充市| 石泉县| 天峻县| 朝阳区| 安庆市| 宜丰县| 中江县| 岗巴县| 当雄县| 红河县| 福贡县| 台江县| 繁峙县| 中超| 玛纳斯县| 新竹县| 屏山县|